SQL Server 存储过程中的循环

7

我需要帮助编写存储过程,并调用另一个存储过程并向其传递值。到目前为止,此操作是使用C#完成的,现在我想将其移动到存储过程并创建SQL代理作业,在特定时间调用它。有什么建议吗?这是情况。

表A

PK_TableA_ID

表B

PK_TableB_ID

存储过程SP1

@TableA_ID
@TableB_ID

我需要用T-SQL实现这个功能。
foreach(var TableAId in TableA)
{
foreach(var TableBId in TableB)
{
//call stored procedure 
SP1(TableAId, TableBId);
}
}

请查看游标(cursors)的相关信息:http://technet.microsoft.com/zh-cn/library/ms180169.aspx - Magnus
这是一个存储过程(不是存储过程)- 即存储在SQL Server内部的过程.... - marc_s
我是T-SQL的新手。如果有人能给我一个根据我提到的情况的例子,那将是非常好的。谢谢。 - user2831001
2个回答

11

这是一个使用光标执行循环的示例:

-- set up some test data
declare @table_a table (PK_TableA_ID int)
declare @table_b table (PK_TableB_ID int)
insert @table_a values (1),(2),(3)
insert @table_b values (4),(5),(6)    

-- do the actual processing
SET NOCOUNT ON

DECLARE @TableA_ID int, @TableB_ID int

DECLARE TableA_cursor CURSOR FOR SELECT PK_TableA_ID FROM @table_a

OPEN TableA_cursor
FETCH NEXT FROM TableA_cursor INTO @TableA_ID

WHILE @@FETCH_STATUS = 0
BEGIN
    DECLARE TableB_cursor CURSOR FOR SELECT PK_TableB_ID FROM @table_b

    OPEN TableB_cursor
    FETCH NEXT FROM TableB_cursor INTO @TableB_ID

    WHILE @@FETCH_STATUS = 0
    BEGIN
        PRINT CAST(@TableA_ID AS CHAR(1)) + ':' + CAST(@TableB_ID AS CHAR(1))
        -- execute your stored procedure here:
        -- EXEC Your_stored_procedure (@TableA_ID, @TableB_ID) 
        FETCH NEXT FROM TableB_cursor INTO @TableB_ID
        END

    CLOSE TableB_cursor
    DEALLOCATE TableB_cursor

    FETCH NEXT FROM TableA_cursor INTO @TableA_ID
END 
CLOSE TableA_cursor
DEALLOCATE TableA_cursor

使用上面的光标(带有临时表中的测试数据)将生成此输出:

1:4
1:5
1:6
2:4
2:5
2:6
3:4
3:5
3:6

然而,使用游标可能不是解决您问题的最佳方法。


1

我有一个干净、清晰的选项,针对这种情况使用表格ID而不需要光标。

DECLARE 
@Counter1 INT,@MaxId1 INT,
@Counter2 INT, @MaxId2 INT 

SELECT @Counter1 = min(PK_TableA_ID) , @MaxId1 = max(PK_TableA_ID) 
FROM TableA
SELECT @Counter2 = min(PK_TableB_ID) , @MaxId2 = max(PK_TableB_ID) 
FROM TableB

WHILE(@Counter1 IS NOT NULL AND @Counter1 <= @MaxId1)
BEGIN 
      WHILE(@Counter2 IS NOT NULL AND @Counter2 <= @MaxId2)
      BEGIN
          //call stored procedure 
          SP1(@Counter1, @Counter2);

          SET @Counter2  = @Counter2  + 1
      END;
      
      SELECT @Counter2 = min(PK_TableB_ID) , @MaxId2 = max(PK_TableB_ID) 
      FROM TableB
      SET @Counter1  = @Counter1  + 1             
END;

这种方法仅在用于PK_TableA_ID和PK_TableB_ID的数字连续且为数字时才能正常工作。原问题中没有提到这一点,因此如果列的类型为uniqueidentifier,则游标的方法仍将起作用,而此方法则不行。 在此代码中,在外部循环中重新选择Counter2和MaxId2应该是不必要的,至少如果SP1不向TableB插入值的话。 - Stefan Illner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接