SQL Server : query to loop through

I have a requirement to obtain all of the application databases and I have been able to obtain that through

select name from sys.database where database_id > 6

Now, I need to run the query below:

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

This is what I have written so far and I am getting an error at 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

Could someone please assist me here?

Thanks


You can use dynamic SQL for this so long as you're using this in a systems administration context and not out in the wild.

--@sql 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

A couple of things to keep in mind:

  • Your dynamic SQL variable needs to be long enough to hold the SQL content plus the database name.
  • I changed sys.database to sys.databases because that's the name of the table
  • If you need to aggregate the list of user names, IDs, and Read Accesses, I'd suggest creating another temp table. This might be a good idea because if you have a lot of databases, your result sets may get a little hard to manage.

You need to use dynamic sql to concatenate the variable name in your query, something like:

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 '+@User_FirstName+', '+@User_Name+', '+@User_Id+', '+@User_Access+' from '+@database_Name+'.dbo.ADMN.User_Details
'
EXEC (@sql)
end

close Maximizer 
deallocate Maximizer