是否有可能获得只读取数据的存储过程列表?

时间:2013-08-21 07:30:53

标签: sql-server tsql

使用SQL Server 2012。 您可以使用TSQL获取存储过程的列表,如下所示:

select * from information_schema.routines r where r.ROUTINE_TYPE = 'PROCEDURE'

有没有办法只获取只读取数据的存储过程的子集(即不要在其中尝试INSERT或UPDATE语句,或者它们调用的任何存储过程)。

我在想这个问题的答案是否定的,但是为了以防万一,只是把它放在这里。

最终目标是尝试创建一个只能读取数据库中数据的数据库角色,而不是修改它。 db_datareader角色有帮助,但也希望能够调用只读取数据的存储过程。最后一种方法是为每个存储过程授予执行权限。

3 个答案:

答案 0 :(得分:5)

假设您的存储过程编码是一致的(例如,您始终使用EXEC显式调用存储过程而不仅仅是其名称),那么您可以使用以下代码获得良好的开端。

SELECT Object_Name(object_id)
     , *
FROM   sys.sql_modules
WHERE  definition NOT LIKE '%EXEC %'
AND    definition NOT LIKE '%INSERT%'
AND    definition NOT LIKE '%UPDATE%'
AND    definition NOT LIKE '%DELETE%'
AND    definition NOT LIKE '%MERGE%'

答案 1 :(得分:1)

不确定是否始终可以依赖目录视图sys.sql_dependencies,而是使用语句

select o.name, ref.name, refc.name, * 
from sys.sql_dependencies d 
inner join sys.objects o on o.object_id = d.object_id
inner join sys.objects ref on d.referenced_major_id = ref.object_id
left outer join sys.columns refc 
    on d.referenced_major_id = refc.object_id 
        and d.referenced_minor_id = refc.column_id
where is_updated = 1
order by 1, 2, 3

你可以找出修改其他对象的对象。

基于此查询,我们可以选择标有is_updated标志的存储过程 not

select o.name
from sys.objects o
where o.type = 'P' and o.object_id not in (
    select d.object_id from sys.sql_dependencies d where is_updated = 1
)
order by 1

答案 2 :(得分:1)

我在上面针对SQL Server 2012调整了我的查询(thx @gvee)。

select o.name, ref.name, refc.name, * 
from sys.sql_expression_dependencies d 
inner join sys.objects o on o.object_id = d.referencing_id
inner join sys.objects ref on d.referenced_id = ref.object_id
left outer join sys.columns refc 
    on d.referenced_id = refc.object_id 
        and d.referenced_minor_id = refc.column_id
order by 1, 2, 3


select o.name,  OBJECT_SCHEMA_NAME(o.object_id), *
from sys.objects o
where o.type = 'P' and o.name not in ('sp_upgraddiagrams')
and not exists (
    select 1
    from  sys.dm_sql_referenced_entities(
        OBJECT_SCHEMA_NAME(o.object_id) + '.' + o.name, 'OBJECT')
    where is_updated = 1
)
order by 1

请注意,sys.dm_sql_referenced_entities不会返回SQL 2008中的is_updated列。

查询sp_upgraddiagrams会引发错误,但仍会返回结果集。