我不确定这是否是我应该在T-SQL中做的事情,我很确定在这个上下文中使用'iterate'这个词是错误的,因为你永远不应该在sql中迭代任何东西。它应该是基于集合的操作,对吗?无论如何,这是场景:
我有一个存储过程,返回许多uniqueidentifiers(单列结果)。这些ID是另一个表中记录的主键。我需要在该表中的所有相应记录上设置一个标志。
如何在不使用游标的情况下执行此操作?应该是一个简单的sql专家!
答案 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
编辑:实际上,在您的情况下,加入会更好;上面的代码是一个无光标的迭代,对你的情况来说太过分了。