使用SQL Server 2012。 您可以使用TSQL获取存储过程的列表,如下所示:
select * from information_schema.routines r where r.ROUTINE_TYPE = 'PROCEDURE'
有没有办法只获取只读取数据的存储过程的子集(即不要在其中尝试INSERT或UPDATE语句,或者它们调用的任何存储过程)。
我在想这个问题的答案是否定的,但是为了以防万一,只是把它放在这里。
最终目标是尝试创建一个只能读取数据库中数据的数据库角色,而不是修改它。 db_datareader角色有帮助,但也希望能够调用只读取数据的存储过程。最后一种方法是为每个存储过程授予执行权限。
答案 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
会引发错误,但仍会返回结果集。