Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何在实例上的所有数据库上运行相同的查询?_Sql Server_Sql Server 2008 R2_Multiple Databases - Fatal编程技术网

Sql server 如何在实例上的所有数据库上运行相同的查询?

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

为了进行测试,我在SQLServer2008R2实例上有许多具有相同模式(=基本上相同的表和列)的数据库

我想问一下

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