实现 SQL 脚本的最佳方式是什么,该脚本将向数据库中所有用户表的数据库角色授予权限?

What's the best way to implement a SQL script that will grant permissions to a database role on all the user tables in a database?

提问人:Scott Lawrence 提问时间:9/5/2008 最后编辑:LaurelScott Lawrence 更新时间:6/29/2016 访问量:4001

问:

实现 SQL 脚本的最佳方式是什么,该脚本将向数据库中所有用户表的数据库角色授予选择、引用、插入、更新和删除权限?

理想情况下,当新表添加到数据库时,此脚本可以多次运行。SQL Server Management Studio 为单个数据库对象生成脚本,但我正在寻找更多的“即发即弃”脚本。

sql-server t-sql 权限

评论

1赞 Edwin Stoteler 9/17/2015
这不就是db_datareader和db_datawriter角色的用途吗?或者当被问到这个问题时它们不存在吗?

答:

2赞 Dr Zimmerman 9/5/2008 #1

我确信有一种更简单的方法,但您可以遍历数据库中的 sysobjects 表,并向存在的任何用户表对象授予权限。然后,每当添加新表时,都可以多次运行它。

1赞 ninesided 9/5/2008 #2

齐默尔曼博士在这方面走在正确的轨道上。我希望编写一个存储过程,该过程具有使用立即执行在用户对象之间循环的游标以影响授权。像这样的东西:

 IF EXISTS (
    SELECT 1 FROM sysobjects
    WHERE name = 'sp_grantastic'
    AND type = 'P'
)
DROP PROCEDURE sp_grantastic
GO
CREATE PROCEDURE sp_grantastic
AS
DECLARE
 @object_name VARCHAR(30)
,@time       VARCHAR(8)
,@rights     VARCHAR(20)
,@role       VARCHAR(20)

DECLARE c_objects CURSOR FOR
    SELECT  name
    FROM    sysobjects
    WHERE   type IN ('P', 'U', 'V')
    FOR READ ONLY

BEGIN

    SELECT  @rights = 'ALL'
           ,@role = 'PUBLIC'

    OPEN c_objects
    WHILE (1=1)
    BEGIN
        FETCH c_objects INTO @object_name
        IF @@SQLSTATUS <> 0 BREAK

        SELECT @time = CONVERT(VARCHAR, GetDate(), 108)
        PRINT '[%1!] hitting up object %2!', @time, @object_name
        EXECUTE('GRANT '+ @rights +' ON '+ @object_name+' TO '+@role)

    END

    PRINT '[%1!] fin!', @time

    CLOSE c_objects
    DEALLOCATE CURSOR c_objects
END
GO
GRANT ALL ON sp_grantastic TO PUBLIC
GO

然后你可以开火并忘记:

EXEC sp_grantastic
0赞 Pascal Paradis 9/5/2008 #3

我们在我工作的地方使用类似的东西。遍历系统的每个表、视图、存储过程。

CREATE PROCEDURE dbo.SP_GrantFullAccess 
    @username varchar(300)
AS

DECLARE @on varchar(300) 
DECLARE @count int
SET @count = 0

PRINT 'Granting access to user ' + @username + ' on the following objects:'

DECLARE c CURSOR FOR 
SELECT name FROM sysobjects WHERE type IN('U', 'V', 'SP', 'P') ORDER BY name
OPEN c 
FETCH NEXT FROM c INTO @on 
WHILE @@FETCH_STATUS = 0 
BEGIN 
 SET @count = @count + 1
 EXEC('GRANT ALL ON [' + @on + '] TO [' + @username + ']') 
 --PRINT 'GRANT ALL ON [' + @on + '] TO ' + @username
 PRINT @on
 FETCH NEXT FROM c INTO @on 
END 
CLOSE c 
DEALLOCATE c

PRINT 'Granted access to ' + cast(@count as varchar(4)) + ' object(s).'
GO
1赞 Martynnw 9/10/2008 #4

有一种未记录的 MS 程序称为 sp_MSforeachtable,您可以使用它肯定是在 2000 年和 2005 年。

要授予选择权限,用法为:

EXECUTE sp_MSforeachtable @command1=' Grant Select on ? to RoleName'

要授予其他权限,请为每个权限创建一个新语句,或者将它们添加到命令中,如下所示:

EXECUTE sp_MSforeachtable @command1=' Grant Select on ? to RoleName; Grant Delete on ? to RoleName;'

通过一些尝试,也可以将角色名称转换为参数。

0赞 CSecord 11/3/2009 #5
use [YourDb]
GO
exec sp_MSforeachtable @command1=
    "GRANT DELETE, INSERT, REFERENCES, SELECT, UPDATE ON ? TO Admins, Mgmt",
    @whereand = " and o.name like 'tbl_%'"
GO

use [YourDb]
GO
exec sp_MSforeachtable @command1=
    "GRANT REFERENCES, SELECT ON ? TO Employee, public",
    @whereand = " and o.name like 'tbl_%'"
GO