use*_*714 19 sql t-sql sql-server stored-procedures
我想在一组中的每一行上执行存储过程,而不使用类似这样的游标:
我在SQL Server 2005中使用T-SQL.我认为这可能是使用函数,但我想尽可能使用存储过程(公司标准)
SELECT EXEC dbo.Sproc @Param1 = Table1.id
FROM Table1
Jos*_*sef 18
是.如果您有一个列,您可以在表中使用以标记已处理的列,您可以使用WHILE EXISTS:
DECLARE @Id int
WHILE EXISTS(SELECT * FROM Table1 WHERE Processed='N')
BEGIN
SELECT Top 1 @Id = id from Table1 WHERE Procesed='N'
EXEC dbo.Sproc @Id
UPDATE Table1 SET Processed = 'Y' WHERE Id = @Id
END
Run Code Online (Sandbox Code Playgroud)
或者,将id转储到临时表或表变量中,并在完成时删除:
DECLARE @HoldTable table (Id int PRIMARY KEY)
DECLARE @Id int
INSERT INTO @HoldTable SELECT Id FROM Table1
WHILE EXISTS(SELECT * FROM @HoldTable)
BEGIN
SELECT @Id = id from @HoldTable
EXEC dbo.Sproc @Id
DELETE FROM @HoldTable where Id = @Id
END
Run Code Online (Sandbox Code Playgroud)
Joe*_*eda 14
如果您只使用SQL Server 2005或更高版本,不关心向后兼容性并且可以将代码转换为用户定义函数(而不是存储过程),那么您可以使用新的"CROSS APPLY"运算符,它确实使用与您想要的语法非常相似的语法.我在这里找到了一个简短的介绍(当然,你也可以阅读BOL和MSDN)
假设您的SP返回一个名为out_int的值,您的示例可以重写为:
SELECT T.id, UDF.out_int
FROM
Table1 T
CROSS APPLY
dbo.fn_My_UDF(T.id) AS UDF
Run Code Online (Sandbox Code Playgroud)
这将从Table1中检索每个"id"并使用它来调用fn_My_UDF,其结果将出现在除原始参数之外的最终结果集中.
"CROSS APPLY"的变量是"外部应用".它们是"INNER JOIN"和"LEFT JOIN"的等价物,但是可以加入表和UDF(并同时调用第二个).
如果你必须(通过尖头发老板的明确顺序)使用SPs insead,那么 - 运气不好!您将不得不使用游标,或尝试作弊:将代码更改为UDF,并创建包装SP:D.
十分之九你可以在没有光标或 while 循环的情况下做你想做的事情。但是,如果您必须使用一个循环,我发现 while 循环往往更快。
另外,如果您不想删除或更新表,您可以使用如下内容:
DECLARE @id [type]
SELECT @id = MIN([id]) FROM [table]
WHILE @id IS NOT NULL
BEGIN
EXEC [sproc] @id
SELECT @id = MIN([id]) FROM [table] WHERE [id] > @id
END
Run Code Online (Sandbox Code Playgroud)