问题
I have a stored procedure that finds all the existing databases and reads from a table in each one.
Is there a way I can give a login read access to all databases, and to all future databases i.e., I won't have to do anything when a new database is added?
Is there a server role that would work? Is there a way to make a SQL agent job add the permissions on any new databases? Or is there some other method?
回答1:
For new databases, add the user in the model database. This is used as the template for all new databases.
USE model
CREATE USER ... FROM LOGIN...
EXEC sp_addrolemember 'db_datareader', '...'
For existing databases, use sp_MSForEachDb
EXEC sp_MSForEachDb '
USE ?
CREATE USER ... FROM LOGIN...
EXEC sp_addrolemember ''db_datareader'', ''...''
'
回答2:
USE [master] GO --IF Not EXISTS (SELECT * FROM syslogins where loginname = 'replace with Login name ') --CREATE LOGIN [replace with Login name ] FROM WINDOWS WITH DEFAULT_DATABASE=[master] --GO DECLARE @SQL VARCHAR(MAX) DECLARE @DatabaseName VARCHAR(255)
DECLARE crFetch CURSOR FOR --SELECT NAME FROM SYSDATABASES WHERE name in --('master','model','tempdb','msdb','distribution')
SELECT NAME FROM SYS.DATABASES WHERE name not in ('master','model','tempdb','msdb','distribution')
OPEN crFetch FETCH NEXT FROM crFetch INTO @DatabaseName
WHILE @@FETCH_STATUS <> -1 BEGIN
SET @SQL =
'USE [' + @DatabaseName + ']' + 'if not exists (select name from sysusers where name='+ ''''+ 'replace with Login name '+ ''''+ ')' + 'CREATE USER [replace with Login name ] FOR LOGIN [replace with Login name ]' + 'EXEC sp_addrolemember N' + '''' + 'db_ETL' + '''' + ', N' + '''' + 'replace with Login name ' + '''' +' '
--'EXEC sp_addrolemember N' + '''' + 'db_datareader' + '''' + ', N' + '''' + 'replace with Login name ' + '''' + --'if not exists(select name from sysusers where name='+ ''''+ 'db_executor'+''''+ 'and issqlrole=1)' + --'create ROLE db_executor' + ' ' + --'GRANT EXECUTE TO db_executor' + ' ' + --'EXEC sp_addrolemember N' + '''' + 'db_executor' + '''' + ', N' + '''' + 'replace with Login name ' + '''' +'
--PRINT @SQL
EXEC(@SQL)
FETCH NEXT FROM crFetch INTO @DatabaseName END
CLOSE crFetch DEALLOCATE crFetch
来源:https://stackoverflow.com/questions/3550497/sql-server-give-a-login-permission-for-read-access-to-all-existing-and-future