从sql中的foreach循环中断(dbo.sp_MsForEachDb)

时间:2014-02-26 21:07:46

标签: sql sql-server foreach

我有几个具有相同架构的数据库。所有数据库都有一个名为Invoices的表。每张发票都有一个唯一的ID,因为它是一个GUID。有时我会收到发票ID,我想知道它属于哪个数据库。结果,我执行以下查询:

DECLARE @sql NVARCHAR(2000)

SET @sql = '
IF OBJECT_ID(''[?].dbo.Invoices'') IS NOT NULL   
begin
    declare @query NVARCHAR(255)
    Select @query = (Select [Id] from [?].dbo.Invoices where [Id] = ''XF4G-XF78-2156-7XH8'')    
    IF @query IS NOT NULL
    begin
          print ''Database = '' + ''?''             
    end
end
'
EXEC dbo.sp_MsForEachDb @sql

基本上EXEC dbo.sp_MsForEachDb @sql执行@sql查询,替换每个数据库的?。一旦我输入了print语句,因为发现了发票,我想停止执行。换句话说,我希望能够做类似

的事情
begin
          print 'Database = ' + ''?''  
          return            
end

如果我调试我的查询,即使我已找到发票,我仍然会看到查询在所有数据库上执行。

1 个答案:

答案 0 :(得分:1)

不幸的是,我认为没有一种简单的方法可以做到这一点。

一种完全不优雅的方法是关闭系统过程使用的游标。而不是return使用CLOSE hCForEachDatabase。它会让你退出循环,但有一个错误。就像我说的那样,这是一种可怕的做法。

更优雅的方法是继续循环遍历所有数据库,但是一旦找到匹配就不进行任何处理。假设用户有权创建临时表,你可以这样做......

DECLARE @sql NVARCHAR(2000)

CREATE TABLE #StopProcess(STOP BIT NULL);

SET @sql = '
IF  (SELECT COUNT(*) FROM #StopProcess) = 0
BEGIN
    IF OBJECT_ID(''[?].dbo.Invoices'') IS NOT NULL   
    BEGIN
        declare @query NVARCHAR(255)
        Select @query = (Select [Id] from [?].dbo.Invoices where [Id] = ''XF4G-XF78-2156-7XH8'')    
        IF @query IS NOT NULL
        END
            print ''Database = '' + ''?''     
            INSERT INTO #StopProcess values (1);            
        END
    END
END'

EXEC dbo.sp_MsForEachDb @sql

DROP TABLE #StopProcess;

如果您绝对需要停止处理所有数据库,我能想到的唯一选择是推出您自己的sp_MSforeachdbsp_MSforeach_worker版本。

希望这有帮助。