SQL Server Loop used to execute a procedure multiple times fails during nth run

wr98u20j  于 2023-10-15  发布在  其他
关注(0)|答案(2)|浏览(136)

I have the following code running a loop

DECLARE @table_name NVARCHAR(100)
, @sql NVARCHAR(MAX)
, @sp_name NVARCHAR(100)
, @rep_dt nvarchar(10)
, @min_rep_dt DATE

DECLARE mycursor CURSOR
LOCAL STATIC
LOCAL READ_ONLY FORWARD_ONLY
FOR
SELECT 
table_name
,sp_name
,report_dt
FROM staging.raw_sp_runlist

OPEN mycursor
FETCH NEXT FROM mycursor
INTO @table_name, @sp_name, @rep_dt

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @sql = N'EXEC '
            + @sp_name
            + ' @ds_table_name = ' + '''' + @table_name + ''''
            + ' ,@report_dt = ' + '''' + @rep_dt + ''''

    EXEC sp_executeSQL @sql

    FETCH NEXT FROM mycursor
    INTO @table_name, @sp_name, @rep_dt

END

CLOSE mycursor DEALLOCATE mycursor

Example of table being used to set the sp and parameters
| table_name | SP_Name | report_dt |
| ------------ | ------------ | ------------ |
| raw_table_A | run_raw_table | 20230101 |
| raw_table_B | run_raw_table | 20230201 |

The reason this is not a union is because we want to handle running a single months or multiple months between a start and an end date. The first table will be appended but the rest of the database will be ran as delta loads on a monthly basis.

What happens is the loop runs through the stored procs for about 15 runs and then the stored proc doesn't complete.

When I run the stored proc that will be executed in the loop outside of the loop it runs no issues, I have also tried different stored procs in the loop and it always fails on the 15th run?

scyqe7ek

scyqe7ek1#

A much simpler version of your code would look something like this..

DECLARE @table_name NVARCHAR(100)
    ,   @sp_name NVARCHAR(100)
    ,   @rep_dt DATE
    ,   @Sql NVARCHAR(MAX);

DECLARE mycursor CURSOR LOCAL FAST_FORWARD FOR
SELECT table_name , sp_name , report_dt FROM staging.raw_sp_runlist

OPEN mycursor FETCH NEXT FROM mycursor INTO @table_name , @sp_name , @rep_dt

    WHILE (@@FETCH_STATUS = 0)
    BEGIN

        SET @Sql = N'Exec ' + QUOTENAME(@sp_name) 
                 + N'   @ds_table_name = @table_name '
                 + N' , @report_dt = @rep_dt '

        EXEC sp_executesql @Sql
                        , N'@table_name NVARCHAR(100) , @rep_dt DATE'
                        , @table_name
                        , @rep_dt

        FETCH NEXT FROM mycursor INTO @table_name , @sp_name , @rep_dt

    END

CLOSE mycursor 
DEALLOCATE mycursor

Also I would suggest to create a separate proc to execute procs and add error handling so if a proc execution fails this process continues to execute next proc and also log some error details.

I implemented a similar solution at my place but it has a much more sophisticated implementation and a lot of error handling and reporting on top of this process.

soat7uwm

soat7uwm2#

Fixed with the below code:

DECLARE @table_name NVARCHAR(100)
, @sql NVARCHAR(MAX)
, @sp_name NVARCHAR(100)
, @rep_dt nvarchar(10)
, @min_rep_dt DATE

DECLARE mycursor CURSOR
LOCAL STATIC
LOCAL READ_ONLY FORWARD_ONLY
FOR
SELECT 
table_name
,sp_name
,report_dt
FROM staging.raw_sp_runlist

OPEN mycursor
FETCH NEXT FROM mycursor
INTO @table_name, @sp_name, @rep_dt

WHILE @@FETCH_STATUS = 0
BEGIN

SET NOCOUNT ON
BEGIN TRY

    SET @sql = N'EXEC '
            + @sp_name
            + ' @ds_table_name = ' + '''' + @table_name + ''''
            + ' ,@report_dt = ' + '''' + @rep_dt + ''''



    EXEC sp_executeSQL @sql

END TRY
BEGIN CATCH
END CATCH

    FETCH NEXT FROM mycursor
    INTO @table_name, @sp_name, @rep_dt

END

CLOSE mycursor
DEALLOCATE mycursor

相关问题