SQL for循环使用Select语句中返回的ID

时间:2012-01-05 10:42:44

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

我需要在某种条件下从我的数据库中删除一堆行。我有select语句来返回这个条件,然后对于这个select语句中的每一行,我需要它执行一个SP,它将删除这些行和一堆相关的行。到目前为止,我有:

select importfileid from import.importfiles where importfilestatusid < 7

然后执行

EXEC    [import].[spDeleteFromAllImportRelatedTables]
    @fileID = @importfileid

我只是不确定如何做中间?如果有人能指出我正确的方向,那就太好了。

注意:这是一次性的事情。表现不是问题。

5 个答案:

答案 0 :(得分:2)

你可以使用光标:

declare @importFileID int
declare @cur cursor

set @cur = cursor fast_forward for 
select importfileid from import.importfiles where importfilestatusid < 7

open @cur
fetch next from @cur into @importFileID
while(@@fetch_status = 0)
begin
  exec [import].[spDeleteFromAllImportRelatedTables] @fileID = @importFileID
  fetch next from @cur into @importFileID
end
close @cur
deallocate @cur

答案 1 :(得分:1)

尝试在选择上使用光标。请查看此链接http://msdn.microsoft.com/en-us/library/ms180169.aspx

答案 2 :(得分:0)

我永远不建议使用光标,而是选择基于SET的方法。如果可能,您可以在所有相关表上使用连接来删除所有这些行。这将是更快的方法。创建一个SP并创建一个在特定时间间隔内为您完成此任务的作业,生活将变得轻松。

答案 3 :(得分:0)

你有几个选择,其中没有一个是漂亮的。

使用光标

使用(fastforward readonly)游标,您可以逐个遍历结果并调用存储过程。


持有表

将所有记录插入表中,然后记录存储过程以从该表中读取。

这可以是真实的表格,也可以是#temporary_table。

这样做的好处在于,您可以一起完成所有删除操作,而不是迭代循环。


封装函数中的第一步

如果将SELECT代码放入函数中,则可以重新编码SP以调用该函数以查找要删除的记录。然后SP的参数变为函数的参数。


这在SQL Server 2008+中使用表参数进行了一些整理。但不是在SQL Server 2005中。

答案 4 :(得分:-1)

我认为SP正在做一些比删除行更特殊的事情。

如果这是一件事,你可以做一些像哈克一样的事情:

SELECT 'EXEC    [import].[spDeleteFromAllImportRelatedTables]    @fileID =',  importfileid from import.importfiles where importfilestatusid < 7

然后复制并粘贴结果并运行它?

另外,如果这是预定的清理,请考虑重新考虑您的代码并编写一个新的SP,它执行DeleteFromAllImportRelatedTables所做的事情,但使用您在上面说明的标准。虽然可能存在一些重复的代码,但它可能会更快更容易理解正在发生的事情并且更容易调试,因为您不会通过SP中的SP调用来查找任何问题。