SQL Server - How to Grant Read Access to ALL databases to a Login?

后端 未结 7 724
独厮守ぢ
独厮守ぢ 2021-02-05 05:22

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?

相关标签:
7条回答
  • 2021-02-05 05:39

    I had to tweak Martin Smith's answer slightly as:

    1. The spaces and linebreaks resulted in not all the text being generated properly
    2. The QUOTENAME in the Exec statement put in square brackets which is incorrect.

    My version:

    SET NOCOUNT ON;
    
    DECLARE @user_name    SYSNAME
            , @login_name SYSNAME;
    
    SELECT @user_name = 'HelpdeskUser',
           @login_name = 'Helpdesk'
    
    SELECT 'USE ' + QUOTENAME(NAME) + ';
            CREATE USER ' + QUOTENAME(@user_name)
           + ' FOR LOGIN ' + QUOTENAME(@login_name)
           + ' WITH DEFAULT_SCHEMA=[dbo];
        EXEC sys.sp_addrolemember ''db_datareader'',''' + @user_name + ''';
        EXEC sys.sp_addrolemember ''db_denydatawriter'', ''' + @user_name + '''; 
    GO'
    FROM   sys.databases
    WHERE  database_id > 4
           AND state_desc = 'ONLINE' 
    

    Otherwise works perfectly. Thanks

    0 讨论(0)
  • 2021-02-05 05:44

    You can use for example Cursor, like this :

    USE master
    GO
    
    DECLARE @DatabaseName VARCHAR(32)   
    DECLARE @SQL NVARCHAR(max)
    DECLARE @User VARCHAR(64)
    SET @User = '[SQL\srvSSISAcc]' --Your User
    
    DECLARE Grant_Permission CURSOR LOCAL FOR
    SELECT name FROM MASTER.dbo.sysdatabases
    WHERE name NOT IN ('master','model','msdb','tempdb')  
    
    OPEN Grant_Permission  
    FETCH NEXT FROM Grant_Permission INTO @DatabaseName  
    WHILE @@FETCH_STATUS = 0  
    BEGIN  
    
        SELECT @SQL = 'USE '+ '[' + @DatabaseName + ']' +'; '+ 'CREATE USER ' + @User + 
        'FOR LOGIN ' + @User + '; EXEC sp_addrolemember N''db_datareader'', 
        ' + @User + '; EXEC sp_addrolemember N''db_datawriter'', ' + @User + ''
    
        EXEC sp_executesql @SQL
        PRINT @SQL
    
    FETCH NEXT FROM Grant_Permission INTO @DatabaseName  
    END  
    CLOSE Grant_Permission  
    DEALLOCATE Grant_Permission 
    

    More info find in my post about this topic: http://www.pigeonsql.com/single-post/2016/12/23/Grant-User-Access-to-All-Databases

    0 讨论(0)
  • 2021-02-05 05:46

    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 
    
    0 讨论(0)
  • 2021-02-05 05:48

    One way would be to Set "Results to Text" on the query menu in SSMS then execute the below.

    It doesn't actually make the change but generates a script for you to review and execute.

    SET NOCOUNT ON;
    
    DECLARE @user_name    SYSNAME
            , @login_name SYSNAME;
    
    SELECT @user_name = 'user_name',
           @login_name = 'login_name'
    
    SELECT '
        USE ' + QUOTENAME(NAME) + ';
    
        CREATE USER ' + QUOTENAME(@user_name)
           + ' FOR LOGIN ' + QUOTENAME(@login_name)
           + ' WITH DEFAULT_SCHEMA=[dbo];
    
        EXEC sys.sp_addrolemember
          ''db_datareader'',
          ''' + QUOTENAME(@user_name) + ''';
    
        EXEC sys.sp_addrolemember
          ''db_denydatawriter'',
          '''
           + QUOTENAME(@user_name) + '''; 
    
    GO
    '
    FROM   sys.databases
    WHERE  database_id > 4
           AND state_desc = 'ONLINE' 
    

    Or you could look at sys.sp_MSforeachdb as here or Aaron Bertrand's improved version here

    If you are not seeing all of the characters when you run this, open the Query Options for Text and check the setting for 'Maximum number of characters displayed in each column'. Make sure this is set to a value large enough to display all characters.

    0 讨论(0)
  • 2021-02-05 05:48
    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
    
    0 讨论(0)
  • 2021-02-05 05:51
    EXEC sp_MSForEachDB 
    'Declare @name varchar(100)
     select @name = ''?''
     PRINT @name
     IF db_id(@name) > 4
     BEGIN
     USE ?
     CREATE USER [user] FOR LOGIN [user];
    EXEC sp_addrolemember ''db_datareader'', ''user''
     END'
    
    0 讨论(0)
提交回复
热议问题