2010-07-19 42 views
1

我正在尝试编写一个存储过程,该存储过程将允许我编写在SQL Server上的所有数据库上运行的单个SELECT语句。 (微软SQL 2005)为统计目的查询多个数据库SQL

到目前为止,香港专业教育学院想出了下面的过程

set ANSI_NULLS ON 
set QUOTED_IDENTIFIER ON 
GO 

CREATE PROCEDURE [sp_cross_db_query] 
@SQLQuery varchar(400) 
AS 

DECLARE @DB_Name varchar(100) 
DECLARE database_cursor CURSOR FOR 

SELECT DatabaseName 
FROM Management.dbo.Customers 

OPEN database_cursor 

FETCH NEXT FROM database_cursor INTO @DB_Name 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    exec(
     'USE [' + @DB_Name + '];' + 
     @SQLQuery 
     ) 
     FETCH NEXT FROM database_cursor INTO @DB_Name 
END 
CLOSE database_cursor 
DEALLOCATE database_cursor 

通过它来运行查询

exec sp_cross_db_query 'SELECT count(*) FROM Products' 

我可以指望在所有数据库中的所有产品,问题是我返回数据的方式。现在我得到了几个“窗户”,结果巫婆是非常难以控制的。 所以我的问题是,我怎么能得到非常像一个选择结果..,联盟选择..,联盟选择..? (换句话说,一个结果表)?

我想过在程序内部创建临时表,您怎么看?

在此先感谢!

回答

1

可能动态SQL

DECLARE @DynSQL nvarchar(max) 

select 
@DynSQL = isnull(@DynSQL + ' UNION ALL ','') + 
'SELECT count(*) AS ProdCnt FROM ' + quotename(name) + '..Products' 
from sys.databases 
WHERE state= 0 AND is_in_standby=0 AND database_id>4 /*Exclude Offline and System 
                 databases*/ 

PRINT @DynSQL /*For Debugging or use the next line if the print output is truncated*/ 
SELECT @DynSQL AS [processing-instruction(x)] FOR XML PATH('') 

EXEC sp_executesql @DynSQL 
+0

谢谢,我会试试这个。 – Alexander 2010-07-19 12:34:18

+0

有什么更大的nvarchar(最大)? /: 这对我不起作用 – Alexander 2010-07-19 13:03:27

+0

它没有足够的字符。该查询得到'切断' – Alexander 2010-07-19 13:12:29

2

我想除了临时表之外没有别的办法来实现你想要的功能。您需要在临时表中添加行,而不必使用select @tablevariable来获取所有数据。

检查:http://www.sqlteam.com/article/introduction-to-dynamic-sql-part-2

+0

感谢pranay,做u对如何做到这一点的任何代码示例或引用?即时通讯不是那么伟大的SQL): – Alexander 2010-07-19 12:26:04

+0

检查链接为那 – 2010-07-19 12:40:12