sqlSQL数据库怎么批量为存储过程/函数授权呢?

2022-11-12 09:44:42
内容摘要
这篇文章主要为大家详细介绍了sqlSQL数据库怎么批量为存储过程/函数授权呢?,具有一定的参考价值,可以用来参考一下。 对此感兴趣的朋友,看看idc笔记做的技术笔记! 在工作当中遇
文章正文

这篇文章主要为大家详细介绍了sqlSQL数据库怎么批量为存储过程/函数授权呢?,具有一定的参考价值,可以用来参考一下。

对此感兴趣的朋友,看看idc笔记做的技术笔记!

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

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

【图片暂缺】

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

【图片暂缺】

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

【图片暂缺】

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

【图片暂缺】

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

GRANT EXEC ON dbo.sp_diskcapacity_cal TO Test;

GRANT EXEC ON dbo.sp_diskcapacity_cal TO Test1;

【图片暂缺】

SELECT * FROM sys.sysusersWHERE name ='Test' OR name ='Test1'

【图片暂缺】

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

代码如下:


Code Snippet
USE MyAssistant;
GO
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON
GO
IF EXISTS(SELECT 1 FROM sysobjects WHERE id=OBJECT_ID(N'sp_authorize_right') AND OBJECTPROPERTY(id, 'IsProcedure') =1)
 DROP PROCEDURE sp_authorize_right;
GO
--=========================================================================================================
-- ProcedureName : sp_authorize_right
-- Author : Kerry 
-- CreateDate : 2013-05-10 
-- Blog : www.cnblogs.com/kerrycode/ 
-- Description : 将数据库的所有自定义存储过程或自定义函数赋权给某个用户(可以继续扩展)
/**********************************************************************************************************
 Parameter : 参数说明
***********************************************************************************************************
 @type : 'P' 代表存储过程 , 'F' 代表存储过程,如果需要可以扩展其它对象
 @user : 某个用户账户
***********************************************************************************************************
 Modified Date Modified User Version Modified Reason
***********************************************************************************************************
 2013-05-13 Kerry V01.00.01 排除系统存储过程和系统函数的授权处理
 2013-05-14 Kerry V01.00.02 增加判断,如果某个存储过程已经赋予权限
 则不做任何操作
***********************************************************************************************************/
--=========================================================================================================
CREATE PROCEDURE sp_authorize_right
(
 @type AS CHAR(10) ,
 @user AS VARCHAR(20)
)
AS
 DECLARE @sqlTextVARCHAR(1000);
 DECLARE @UserId INT;
SELECT @UserId = uid FROM sys.sysusers WHERE name=@user;
 IF @type = 'P'
 BEGIN
 CREATE TABLE #ProcedureName( SqlText VARCHAR(max));
 INSERT INTO #ProcedureName
 SELECT 'GRANT EXECUTE ON ' + p.name + ' TO ' + @user + ';'
 FROM sys.procedures p
 WHERE NOT EXISTS( SELECT 1
 FROM sys.database_permissions r
 WHERE r.major_id = p.object_id
 AND r.grantee_principal_id = @UserId
 AND r.permission_name IS NOT NULL )
 SELECT * FROM #ProcedureName;
 --SELECT 'GRANT EXECUTE ON ' + NAME + ' TO ' +@user +';'
 --FROM sys.procedures;
 --SELECT 'GRANT EXECUTE ON ' + [name] + ' TO ' +@user +';'
 -- FROM sys.all_objects
 --WHERE [type]='P' OR [type]='X' OR [type]='PC'
 DECLARE cr_procedure CURSOR FOR
 SELECT * FROM #ProcedureName;
 OPEN cr_procedure;
 FETCH NEXT FROM cr_procedure INTO @sqlText;
 WHILE @@FETCH_STATUS = 0
 BEGIN
 EXECUTE(@sqlText);
 FETCH NEXT FROM cr_procedure INTO @sqlText;
 END 
 CLOSE cr_procedure;
 DEALLOCATE cr_procedure;
 END
 ELSE
 IF @type='F'
 BEGIN
 CREATE TABLE #FunctionSet( functionName VARCHAR(1000));
 INSERT INTO #FunctionSet
 SELECT 'GRANT EXEC ON ' + name + ' TO ' + @user + ';'
 FROM sys.all_objects s
 WHERE NOT EXISTS( SELECT 1
 FROM sys.database_permissions p
 WHERE p.major_id = s.object_id
 AND p.grantee_principal_id = @UserId)
 AND schema_id = SCHEMA_ID('dbo')
 AND( s.[type] = 'FN'
 OR s.[type] = 'AF'
 OR s.[type] = 'FS'
 OR s.[type] = 'FT'
 ) ;
 SELECT * FROM #FunctionSet;
 --SELECT 'GRANT EXEC ON ' + name + ' TO ' + @user +';' FROM sys.all_objects
 -- WHERE schema_id =schema_id('dbo')
 -- AND ([type]='FN' OR [type] ='AF' OR [type]='FS' OR [type]='FT' );
 INSERT INTO #FunctionSet
 SELECT 'GRANT SELECT ON ' + name + ' TO ' + @user + ';'
 FROM sys.all_objects s
 WHERE NOT EXISTS( SELECT 1
 FROM sys.database_permissions p
 WHERE p.major_id = s.object_id
 AND p.grantee_principal_id = @UserId)
 AND schema_id = SCHEMA_ID('dbo')
 AND( s.[type] = 'TF'
 OR s.[type] = 'IF'
 ) ; 
 SELECT * FROM #FunctionSet;
 --SELECT 'GRANT SELECT ON ' + name + ' TO ' + @user +';' FROM sys.all_objects
 -- WHERE schema_id =schema_id('dbo')
 -- AND ([type]='TF' OR [type]='IF') ; 
 DECLARE cr_Function CURSOR FOR
 SELECT functionName FROM #FunctionSet;
 OPEN cr_Function;
 FETCH NEXT FROM cr_Function INTO @sqlText;
 WHILE @@FETCH_STATUS = 0
 BEGIN 
 PRINT(@sqlText);
 EXEC(@sqlText);
 FETCH NEXT FROM cr_Function INTO @sqlText;
 END
 CLOSE cr_Function;
 DEALLOCATE cr_Function;
 END
GO

注:关于sqlSQL数据库怎么批量为存储过程/函数授权呢?的内容就先介绍到这里,更多相关文章的可以留意

代码注释

作者:喵哥笔记

IDC笔记

学的不仅是技术,更是梦想!