代码改变世界

MS SQL 批量给存储过程/函数授权

2013-05-14 23:38  潇湘隐者  阅读(3396)  评论(3编辑  收藏  举报

  在工作当中遇到一个类似这样的问题:要对数据库账户的权限进行清理、设置,其中有一个用户Test,只能拥有数据库MyAssistant的DML(更新、插入、删除等)操作权限,另外拥有执行数据库存储过程、函数的权限,但是不能进行DDL操作(包括新建、修改表、存储过程等...),于是需要设置登录名Test的相关权限:

1:右键单击登录名Test的属性.

clip_image002[6]

2: 在服务器角色里面选择"public"服务器角色。

clip_image004

3:在用户映射选项当中,选择"db_datareader"、"db_datawriter"、"public"三个数据库角色成员。

clip_image006

此时,已经实现了拥有DML操作权限,如果需要拥有存储过程和函数的执行权限,必须使用GRANT语句去授权,一个生产库的存储过程和函数加起来成千上百,如果手工执行的话,那将是一个辛苦的体力活,而我手头有十几个库,所以必须用脚本去实现授权过程。下面是我写的一个存储过程,亮点主要在于会判断存储过程、函数是否已经授予了EXE或SELECT权限给某个用户。这里主要用到了安全目录试图sys.database_permissions,例如,数据库里面有个存储过程dbo.sp_authorize_right,如果这个存储过程授权给Test用户了话,那么在目录试图sys.database_permissions里面会有一条记录,如下所示:

image

如果我将该存储过程授予EXEC权限给TEST1,那么

GRANT EXEC ON dbo.sp_diskcapacity_cal TO Test;

GRANT EXEC ON dbo.sp_diskcapacity_cal TO Test1;

image

SELECT * FROM sys.sysusers WHERE name ='Test' OR name ='Test1'

image

其实grantee_principal_id代表向其授予权限的数据库主体 ID ,所以我就能通过上面两个视图来判断存储过程是否授予执行权限给用户Test与否,同理,对于函数也是如此,存储过程如下所示,其实这个存储过程还可以扩展,如果您有特殊的需要的话。

Code Snippet
  1. USE MyAssistant;
  2. GO
  3.  
  4. SET ANSI_NULLS ON;
  5. GO
  6.  
  7. SET QUOTED_IDENTIFIER ON
  8. GO
  9.  
  10. IF EXISTS(SELECT 1 FROM sysobjects WHERE id=OBJECT_ID(N'sp_authorize_right')
  11.                                      AND OBJECTPROPERTY(id, 'IsProcedure') =1)
  12.     DROP PROCEDURE sp_authorize_right;
  13. GO
  14. --====================================================================================================
  15. --        ProcedureName        :            sp_authorize_right
  16. --        Author               :            Kerry    
  17. --        CreateDate           :            2013-05-10                
  18. --        Blog                 :            www.cnblogs.com/kerrycode/        
  19. --        Description          :            将数据库的所有自定义存储过程或自定义函数赋权给某个用户(可以继续扩展)
  20. /*****************************************************************************************************
  21.         Parameter              :                         参数说明
  22. ******************************************************************************************************
  23.         @type                  :  'P'  代表存储过程 , 'F' 代表存储过程,如果需要可以扩展其它对象
  24.         @user                  :  某个用户账户
  25. ******************************************************************************************************
  26.     Modified Date        Modified User        Version                    Modified Reason
  27. ******************************************************************************************************
  28.     2013-05-13           Kerry                 V01.00.01             排除系统存储过程和系统函数的授权处理
  29.     2013-05-14           Kerry                 V01.00.02             增加判断,如果某个存储过程已经赋予权限
  30.                                                                      则不做任何操作
  31. *****************************************************************************************************/
  32. --====================================================================================================
  33. CREATE PROCEDURE sp_authorize_right
  34. (
  35.     @type        AS   CHAR(10)    ,
  36.     @user        AS     VARCHAR(20)
  37. )
  38. AS
  39.  
  40.   DECLARE @sqlTextVARCHAR(1000);
  41.   DECLARE @UserId    INT;
  42.  
  43. SELECT @UserId = uid FROM sys.sysusers WHERE name=@user;
  44.  
  45.     IF @type = 'P'
  46.       BEGIN
  47.         CREATE TABLE #ProcedureName( SqlText  VARCHAR(max));
  48.         
  49.             INSERT  INTO #ProcedureName
  50.             SELECT  'GRANT EXECUTE ON ' + p.name + ' TO ' + @user + ';'
  51.             FROM    sys.procedures p
  52.             WHERE   NOT EXISTS( SELECT 1
  53.                                  FROM   sys.database_permissions r
  54.                                  WHERE  r.major_id = p.object_id
  55.                                         AND r.grantee_principal_id = @UserId
  56.                                         AND r.permission_name IS NOT  NULL )
  57.                             
  58.     
  59.             SELECT * FROM #ProcedureName;
  60.             --SELECT  'GRANT EXECUTE ON ' + NAME + ' TO ' +@user +';'
  61.             --FROM    sys.procedures;
  62.             --SELECT 'GRANT EXECUTE ON ' + [name] + ' TO ' +@user +';'
  63.             -- FROM sys.all_objects
  64.             --WHERE [type]='P' OR [type]='X' OR [type]='PC'
  65.             
  66.         DECLARE cr_procedure CURSOR FOR
  67.             SELECT * FROM #ProcedureName;
  68.             
  69.         OPEN cr_procedure;
  70.         
  71.         FETCH NEXT FROM cr_procedure  INTO @sqlText;
  72.         
  73.         WHILE @@FETCH_STATUS = 0
  74.         BEGIN
  75.         
  76.             EXECUTE(@sqlText);
  77.             
  78.             FETCH NEXT FROM cr_procedure INTO @sqlText;
  79.         END    
  80.         
  81.         CLOSE cr_procedure;
  82.         DEALLOCATE cr_procedure;
  83.         
  84.       END
  85.     ELSE
  86.         IF @type='F'
  87.            BEGIN
  88.                 
  89.                CREATE TABLE #FunctionSet( functionName VARCHAR(1000));
  90.                
  91.             INSERT  INTO #FunctionSet
  92.             SELECT  'GRANT EXEC ON ' + name + ' TO ' + @user + ';'
  93.             FROM    sys.all_objects s
  94.             WHERE   NOT EXISTS( SELECT 1
  95.                                  FROM   sys.database_permissions p
  96.                                  WHERE  p.major_id = s.object_id
  97.                                     AND  p.grantee_principal_id = @UserId)
  98.                     AND schema_id = SCHEMA_ID('dbo')
  99.                     AND( s.[type] = 'FN'
  100.                           OR s.[type] = 'AF'
  101.                           OR s.[type] = 'FS'
  102.                           OR s.[type] = 'FT'
  103.                         ) ;
  104.  
  105.               SELECT * FROM #FunctionSet;
  106.                     --SELECT 'GRANT EXEC ON ' + name + ' TO ' + @user +';' FROM sys.all_objects
  107.                     -- WHERE schema_id =schema_id('dbo')
  108.                     --     AND ([type]='FN' OR [type] ='AF' OR [type]='FS' OR [type]='FT' );
  109.                 
  110.             INSERT  INTO #FunctionSet
  111.             SELECT  'GRANT SELECT ON ' + name + ' TO ' + @user + ';'
  112.             FROM    sys.all_objects s
  113.             WHERE   NOT EXISTS( SELECT 1
  114.                                  FROM   sys.database_permissions p
  115.                                  WHERE  p.major_id = s.object_id
  116.                                     AND  p.grantee_principal_id = @UserId)
  117.                     AND schema_id = SCHEMA_ID('dbo')
  118.                     AND( s.[type] = 'TF'
  119.                           OR s.[type] = 'IF'
  120.                         ) ;    
  121.                         
  122.                 SELECT * FROM #FunctionSet;
  123.                 --SELECT 'GRANT SELECT ON ' + name + ' TO ' + @user +';' FROM sys.all_objects
  124.                 -- WHERE schema_id =schema_id('dbo')
  125.                 --     AND ([type]='TF' OR  [type]='IF') ;         
  126.                          
  127.                     
  128.                DECLARE cr_Function CURSOR FOR
  129.                     SELECT functionName FROM #FunctionSet;
  130.                     
  131.                 OPEN cr_Function;
  132.                 
  133.                 FETCH NEXT FROM cr_Function INTO @sqlText;
  134.                 
  135.                 WHILE @@FETCH_STATUS = 0
  136.                 BEGIN    
  137.                     PRINT(@sqlText);
  138.                     EXEC(@sqlText);
  139.                 
  140.                     FETCH NEXT FROM cr_Function INTO @sqlText;
  141.                 END
  142.                 
  143.                 CLOSE cr_Function;
  144.                 DEALLOCATE cr_Function;
  145.                 
  146.                 
  147.            END
  148. GO