如何在另一个存储过程中迭代存储过程结果....没有游标?

时间:2008-09-29 15:19:21

标签: sql sql-server sql-server-2005 tsql

我不确定这是否是我应该在T-SQL中做的事情,我很确定在这个上下文中使用'iterate'这个词是错误的,因为你永远不应该在sql中迭代任何东西。它应该是基于集合的操作,对吗?无论如何,这是场景:

我有一个存储过程,返回许多uniqueidentifiers(单列结果)。这些ID是另一个表中记录的主键。我需要在该表中的所有相应记录上设置一个标志。

如何在不使用游标的情况下执行此操作?应该是一个简单的sql专家!

7 个答案:

答案 0 :(得分:15)

这可能不是最有效的,但我会创建一个临时表来保存存储过程的结果,然后在目标表的连接中使用它。例如:

CREATE TABLE #t (uniqueid int)
INSERT INTO #t EXEC p_YourStoredProc

UPDATE TargetTable 
SET a.FlagColumn = 1
FROM TargetTable a JOIN #t b 
    ON a.uniqueid = b.uniqueid

DROP TABLE #t

答案 1 :(得分:2)

您还可以将存储过程更改为用户定义的函数,该函数返回包含您的uniqueidentifier的表。您可以直接与UDF联系并将其视为一个表,以避免必须显式创建额外的临时表。此外,您可以在调用时将参数传递给函数,从而使其成为一种非常灵活的解决方案。

CREATE FUNCTION dbo.udfGetUniqueIDs
()
RETURNS TABLE 
AS
RETURN 
(
    SELECT uniqueid FROM dbo.SomeWhere
)

GO

UPDATE dbo.TargetTable 
SET a.FlagColumn = 1
FROM dbo.TargetTable a INNER JOIN dbo.udfGetUniqueIDs() b 
    ON a.uniqueid = b.uniqueid

修改: 这将适用于SQL Server 2000及更高版本...

答案 2 :(得分:0)

将存储过程的结果插入临时表并将其连接到要更新的表:

INSERT INTO #WorkTable
EXEC usp_WorkResults

UPDATE DataTable
  SET Flag = Whatever
FROM DataTable
INNER JOIN #WorkTable
  ON DataTable.Ket = #WorkTable.Key

答案 3 :(得分:0)

使用临时表或表变量(您正在使用SS2005)。

虽然,这不可嵌套 - 如果存储过程使用该方法,则无法将该输出转储到临时表中。

答案 4 :(得分:0)

如果升级到SQL 2008,那么您可以传递我认为的表参数。否则,您将无法使用全局临时表或创建一个永久表,该表包含某种进程ID的列,以标识对存储过程的哪个调用是相关的。

您在更改生成ID的存储过程方面有多少空间?您可以在其中添加代码来处理它,或者使用一个参数来允许您在调用行时标记行。

答案 5 :(得分:-1)

一个丑陋的解决方案是让你的程序在每次调用时返回“next”id,使用另一个表(或现有表上的某个标志)来过滤掉已经返回的行

答案 6 :(得分:-1)

您可以将临时表或表变量与其他列一起使用:

DECLARE @MyTable TABLE (
    Column1 uniqueidentifer,
    ...,
    Checked bit
)

INSERT INTO @MyTable
SELECT [...], 0 FROM MyTable WHERE [...]

DECLARE @Continue bit
SET @Continue = 1
WHILE (@Continue)
BEGIN
    SELECT @var1 = Column1,
           @var2 = Column2,
           ...
    FROM @MyTable
    WHERE Checked = 1

    IF @var1 IS NULL
        SET @Continue = 0
    ELSE
    BEGIN

        ...

        UPDATE @MyTable SET Checked = 1 WHERE Column1 = @var1
    END
END

编辑:实际上,在您的情况下,加入会更好;上面的代码是一个无光标的迭代,对你的情况来说太过分了。