我有以下代码运行循环
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
关闭我的光标 解除分配我的光标
用于设置 sp 和参数的表格示例
表名 | SP_名称 | 报告_dt |
---|---|---|
raw_table_A | 运行_原始_表 | 20230101 |
原始表_B | 运行_原始_表 | 20230201 |
这不是联合的原因是因为我们想要处理开始日期和结束日期之间的单月或多月运行。第一个表将被附加,但数据库的其余部分将按月增量加载运行。
发生的情况是循环在存储过程中运行大约 15 次,然后存储过程没有完成。
当我运行将在循环外的循环中执行的存储过程时,它运行没有问题,我还在循环中尝试了不同的存储过程,但在第 15 次运行时总是失败?
代码的更简单版本看起来像这样..
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
另外,我建议创建一个单独的过程来执行过程并添加错误处理,这样如果过程执行失败,该过程将继续执行下一个过程并记录一些错误详细信息。
我在自己的地方实现了类似的解决方案,但它具有更复杂的实现以及在此过程之上的大量错误处理和报告。
使用以下代码修复:
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