Sql server 如何在实例上的所有数据库上运行相同的查询?
为了进行测试,我在SQLServer2008R2实例上有许多具有相同模式(=基本上相同的表和列)的数据库 我想问一下Sql server 如何在实例上的所有数据库上运行相同的查询?,sql-server,sql-server-2008-r2,multiple-databases,Sql Server,Sql Server 2008 R2,Multiple Databases,为了进行测试,我在SQLServer2008R2实例上有许多具有相同模式(=基本上相同的表和列)的数据库 我想问一下 SELECT COUNT(*) FROM CUSTOMERS 在实例上的所有数据库上。我希望有两列作为结果: 1-数据库名称 2-计数(*)的值COUNT 例如: DBName // COUNT (*) TestDB1 // 4 MyDB // 5 etc... 注意:我假设客户表存在于所有数据库中(除了主数据库)。直接查询 EXECUTE sp_MSForEa
SELECT COUNT(*) FROM CUSTOMERS
在实例上的所有数据库上。我希望有两列作为结果:
1-数据库名称
2-计数(*)的值COUNT
例如:
DBName // COUNT (*)
TestDB1 // 4
MyDB // 5
etc...
注意:我假设客户
表存在于所有数据库中(除了主数据库
)。直接查询
EXECUTE sp_MSForEachDB
'USE ?; SELECT DB_NAME()AS DBName,
COUNT(1)AS [Count] FROM CUSTOMERS'
此查询将显示您希望看到的内容,但也会为没有名为“CUSTOMERS”的表的每个DB抛出错误。你需要想出一个逻辑来处理这个问题
拉吉试试这个-
SET NOCOUNT ON;
IF OBJECT_ID (N'tempdb.dbo.#temp') IS NOT NULL
DROP TABLE #temp
CREATE TABLE #temp
(
[COUNT] INT
, DB VARCHAR(50)
)
DECLARE @TableName NVARCHAR(50)
SELECT @TableName = '[dbo].[CUSTOMERS]'
DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = STUFF((
SELECT CHAR(13) + 'SELECT ''' + name + ''', COUNT(1) FROM [' + name + '].' + @TableName
FROM sys.databases
WHERE OBJECT_ID('[' + name + ']' + '.' + @TableName) IS NOT NULL
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
INSERT INTO #temp (DB, [COUNT])
EXEC sys.sp_executesql @SQL
SELECT *
FROM #temp t
输出(例如,在AdventureWorks
中)-
像这样的怎么样:
DECLARE c_db_names CURSOR FOR
SELECT name
FROM sys.databases
WHERE name NOT IN('master', 'tempdb') --might need to exclude more dbs
OPEN c_db_names
FETCH c_db_names INTO @db_name
WHILE @@Fetch_Status = 0
BEGIN
EXEC('
INSERT INTO #report
SELECT
''' + @db_name + '''
,COUNT(*)
FROM ' + @db_name + '..linkfile
')
FETCH c_db_names INTO @db_name
END
CLOSE c_db_names
DEALLOCATE c_db_names
SELECT * FROM #report
这里最新也是最好的选择是Brent Ozar's on GitHub中的proc。+1这是一个非常紧凑的解决方案,但我选择了另一个,因为您的解决方案包含许多结果表,而另一个则不值得一提的是,sp_MSForEachDB没有文档记录,不受支持,还有一些Aaron Bertrand在这里讨论过的已知问题。这是一个有用的通用代码段,我刚刚用
sys.tables
替换了sys.databases
,用于一个非常不同的目的,使用相同的样板文件。您忘记了在脚本中声明[at]db_name,您需要添加一行:declare@db_name NVARCHAR(150),其他非常有用的脚本:-)临时表Delcareed在哪里?@Phil3992您是对的,应该添加它,但它只是一个两列的表,名称为VARCHAR,计数为INT。嗨,Devart,我正在使用这个sql,效果非常好。但是,是否可以添加一个检查,检查运行此查询的用户是否有权访问每个数据库,如果没有,则查询仍应继续运行并仅返回用户有权访问的数据库。我想知道的是,用户是否对每个数据库都有DBO角色权限,如果没有,请转到下一个数据库。。请你给个建议。
DECLARE c_db_names CURSOR FOR
SELECT name
FROM sys.databases
WHERE name NOT IN('master', 'tempdb') --might need to exclude more dbs
OPEN c_db_names
FETCH c_db_names INTO @db_name
WHILE @@Fetch_Status = 0
BEGIN
EXEC('
INSERT INTO #report
SELECT
''' + @db_name + '''
,COUNT(*)
FROM ' + @db_name + '..linkfile
')
FETCH c_db_names INTO @db_name
END
CLOSE c_db_names
DEALLOCATE c_db_names
SELECT * FROM #report