我有几个具有相同架构的数据库。所有数据库都有一个名为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
如果我调试我的查询,即使我已找到发票,我仍然会看到查询在所有数据库上执行。
答案 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_MSforeachdb
和sp_MSforeach_worker
版本。
希望这有帮助。