2011-06-10 41 views

回答

24

你可以得到你需要这样的脚本是什么:

declare @RoleName varchar(50) = 'RoleName' 

declare @Script varchar(max) = 'CREATE ROLE ' + @RoleName + char(13) 
select @script = @script + 'GRANT ' + prm.permission_name + ' ON ' + OBJECT_NAME(major_id) + ' TO ' + rol.name + char(13) COLLATE Latin1_General_CI_AS 
from sys.database_permissions prm 
    join sys.database_principals rol on 
     prm.grantee_principal_id = rol.principal_id 
where rol.name = @RoleName 

print @script 
+1

如果你的角色拥有大量的权限,请小心。我发现SQL管理工作室会限制您可以在屏幕上打印的文本数量。当我在我的数据库上运行这个查询时,它实际上只有349的时候才拿起授权语句。我只需删除'@script = @script'+,并将结果作为网格返回。 – Frank 2012-11-19 23:29:01

+0

@Frank你可以进入管理工作室的选项,并将默认文本输出(结果)从256改为8000 – datagod 2015-08-28 13:34:02

3

在SSMS中右键单击用户/登录/角色节点并选择'Script As'将编写此特定用户/登录名/角色。你不能以这种方式编写角色mebership脚本。

Visual Studio使用“数据库开发”选项和Red Gate SQL Compare可以生成数据库之间的更改脚本,其中包括用户,角色和角色成员资格。

由VS角色成员产生看起来是这样的:

EXECUTE sp_addrolemember @rolename = N'db_datareader', @membername = N'DOMAIN\User'; 

如果你没有VS,你可以手动写那些,或用于生成它们创建的SQL脚本。

我确定也应该有一个免费的工具来做这样的事情,但是因为我不需要它,因为我有Visual Studio,所以我从来没有去过它。

编辑:我只是意识到,我回答错误的问题,你问有关角色的权限,我告诉你关于角色成员。为此事道歉。如果对别人有用,我会在这里留下这个答案。通过回答亚历克斯Aza看起来不错。

+1

“它产生只有一行'创建角色时,我右键单击角色,并选择“作为脚本” [ROLENAME ]授权[dbo]' 我也需要获得角色权限 – 2011-06-10 00:44:12

+0

@Foster Geng:是的,我知道。我个人使用Visual Studio的这种类型的工作人员。它产生了像'EXECUTE sp_addrolemember @rolename = N'db_datareader',@membername = N'DOMAIN \ User';' – 2011-06-10 00:48:32

0

这是一个痛苦,但你要找的一切都在一对夫妇的系统视图:的sys.database_permissions,sys.database_principals,和sys.database_role_members。这不是治疗的原因是因为sys.database_permissions中的major_id和minor_id具有基于类列的不同含义。但是,如果你的权限相对简单,那么这可能不会那么糟糕。看一看,看看你能得到什么。

-1

我在上面的代码中添加了一个额外的脚本功能。选择脚本取出角色和权限,因此您只需执行结果:

-- Update the RoleName with the name of your role 
DECLARE @RoleName VARCHAR(75) = 'RoleName' 

DECLARE @RoleTable TABLE ([GrantedBy] VARCHAR (50) NOT NULL, [Permission] VARCHAR (50) NOT NULL, [State] VARCHAR (50) NOT NULL) 
DECLARE @RoleScript VARCHAR(75) 

INSERT INTO @RoleTable SELECT p2.[name], dbp.[permission_name], dbp.[state_desc] 
FROM [sys].[database_permissions] dbp LEFT JOIN [sys].[objects] so 
    ON dbp.[major_id] = so.[object_id] LEFT JOIN [sys].[database_principals] p 
    ON dbp.[grantee_principal_id] = p.[principal_id] LEFT JOIN [sys].[database_principals] p2 
    ON dbp.[grantor_principal_id] = p2.[principal_id] 
WHERE p.[name] = @RoleName 

SELECT 'USE [' + DB_NAME() + '] CREATE ROLE [' + @RoleName + ']' AS 'Create Role' 
SELECT 'USE [' + DB_NAME() + '] GRANT ' + [Permission] + ' ON SCHEMA::[' + [GrantedBy] + '] TO [' + @RoleName + ']' AS 'Add Permissions' 
FROM @RoleTable 
4

此脚本为您的角色生成GRANT语句。我喜欢,它支持列leven权限。它必须适应您的需要(即针对更复杂的数据库进行改进,连接语句和执行,为您的角色添加创建语句)。但只给你一个想法:

SELECT 'GRANT ' + database_permissions.permission_name + ' ON ' + 
    CASE database_permissions.class_desc 
     WHEN 'SCHEMA' THEN schema_name(major_id) 
     WHEN 'OBJECT_OR_COLUMN' THEN 
      CASE WHEN minor_id = 0 THEN object_name(major_id) COLLATE Latin1_General_CI_AS_KS_WS 
      ELSE (SELECT object_name(object_id) + ' ('+ name + ')' 
        FROM sys.columns 
        WHERE object_id = database_permissions.major_id 
        AND column_id = database_permissions.minor_id) end 
     ELSE 'other' 
    END + 
    ' TO ' + database_principals.name COLLATE Latin1_General_CI_AS_KS_WS 
FROM sys.database_permissions 
JOIN sys.database_principals 
ON database_permissions.grantee_principal_id = database_principals.principal_id 
LEFT JOIN sys.objects --left because it is possible that it is a schema 
ON objects.object_id = database_permissions.major_id 
WHERE database_permissions.major_id > 0 
AND permission_name in ('SELECT','INSERT','UPDATE','DELETE') 
+0

漂亮的小脚本! – mcfea 2014-10-07 20:13:51

+0

任何方式梳理出架构,所以你可以得到“授予选择ON test.TABLE到fooUser”? – mcfea 2014-10-07 20:24:33

+0

我在答案中加入了模式。 – mcfea 2014-10-07 20:33:27

7

我对马里奥的Eis的的回答扩展:

SELECT 'GRANT ' + database_permissions.permission_name + ' ON ' + CASE database_permissions.class_desc 
     WHEN 'SCHEMA' 
      THEN '[' + schema_name(major_id) + ']' 
     WHEN 'OBJECT_OR_COLUMN' 
      THEN CASE 
        WHEN minor_id = 0 
         THEN'['+OBJECT_SCHEMA_NAME(major_id) + '].' + '[' + object_name(major_id) + ']' COLLATE Latin1_General_CI_AS_KS_WS 
        ELSE (
          SELECT object_name(object_id) + ' (' + NAME + ')' 
          FROM sys.columns 
          WHERE object_id = database_permissions.major_id 
           AND column_id = database_permissions.minor_id 
          ) 
        END 
     ELSE 'other' 
     END + ' TO [' + database_principals.NAME + ']' COLLATE Latin1_General_CI_AS_KS_WS 
FROM sys.database_permissions 
JOIN sys.database_principals ON database_permissions.grantee_principal_id = database_principals.principal_id 
LEFT JOIN sys.objects --left because it is possible that it is a schema 
    ON objects.object_id = database_permissions.major_id 
WHERE database_permissions.major_id > 0 
    AND permission_name IN (
     'SELECT' 
     ,'INSERT' 
     ,'UPDATE' 
     ,'DELETE' 
     ,'EXECUTE' 
     ) 
+3

谢谢,我使用了这个选项,因为我只需要这个特定角色,我将它添加到脚本的WHERE子句的末尾:AND database_principals.NAME ='RoleNameHere' – 2015-01-06 15:35:27

+2

如果您将“AS PermStatement”添加到末尾SELECT子句和“ORDER BY PermStatement”在WHERE子句后的结果将按字母顺序排列。这完全不会影响功能,但是如果您尝试比较同一数据库的两个不同版本上的角色权限,将会有所帮助。 – 2015-10-06 20:12:35

+0

如果要修改尚不存在的特定命令,请不要忘记首先创建角色:CREATE ROLE [rolename] – 2016-09-21 11:39:15

3

我做了一个非常全面的脚本,不仅脚本的所有权限,也是所有会员,并把蛋糕上的糖霜格式输出,以方便复制/粘贴到新的查询窗口中。我已经张贴脚本my blog从时间到时间更新了,但下面是其中应包括最基础的当前版本:

/******************************************************************** 
*                 * 
* Author: John Eisbrener           * 
* Script Purpose: Script out Database Role Definition    * 
* Notes: Please report any bugs to http://www.dbaeyes.com/   * 
*                 * 
********************************************************************/ 
DECLARE @roleName VARCHAR(255) 
SET @roleName = 'DatabaseRoleName' 

-- Script out the Role 
DECLARE @roleDesc VARCHAR(MAX), @crlf VARCHAR(2) 
SET @crlf = CHAR(13) + CHAR(10) 
SET @roleDesc = 'CREATE ROLE [' + @roleName + ']' + @crlf + 'GO' + @crlf + @crlf 

SELECT @roleDesc = @roleDesc + 
     CASE dp.state 
      WHEN 'D' THEN 'DENY ' 
      WHEN 'G' THEN 'GRANT ' 
      WHEN 'R' THEN 'REVOKE ' 
      WHEN 'W' THEN 'GRANT ' 
     END + 
     dp.permission_name + ' ' + 
     CASE dp.class 
      WHEN 0 THEN '' 
      WHEN 1 THEN --table or column subset on the table 
       CASE WHEN dp.major_id < 0 THEN 
        + 'ON [sys].[' + OBJECT_NAME(dp.major_id) + '] ' 
       ELSE 
        + 'ON [' + 
        (SELECT SCHEMA_NAME(schema_id) + '].[' + name FROM sys.objects WHERE object_id = dp.major_id) 
         + -- optionally concatenate column names 
        CASE WHEN MAX(dp.minor_id) > 0 
         THEN '] ([' + REPLACE(
             (SELECT name + '], [' 
             FROM sys.columns 
             WHERE object_id = dp.major_id 
              AND column_id IN (SELECT minor_id 
                   FROM sys.database_permissions 
                   WHERE major_id = dp.major_id 
                   AND USER_NAME(grantee_principal_id) IN (@roleName) 
                  ) 
             FOR XML PATH('') 
             ) --replace final square bracket pair 
            + '])', ', []', '') 
         ELSE ']' 
        END + ' ' 
       END 
      WHEN 3 THEN 'ON SCHEMA::[' + SCHEMA_NAME(dp.major_id) + '] ' 
      WHEN 4 THEN 'ON ' + (SELECT RIGHT(type_desc, 4) + '::[' + name FROM sys.database_principals WHERE principal_id = dp.major_id) + '] ' 
      WHEN 5 THEN 'ON ASSEMBLY::[' + (SELECT name FROM sys.assemblies WHERE assembly_id = dp.major_id) + '] ' 
      WHEN 6 THEN 'ON TYPE::[' + (SELECT name FROM sys.types WHERE user_type_id = dp.major_id) + '] ' 
      WHEN 10 THEN 'ON XML SCHEMA COLLECTION::[' + (SELECT SCHEMA_NAME(schema_id) + '.' + name FROM sys.xml_schema_collections WHERE xml_collection_id = dp.major_id) + '] ' 
      WHEN 15 THEN 'ON MESSAGE TYPE::[' + (SELECT name FROM sys.service_message_types WHERE message_type_id = dp.major_id) + '] ' 
      WHEN 16 THEN 'ON CONTRACT::[' + (SELECT name FROM sys.service_contracts WHERE service_contract_id = dp.major_id) + '] ' 
      WHEN 17 THEN 'ON SERVICE::[' + (SELECT name FROM sys.services WHERE service_id = dp.major_id) + '] ' 
      WHEN 18 THEN 'ON REMOTE SERVICE BINDING::[' + (SELECT name FROM sys.remote_service_bindings WHERE remote_service_binding_id = dp.major_id) + '] ' 
      WHEN 19 THEN 'ON ROUTE::[' + (SELECT name FROM sys.routes WHERE route_id = dp.major_id) + '] ' 
      WHEN 23 THEN 'ON FULLTEXT CATALOG::[' + (SELECT name FROM sys.fulltext_catalogs WHERE fulltext_catalog_id = dp.major_id) + '] ' 
      WHEN 24 THEN 'ON SYMMETRIC KEY::[' + (SELECT name FROM sys.symmetric_keys WHERE symmetric_key_id = dp.major_id) + '] ' 
      WHEN 25 THEN 'ON CERTIFICATE::[' + (SELECT name FROM sys.certificates WHERE certificate_id = dp.major_id) + '] ' 
      WHEN 26 THEN 'ON ASYMMETRIC KEY::[' + (SELECT name FROM sys.asymmetric_keys WHERE asymmetric_key_id = dp.major_id) + '] ' 
     END COLLATE SQL_Latin1_General_CP1_CI_AS 
     + 'TO [' + @roleName + ']' + 
     CASE dp.state WHEN 'W' THEN ' WITH GRANT OPTION' ELSE '' END + @crlf 
FROM sys.database_permissions dp 
WHERE USER_NAME(dp.grantee_principal_id) IN (@roleName) 
GROUP BY dp.state, dp.major_id, dp.permission_name, dp.class 

SELECT @roleDesc = @roleDesc + 'GO' + @crlf + @crlf 

-- Display users within Role. Code stubbed by Joe Spivey 
SELECT @roleDesc = @roleDesc + 'EXECUTE sp_AddRoleMember ''' + roles.name + ''', ''' + users.name + '''' + @crlf 
FROM sys.database_principals users 
     INNER JOIN sys.database_role_members link 
      ON link.member_principal_id = users.principal_id 
     INNER JOIN sys.database_principals roles 
      ON roles.principal_id = link.role_principal_id 
WHERE roles.name = @roleName 

-- PRINT out in blocks of up to 8000 based on last \r\n 
DECLARE @printCur INT 
SET @printCur = 8000 

WHILE LEN(@roleDesc) > 8000 
BEGIN 
    -- Reverse first 8000 characters and look for first lf cr (reversed crlf) as delimiter 
    SET @printCur = 8000 - CHARINDEX(CHAR(10) + CHAR(13), REVERSE(SUBSTRING(@roleDesc, 0, 8000))) 

    PRINT LEFT(@roleDesc, @printCur) 
    SELECT @roleDesc = RIGHT(@roleDesc, LEN(@roleDesc) - @printCur) 
END 

PRINT @RoleDesc + 'GO' 

值得注意的是,你可能会碰到一个情况sp_AddRoleMember系统中sp将用户添加到之前没有的数据库中。在这种情况下,即使添加了用户,他们也不会被授予CONNECT权限,并且由该用户或组进行的任何连接尝试都将生成用户登录错误。为了纠正这个问题,您需要执行每个新用户以下的数据库内/组:

USE [DatabaseName] 
GO 
GRANT CONNECT TO [Login/GroupName] 
GO