我需要创建一个在SQL Server实例的所有数据库上执行的查询。另一个约束是,查询只能在包含带有特殊列的特殊表的数据库上执行。背景是在某些数据库中,特殊表(没有)具有特殊列。
基于this solution,到目前为止,我只有一个查询,该查询仅在包含特定表的数据库上执行。
SELECT *
FROM sys.databases
WHERE DATABASEPROPERTY(name, 'IsSingleUser') = 0
AND HAS_DBACCESS(name) = 1
AND state_desc = 'ONLINE'
AND CASE WHEN state_desc = 'ONLINE'
THEN OBJECT_ID(QUOTENAME(name) + '.[dbo].[CERTAIN_TABLE]', 'U')
END IS NOT NULL
但是,仍然缺少的约束条件是查询只能选择表CERTAIN_TABLE
具有特定列的数据库。如何实现?
答案 0 :(得分:1)
为此,您将需要一些循环或动态sql。我真的不喜欢循环,所以这里是如何使用动态sql做到这一点。
declare @TableName sysname = 'CERTAIN_TABLE'
, @ColumnName sysname = 'CERTAIN_COLUMN'
declare @SQL nvarchar(max) = ''
select @SQL = @SQL + 'select DatabaseName = ''' + db.name + ''' from ' + QUOTENAME(db.name) + '.sys.tables t join ' + QUOTENAME(db.name) + '.sys.columns c on c.object_id = t.object_id where t.name = ''' + QUOTENAME(@TableName) + ''' and c.name = ''' + QUOTENAME(@ColumnName) + '''' + char(10) + 'UNION ALL '
from sys.databases db
where db.state_desc = 'ONLINE'
order by db.name
select @SQL = substring(@SQL, 0, len(@SQL) - 9)
select @SQL
--uncomment the line below when you are comfortable the query generated is correct
--exec sp_executesql @SQL
答案 1 :(得分:1)
当我想遍历所有数据库时,我会像以下那样进行遍历。易于理解:
DECLARE @dbs TABLE ( dbName NVARCHAR(100) )
DECLARE @results TABLE ( resultName NVARCHAR(100) )
INSERT INTO @dbs
SELECT name FROM sys.databases
DECLARE @current NVARCHAR(100)
WHILE (SELECT COUNT(*) FROM @dbs) > 0
BEGIN
SET @current = (SELECT TOP 1 dbName FROM @dbs)
INSERT INTO @results
EXEC
(
'IF EXISTS(SELECT 1 FROM "' + @current + '".INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = ''Target_Table_Name'' AND COLUMN_NAME = ''Target_Column_Name'')
BEGIN
--table and column exists, execute query here
SELECT ''' + @current + '''
END'
)
DELETE FROM @dbs
WHERE dbName = @current
END
SELECT * FROM @results