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

在工作当中遇到一个类似这样的问题:要对数据库账户的权限进行清理、设置,其中有一个用户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.sysusers WHERE 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

(0)

相关推荐

  • sql 判断数据库,表,存储过程等是否存在的代码

    代码: --库是否存在 if exists(select * from master..sysdatabases where name=N'库名') print 'exists' else print 'not exists' --------------- -- 判断要创建的表名是否存在 if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[表名]') and OBJECTPROPERTY(id, N'IsU

  • SQLserver 数据库危险存储过程删除与恢复方法

    今天为了实现SQLServer/" target="_blank">sqlserver的复制功能,因为以前删除了很多的sqlserver的一些会导致不安全因素的扩展,导致很多功能无法用,没有办法需要重新的恢复扩展. 曾经遇过,差点抓狂,有装MSSQL的朋友,赶紧试一下,删除以下的组件.当然,前提是你要把自己的数据库搞定后再去删除,否则组件删除后很多功能不能用,为了安全,就得牺牲某些功能,当然,像我这类的,我除了把MSSQL导入后,基本上一年用不到两次,所以,我是会毫不犹

  • SQL数据库存储过程示例解析

    什么是存储过程:存储过程可以说是一个记录集吧,它是由一些T-SQL语句组成的代码块,这些T-SQL语句代码像一个方法一样实现一些功能(对单表或多表的增删改查),然后再给这个代码块取一个名字,在用到这个功能的时候调用他就行了. 存储过程的好处: 1.由于数据库执行动作时,是先编译后执行的.然而存储过程是一个编译过的代码块,所以执行效率要比T-SQL语句高. 2.一个存储过程在程序在网络中交互时可以替代大堆的T-SQL语句,所以也能降低网络的通信量,提高通信速率. 3.通过存储过程能够使没有权限的用

  • SQL Server中通过扩展存储过程实现数据库的远程备份与恢复

    本文通过实例解析了 SQL Server 数据库扩展存储过程,实现远程备份与恢复的方法和步骤实例说明: 环境:win2k+sqlserver 2K+查询分析器 SQL SERVER服务实例名称:mainserver 需要备份的数据库名称: msdb 本地机器名称(Client端):david 本地用户:zf 密码:123 本地域名:domain 本地提供备份需求的文件夹:e: est 第一步: 建立共享文件夹 在程序代码中调用(或者CMD窗口) net share test=e: est 或者用

  • mysql 导入导出数据库以及函数、存储过程的介绍

    mysql常用导出数据命令:1.mysql导出整个数据库  mysqldump -hhostname -uusername -ppassword databasename > backupfile.sql   mysqldump -hlocalhost -uroot hqgr> hqgr.sql     (如果root用户没用密码可以不写-p,当然导出的sql文件你可以制定一个路径,未指定则存放在mysql的bin目录下) 2.mysql导出数据库一个表 mysqldump -hhostnam

  • 一个查看MSSQLServer数据库空间使用情况的存储过程 SpaceUsed

    运行下面存储过程 然后直接使用 SpaceUsed 就可以查看了. 存储过程代码 程序代码 复制代码 代码如下: Create procedure SpaceUsed as begin declare @id       int                  -- The object id of @objname. declare @type       character(2) -- The object type. declare       @pages       int     

  • mysql 查询数据库中的存储过程与函数的语句

    方法一: select `name` from mysql.proc where db = 'your_db_name' and `type` = 'PROCEDURE' //存储过程 select `name` from mysql.proc where db = 'your_db_name' and `type` = 'FUNCTION' //函数 方法二: show procedure status; //存储过程 SHOW PROCEDURE STATUS WHERE db='serva

  • MSSQL MySQL 数据库分页(存储过程)

    先看看单条 SQL 语句的分页 SQL 吧. 方法1: 适用于 SQL Server 2000/2005 复制代码 代码如下: SELECT TOP 页大小 * FROM table1 WHERE id NOT IN ( SELECT TOP 页大小*(页数-1) id FROM table1 ORDER BY id ) ORDER BY id 方法2: 适用于 SQL Server 2000/2005 复制代码 代码如下: SELECT TOP 页大小 * FROM table1 WHERE

  • MSSQL监控数据库的DDL操作(创建,修改,删除存储过程,创建,修改,删除表等)

    前言: 有时候,一个数据库有多个帐号,包括数据库管理员,开发人员,运维支撑人员等,可能有很多帐号都有比较大的权限,例如DDL操作权限(创建,修改,删除存储过程,创建,修改,删除表等),账户多了,管理起来就会相当麻烦,容易产生混乱,如果数据库管理员不监控数据库架构变更的话,就不知道谁对数据库架构做了啥改动(此处改动仅仅只DDL操作),尤其有时候,有些开发人员可能不按规章制度办事,绕过或忘了通知发布人员或DBA,直接去生产机做一些DDL操作,那么我们就需要对数据库架构某些更改的事件进行监控,如果能够

  • sqlserver 复制表 复制数据库存储过程的方法

    在目前的工作中需要解决复制整个SqlServer数据库的问题,复制的内容包括数据库大纲.数据库中的存储过程.函数.表结构.主外键关系以及表中的所有数据等,也就是说copy版本与原数据库一模一样.经过一段时间的摸索,找到的一个比较简单的解决方案是:  (1)在复制数据库之前,先备份该数据库到文件.  (2)依据备份文件创建新的数据库,并Restore即可.  备份数据库可用如下Sql语句:  string.Format("backup database {0} to disk = '{1}';&q

随机推荐