2013-08-21 42 views
2

使用SQL Server 2012 您可以使用T-SQL像这样得到存储特效列表:是否有可能获得只读取数据的存储过程的列表?

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

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

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

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

+0

不会尝试只写miserablly的方法无法执行INSERT/UPDATE吗? –

+0

@TomerW并不总是这样:http://msdn.microsoft.com/en-us/library/ms181362.aspx - 虽然有很好的建议;你可以遍历'TRY ... CATCH'中的所有对象并记录失败/成功。 – gvee

+0

@TomerW - 否。如果您将'EXEC'授予存储过程,则可以应用所有权链接,这意味着它不会检查基表上的权限。 –

回答

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

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

+0

伟大的东西,这似乎工作!我不得不添加一些递归CTE代码来处理案件的存储过程调用其他存储过程,但到目前为止非常好 –

+0

边缘案例 - “is_updated”没有设置为1“TRUNCATE TABLE”语句由于TRUNCATE TABLE很少使用,所以我可以通过异常表。我不认为有任何代码可以检测到存储过程是否调用TRUNCATE TABLE(除了文本搜索)? –

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%' 
+0

更新两次,但没有删除? :)另外,OP可能希望允许执行本身也是只读的其他SP的SP。我认为OP正处于手动检查的痛苦之路,未来的变化可能会导致问题。 – MatBailie

+0

@MatBailie复制粘贴错误;)链上的非常好的一点。此代码仅用于说明目的,并提供了一个起点,绝对不是完整的最终目标! – gvee

+0

@MatBailie - 我认为你是正确的所有计数:) –

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标志:

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 
+0

只是FYI:“此功能将在未来版本的Microsoft SQL Server中删除。避免在新开发工作中使用此功能,并计划修改当前使用此功能的应用程序。改为使用sys.sql_expression_dependencies。“来源:http://msdn.microsoft.com/en-us/library/ms174402.aspx – gvee

相关问题