Execute SPROC after completion of another SPROC - sql-server

Essentially, I want to do this in T-SQL
1) Execute SPROC1
2) Upon completion of SPROC1, execute SPROC2
3) Upon completion of SPROC2, execute SPROC3
I know this is possible using SSIS. If there any way I can do this?
Thanks

try this:
Execute SPROC1
execute SPROC2
execute SPROC3
SPROC2 will not run until SPROC1 is complete, and then SPROC3 will not run until SPROC2 is complete.
You can test it out:
CREATE PROCEDURE pTest1 AS
SELECT 1,GETDATE()
WAITFOR DELAY '00:00:02'
RETURN 0
go
CREATE PROCEDURE pTest2 AS
SELECT 2,GETDATE()
WAITFOR DELAY '00:00:02'
RETURN 0
go
CREATE PROCEDURE pTest3 AS
SELECT 3,GETDATE()
WAITFOR DELAY '00:00:02'
RETURN 0
go
EXEC pTest1
EXEC pTest2
EXEC pTest3
OUTPUT:
----------- -----------------------
1 2010-06-07 08:43:08.423
(1 row(s) affected)
----------- -----------------------
2 2010-06-07 08:43:10.423
(1 row(s) affected)
----------- -----------------------
3 2010-06-07 08:43:12.423
(1 row(s) affected)

For one DB call, use a wrapper
CREATE PROC SPROCwrapper
AS
EXEC SPROC1
EXEC SPROC2
EXEC SPROC3
GO
... or send 3 lines as per KM's answer.
SQL is sequentially executed

Related

How to return partial result of a procedure during its calculation?

How to return partial result of a procedure during its calculation in MS SQL? Let's say it takes a lot to calculate a procedure because of waitfor delay or a huge query inside. But I would like to show the results that are already calculated before the whole procedure reaches the end.
In the example below I would like to see "1" as a partial result before 5 seconds pass and I can see "2" as the final result.
CREATE PROCEDURE #Proc
AS
BEGIN
SELECT 1 AS PartialResult;
WAITFOR DELAY '00:00:05'
SELECT 2 AS FinalResult;
END;
EXEC #Proc;
Add a RAISERROR('',0,1) WITH NOWAIT; to flush the buffer to the client before the delay.
CREATE PROCEDURE #Proc
AS
BEGIN
SELECT 1 AS PartialResult;
RAISERROR('',0,1) WITH NOWAIT;
WAITFOR DELAY '00:00:05'
SELECT 2 AS FinalResult;
END;

Delete query does not work in SQL Server

This is strange but my SQL Server does not delete items:
I have a stored procedure like this:
Create Procedure DeleteItem #cnm nchar(10)
as
Begin Transaction
Delete From T1 where Cnm = #cnm
Delete From T2 where Cnm = #cnm
if ##ERROR <> 0
Begin
Commit
End
Else
Begin
RollBack
End
and when I run this query in SQL Server Management Studio:
Exec DeleteItem '1111111111'
it returns in the Messages pane:
(1 row(s) affected)
(1 row(s) affected)
but when I get data from that tables the deleted record still exist!
Am I doing anything wrong?
##ERROR returns 0 if the previous Transact-SQL statement encountered no errors.
Change your IF condition
if ##ERROR = 0
Commit
else
....

Forcing a specific stored procedure to stop after 30 seconds: I do not want to reconfigure the timeout of the whole DB

(The reason why I need the following are unimportant)
What I'd like to do is adjust the following so that it executes the stored procedure, which usually takes 30 minutes, but then the procedure stops after a set time of 60 seconds - effectively the same as if I am in SSMS running the procedure and press the cancel button after 60 seconds.
I don't want to reconfigure the whole db so that every other long running stored procedure times out after 30 seconds - only the specific procedure TESTexecuteLongRunningProc.
Here is the test procedure being called:
CREATE PROCEDURE [dbo].[TESTlongRunningProc]
AS
BEGIN
--placeholder that represents the long-running proc
WAITFOR DELAY '00:30:00';
END;
This is the proc I would like to adjust so it cancels itself after 60 seconds:
CREATE PROCEDURE [dbo].[TESTexecuteLongRunningProc]
AS
BEGIN
EXECUTE WH.dbo.TESTlongRunningProc;
-->>here I would like some code that cancels TESTexecuteLongRunningProc after 60 seconds
END;
Essentially you can create a separate process to watch the background for a specific tasks and metrics and kill if necessary. Lets start by implanting a tracking device into your code you wish to track. I used a comment block with a key phrase "Kill Me". You can place something similar in your original code
CREATE PROCEDURE TrackedToKill
-- EXEC TrackedToKill
/* Comment Block tracking device: Kill Me*/
AS
BEGIN
DECLARE #Counter bigint = 0
WHILE 1 = 1
BEGIN
SET #Counter = #Counter + 1
WAITFOR DELAY '00:00:30'
END
END
Then lets see if we can find the running sessions
SELECT session_id,
command,database_id,user_id,
wait_type,wait_resource,wait_time,
percent_complete,estimated_completion_time,
total_elapsed_time,reads,writes,text
FROM sys.dm_exec_requests
CROSS APPLY sys.dm_exec_sql_text (sys.dm_exec_requests.sql_handle)
WHERE text LIKE '%Kill Me%'
AND session_id <> ##SPID
OK Great, this should return sessions with your tracking device. We can then turn this into another stored procedure that will kill your processes based on the tracking device and any other criteria you might need. You can launch this manually or perhaps with the SQL agent at start up. Include as many additional criteria you need to make sure you limit the scope of what you're killing (ie; User, database, block or Processes that that haven't been rolled back already).
CREATE PROCEDURE HunterKiller
-- EXEC HunterKiller
AS
BEGIN
DECLARE #SessionToKill int
DECLARE #SQL nvarchar(3000)
WHILE 1=1
BEGIN
SET #SessionToKill = (SELECT TOP 1 session_id
FROM sys.dm_exec_requests
CROSS APPLY sys.dm_exec_sql_text (sys.dm_exec_requests.sql_handle)
WHERE session_id <> ##SPID
AND text LIKE '%Kill Me%'
AND total_elapsed_time >= 15000)
SET #SQL = 'KILL ' + CONVERT(nvarchar,#SessionToKill)
EXEC (#SQL)
WAITFOR DELAY '00:00:05'
END
END
Assuming you can use the SQL Server Agent, perhaps using the sp_start_job and sp_stop_job procedures could work for you.
This is untested and without any sort of warranty, and the parameters have been shortened for readability:
-- control procedure
declare #starttime DATETIME = SYSDATETIME()
exec msdb..sp_start_job 'Job' -- The job containing the target procedure that takes 30 minutes
while 1>0
BEGIN
-- Check to see if the job is still running and if it has been running long enough
IF EXISTS(
SELECT TOP 1 b.NAME
FROM msdb..sysjobactivity a
INNER JOIN msdb..sysjobs b
ON a.job_id = b.job_id
WHERE start_execution_date >= #starttime
AND stop_execution_date IS NULL
AND b.NAME in ('job')
and DATEDIFF(second,start_execution_date,SYSDATETIME()) >= 60
)
BEGIN
exec msdb..sp_stop_job 'Job'
END
waitfor delay '00:00:05';
END

CREATE PROCEDURE statement results in (1 row(s) affected)

I'm running SQL Server 2012.
I have a create procedure statement:
USE [dbname]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Test]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[Test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[Test]
AS
SELECT 1
When I run this with dbname equals one database, I get:
(1 row(s) affected)
When running it dbname equals another database on the same server, I get:
Command(s) completed successfully.
Obviously this is a database setting or something specific to the database, but I can't seem to find anything. Does anyone know what is causing the difference?
Thanks in advance.
This may be cause of DDL trigger existence. as you mentioned in your comments, one of the triggers has SET NO COUNT ON, which will be stops the message that shows the count of the number of rows affected by a Transact-SQL statement or stored procedure from being returned as part of the result set. if you comment it, or add it to the other trigger too, you will see the same results for both above mentioned scenarios.

How really functions WAITFOR statement in SQL?

Maybe someone already ask this, but I can't find appropriate answer to this question.
If I have, let's say, following query:
SELECT
column1,
column2,
column3
FROM Table1 AS t1
WAITFOR DELAY '10:00:00'
where this query returns around 100000 rows.
Did WAITFOR statement waiting 10 hours before telling SQL Server to execute query and produce result or SQL Server execute query immediately and keep result in RAM for 10 hours and then send it over network or just show?
Am I missing here something?
I would appreciate if someone give me real example that prove first or second solution.
I executed next query:
SELECT GETDATE()
SELECT GETDATE()
WAITFOR DELAY '00:00:05'
The result was two dates that were the same. On this basis, I will conclude that SQL Server immediately executes the query and keeps the result for certain time to show, but that made little sense for me.
According to the docs, the WAITFOR command is used to block a statement or transaction for the specified amount of time. In that case, you'd use it to delay subsequent statements. In other words, you'd want to execute something after the WAITFOR command, not before. Here's a few examples:
The following example executes the stored procedure after a two-hour delay.
BEGIN
WAITFOR DELAY '02:00';
EXECUTE sp_helpdb;
END;
GO
The following example executes the stored procedure sp_update_job at 10:20 P.M. (22:20).
USE msdb;
EXECUTE sp_add_job #job_name = 'TestJob';
BEGIN
WAITFOR TIME '22:20';
EXECUTE sp_update_job #job_name = 'TestJob',
#new_name = 'UpdatedJob';
END;
GO

Resources