views:

52

answers:

3

I need to give a new login read access to all 300 databases on a server. How can I accomplish this without checking 300 checkboxes in the user mapping area?

+1  A: 

Cursor through the databases and GRANT access to each with a little t-sql.

I did not test the code below.

DECLARE db_cursor CURSOR FOR
SELECT name 
FROM master.dbo.sysdatabases 
WHERE name NOT IN ('master','model','msdb','tempdb') 


WHILE @@FETCH_STATUS = 0  
BEGIN  

GRANT SELECT ON DATABASE::@name to 'username'; 

FETCH NEXT FROM db_cursor INTO @name  
END 
buckbova
The t-sql to use after that point is my point of confusion. Any pointers on that?
Greg
+3  A: 

From this article Set Results to Text to generate a script that you can then run. Obviously review its suitability first. You might want to exclude system databases.

select 'use ['+name +']'+ char(13)+'Go'+char(13)+'sp_adduser 
 '+char(13)+'Go'+char(13) + 'sp_addrolemember ''db_datareader'',
' +char(13)+'Go' +char(13) + ' sp_addrolemember ''db_denydatawriter'',
' +char(13)+'Go'+char(13) from master..sysdatabases

Or look at sp_msforeachdb as here

Martin Smith
Why am I hearing about this sp_msforeachdb just now? I guess I just try and figure out everything with the tools I know. Well, I'm adding that to the toolbox. Thanks!
buckbova
Thanks! This seemed to work. I did have the copy the results of that query into textpad and replace Go with \nGo\n
Greg
@Greg - Glad it worked. Did you run it in Management Studio? If so selecting the option "Results to Text" (CTRL + T) would probably have avoided the need for the intermediate step.
Martin Smith
+1  A: 
Declare @Databases Cursor
Declare @DbName as nvarchar(64)
Declare @Sql nvarchar(max)
Declare @BaseAddUserSql nvarchar(max)
Declare @BaseAddRoleSql nvarchar(max)

Set @Databases = Cursor Fast_Forward For
    select [name]
    from master..sysdatabases
    where [name] not in('master','model','msdb','tempdb')

Open @Databases
Fetch Next From @Databases Into @DbName

Set @BaseAddUserSql = 'exec sp_adduser ''LOGINNAME'''
Set @BaseAddRoleSql = 'exec sp_addrolemember ''db_datareader'', ''LOGINNAME'''


While @@Fetch_Status = 0
Begin
    Begin Try
        Set @Sql = 'Use ' + Quotename(@DbName)
        exec (@Sql)

        Set @Sql = Replace(@BaseAddUserSql, 'LOGINNAME', <loginname>)
        exec(@Sql)

        Set @Sql = Replace(@BaseAddRoleSql, 'LOGINNAME', <loginname>)
        exec(@Sql)
    End Try
    Begin Catch
    End Catch

    Fetch Next From @Databases Into @DbName
End

Close @Databases
Deallocate @Databases
Thomas
It says it completed successfully but I don't see any changes. The user mappings area hasn't changed. And the login I put for <loginname> doesn't appear as a user in any of the databases. Any ideas?
Greg
@Greg - You might want to comment out the Try-Catch blocks to see the error that is being thrown.
Thomas