2013-10-29 87 views
2

查询循环我有一个要求获得所有的应用程序的数据库,我已经能够获得通过SQL服务器:通过

select name from sys.database where database_id > 6 

现在,我需要运行下面的查询:

select 
    User_FirstName 
    , User_Name 
    , User_Id 
    , User_ReadAccess 
from 
    [name obtained from sys.databases].dbo.ADMN_User_Details 

这是我至今写的,我在database_Name.dbo.ADMN.User_Details得到一个错误:

declare @database_name varchar(50) 
declare @User_FirstName varchar (50) 
declare @User_Name varchar (50) 
declare @User_Access int 
declare @User_Id varchar (50) 

declare Maximizer cursor FOR 

select name from sys.databases 
where database_id > 6 

open Maximizer 
fetch next from Maximizer into @database_name 

while (@@FETCH_STATUS=0) 
begin 

    select 
     @User_FirstName, @User_Name, @User_Id, @User_Access 
    from 
     @database_Name.dbo.ADMN.User_Details 
end 

close Maximizer 
deallocate Maximizer 

有限公司有人请帮助我吗?

感谢,

DB

+0

“...我得到一个错误......”有什么错误? – zimdanen

+1

请勿使用游标 – Kermit

+2

@FreshPrinceOfSO,如何在没有游标的情况下完成此操作? –

回答

9

您可以使用动态SQL这个只要你正在系统管理环境中使用它,而不是在野外。

[email protected] holds your dynamic sql, @db holds the current DB 
declare @sql varchar(1000) 
declare @db varchar(100) 

--populate your list of databases through which you'll iterate. 
select name, 0 as run 
into #dbs 
from sys.databases where database_id > 6 

--a while loop in sql...don't tell Jeff Moden 
while exists (select 1 from #dbs where run = 0) 
begin 
    set @db = (select top 1 name from #dbs where run = 0 order by name) 
    set @sql = ' 
    select ''' + @db + ''' 
     , User_FirstName 
     , User_Name 
     , User_Id 
     , User_ReadAccess 
    from '+ @db +'.dbo.ADMN_User_Details' 
    exec(@sql) 
    update #dbs 
    set run = 1 
    where name = @db  
end 

几件事情要记住:

  • 您的动态SQL变量需要足够长以保存SQL内容加上数据库名。
  • 我将sys.database更改为sys.databases,因为这是表名
  • 如果您需要聚合用户名,ID和读访问列表,我建议创建另一个临时表。这可能是一个好主意,因为如果你有很多数据库,你的结果集可能会有点难以管理。
+0

它很好用。非常感谢你。真的很喜欢所有的建议。我需要一点修改。 db_name()打印master作为数据库的名称。是否有办法将数据库名称(@db)与其他用户相关信息一起打印? – user2933907

+0

好抓住OP。 db_name()获取运行查询的数据库。我通过在@db变量中解析(使用所有必需的记号),将查询更改为简单地打印当前数据库的任何内容。 –

+0

非常感谢您的帮助。这现在完成了。 – user2933907

0

你需要使用动态SQL查询来串联变量名,是这样的:

DECLARE @sql 
declare @database_name varchar(50) 
declare @User_FirstName varchar (50) 
declare @User_Name varchar (50) 
declare @User_Access int 
declare @User_Id varchar (50) 
declare @sql VARCHAR(MAX) 

declare Maximizer cursor FOR 

select name from sys.databases 
where database_id > 6 

open Maximizer 
fetch next from Maximizer into @database_name 

while (@@FETCH_STATUS=0) 
begin 

PRINT @database_Name 
SET @sql = ' 
select '[email protected]_FirstName+', '[email protected]_Name+', '[email protected]_Id+', '[email protected]_Access+' from '[email protected]_Name+'.dbo.ADMN.User_Details 
' 
EXEC (@sql) 
end 

close Maximizer 
deallocate Maximizer 
+0

感谢您的回答。我得到一个错误 - “将varchar值转换为数据类型int时转换失败”。我改变了选择语句,并能够纠正错误。有没有办法,我可以打印@database_name以及其他用户信息?再次感谢一堆。 – user2933907

+0

如果你的变量不是varchar,那么如果连接字符串,你将不得不施放它们,但是你已经修复了这个问题,随意编辑答案以显示你在select语句中做了不同的处理。您可以在开始时添加PRINT命令,查看更新的答案。 –