我有多个具有相同表格的数据库。我有一张名为Invoices的桌子。我现在正在进行查询的方式如下:
Select * from [Db1].dbo.Invoices where [Id] = 'someId'
UNION ALL Select * from [Db2].dbo.Invoices where [Id] = 'someId'
UNION ALL Select * from [Db3].dbo.Invoices where [Id] = 'someId'
例如,如果Db3不存在,该查询将引发错误。我正在努力创造像
这样的东西IF db_id('Db1') is not null -- if database Db1 exists
Select * from [Db1].dbo.Invoices where [Id] = 'someId'
IF db_id('Db2') is not null
UNION ALL Select * from [Db2].dbo.Invoices where [Id] = 'someId'
IF db_id('Db3') is not null
UNION ALL Select * from [Db3].dbo.Invoices where [Id] = 'someId'
该查询不起作用,但希望我说明我想要完成的任务
非常感谢您的帮助!如果找不到第一个数据库,我的查询将以UNION ALL
开头,从而产生错误。我该如何防止这种情况?
答案 0 :(得分:1)
您无法执行此操作,因为SQL Server会在执行前解析查询并尝试验证select脚本中的dbs / tables。所以你能做到这一点的唯一方法就是使用动态SQL:
DECLARE @sql NVARCHAR(MAX)
SET @sql = ''
IF db_id('Db1') is not null -- if database Db1 exists
SET @sql+='Select * from [Db1].dbo.Invoices where [Id] = ''someId'''
IF db_id('Db2') is not null
SET @sql+='UNION ALL Select * from [Db2].dbo.Invoices where [Id] = ''someId'''
IF db_id('Db3') is not null
SET @sql+='UNION ALL Select * from [Db3].dbo.Invoices where [Id] = ''someId'''
EXEC (@sql)
斯图。
答案 1 :(得分:1)
您可以使用动态SQL
DECLARE @sql NVARCHAR(MAX) = ''
IF db_id('Db1') is not null -- if database Db1 exists
SET @sql = @sql + 'Select * from [Db1].dbo.Invoices where [Id] = ''someId'''
IF db_id('Db2') is not null
BEGIN
IF LEN(@sql) > 0
SET @sql = @sql + N' UNION ALL '
SET @sql = @sql + 'Select * from [Db2].dbo.Invoices where [Id] = ''someId'''
END
IF db_id('Db3') is not null
BEGIN
IF LEN(@sql) > 0
SET @sql = @sql + N' UNION ALL '
SET @sql = @sql + 'Select * from [Db3].dbo.Invoices where [Id] = ''someId'''
END
exec sp_executesql @sql
答案 2 :(得分:1)
这里需要动态SQL
declare @qry varchar(max)=''
IF db_id('Db1') is not null -- if database Db1 exists
set @qry='Select * from [Db1].dbo.Invoices where [Id] = ''someId'''
IF db_id('Db2') is not null
begin
set @qry=@qry + case when @qry<>'' then ' UNION ' ELSE '' end
set @qry=@qry +' UNION ALL Select * from [Db2].dbo.Invoices where [Id] = ''someId'''
end
IF db_id('Db3') is not null
begin
set @qry=@qry + case when @qry<>'' then ' UNION ' ELSE '' end
set @qry=@qry +' UNION ALL Select * from [Db3].dbo.Invoices where [Id] = ''someId'''
end
if @qry<>''
EXEC(@qry)
答案 3 :(得分:1)
这里最短的版本
这将打印您需要的声明。只需将输出设置为文本并运行以下命令。
EXEC sp_MSForeachDB ' DECLARE @cmd VARCHAR(MAX)
SET @cmd = ''SELECT * FROM [?].dbo.Invoices WHERE ID=''''Something'''' UNION ALL''
PRINT @CMD
'
我相信你可以修改代码来执行而不是打印。它还不完美,但你应该能够使用它。
更新确定,以便缩短版本不会轻松工作。但是,通过应用此技术,您可以获得相同的结果。
CREATE TABLE #Tables
(
TABLE_NAME SYSNAME NOT NULL
);
EXEC sp_MSForeachDB ' DECLARE @cmd VARCHAR(MAX)
INSERT INTO #TABLES SELECT TABLE_NAME FROM [?].INFORMATION_SCHEMA.TABLES'
SELECT * FROM #Tables
DROP TABLE #Tables
这将获得与union相同的结果,您无需提前知道所有数据库。因此,如果您添加DB2000,它将按原样工作。您永远不必再次编辑查询。