2009-10-13 28 views
1

我有一個Windows服務需要SQL Server 2005數據庫的執行權限。在啓動時,我檢查是否可以連接到數據庫,如果不能,我會停止服務。我也想做一個檢查,看看我是否可以使用該連接執行存儲過程。有沒有辦法做到這一點,而不實際嘗試執行一個存儲過程,並在出現異常時查看異常?如何確定我是否以編程方式對數據庫執行權限?

+0

如果這是SQL Server,請參閱[這個問題](http://stackoverflow.com/questions/484145/ms-sql-server-check-to-see-if-a-user-can-execute-一個存儲的過程)。 – Randolpho 2009-10-13 19:59:25

回答

11

SQL 2005和您可以檢查與HAS_PERM_BY_NAME任何權限:

SELECT HAS_PERMS_BY_NAME('sp_foo', 'OBJECT', 'EXECUTE'); 
0

您必須有權訪問數據庫的DataDictionary並對其運行查詢以確定您登錄的帳戶擁有哪些權限。這會因數據庫而異。

3

你可以運行這樣的查詢:

SELECT 
    o.NAME,COALESCE(p.state_desc,'?permission_command?')+' '+COALESCE(p.permission_name,'?permission_name?')+' ON ['+SCHEMA_NAME(o.schema_id)+'].['+COALESCE(o.Name,'?object_name?')+'] TO ['+COALESCE(dp.Name,'?principal_name?')+']' COLLATE SQL_Latin1_General_CP1_CI_AS AS GrantCommand 
    FROM sys.all_objects       o 
     INNER JOIN sys.database_permissions  p ON o.OBJECT_ID=p.major_id 
     LEFT OUTER JOIN sys.database_principals dp ON p.grantee_principal_id = dp.principal_id 
    where p.state_desc='GRANT' AND p.permission_name='EXECUTE' 
     AND o.NAME='YourProcedureName' 
     AND dp.Name='YourSecurityName' 

...並刪除grant命令的別緻的格式,它的存在僅作參考

這些都是好的太...

SELECT * FROM fn_my_permissions('YourTable', 'OBJECT') 
SELECT * FROM fn_my_permissions('YourProcedure', 'OBJECT') 
SELECT * FROM fn_my_permissions (NULL, 'DATABASE') 
SELECT * FROM fn_my_permissions(NULL, 'SERVER') 

要查看權限,其他人可以做到這一點:

EXECUTE AS user = 'loginToTest' 
GO 
PRINT 'SELECT permissions on tables:' 
SELECT 
    HAS_PERMS_BY_NAME( QUOTENAME(SCHEMA_NAME(schema_id))+'.' + QUOTENAME(name) 
          ,'OBJECT','SELECT' 
        ) AS have_select 
     , * 
    FROM sys.tables; 

PRINT 'EXECUTE permissions on stored procedures:' 
SELECT 
    HAS_PERMS_BY_NAME( QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + QUOTENAME(name) 
     ,'OBJECT', 'EXECUTE') AS have_execute 
     , * 
    FROM sys.procedures; 
GO 
REVERT; 
GO 
1

這個答案的第一部分展示瞭如何在T-SQL檢查的權利,第二部分給出了一個例子,如何使用這個在實體框架(注意,是EF版本之間的差異 - 給出的例子是EF 4,但可以很容易地改變到新的版本):


第一部分(SQL):

我使用以下T-SQL腳本檢查權限。它首先檢查是否有任何權限,然後檢查SP的執行權限,最後選擇表的權限。請參閱this鏈接以獲取更多信息。

-- 1. Do I have any permissions? 
SELECT HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'ANY') DoIHaveAnyRights; 

-- 2. create list of schemas 
declare @SchemaList table (schema_id int, name nvarchar(max)); 

PRINT 'Schemas regarded:' 

insert into @SchemaList 
select distinct schema_id, name FROM sys.schemas 
where name in ('dbo') -- enter the schemas you like to check comma-separated 

SELECT s.name, s.schema_id FROM sys.schemas s 
join @SchemaList sl on s.schema_id=sl.schema_id 

-- 3. check execute permissions 
PRINT 'EXECUTE permissions on stored procedures:' 
SELECT 
    HAS_PERMS_BY_NAME(QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' + QUOTENAME(t.name) 
     ,'OBJECT', 'EXECUTE') AS [have execute] 
     ,'['+s.name +'].['+ t.name+']' as [object] 
     --, * 
    FROM sys.procedures t 
    join @SchemaList s on t.schema_id=s.schema_id 
order by s.name, t.name; 

-- 4. check select permissions 
PRINT 'SELECT permissions on tables:' 
SELECT 
    HAS_PERMS_BY_NAME(QUOTENAME(SCHEMA_NAME(t.schema_id))+'.' + QUOTENAME(t.name) 
     ,'OBJECT','SELECT') AS [have select] 
     ,'['+s.name +'].['+ t.name+']' as [object] 
     --, * 
    FROM sys.tables t 
    join @SchemaList s on t.schema_id=s.schema_id 
order by s.name, t.name; 

隨着Northwind數據庫例如,這給你以下結果:

Query_results

注意,您可以配置在第2步認爲如果你不」的模式t需要檢查一組有限的模式,您可以註釋掉insert into @SchemaList語句中的where子句以獲取所有模式。


第二部分(實體框架):

在本節中,我想告訴你,你怎麼可以得到的結果爲實體框架。 讓我們假設你想使用任何在你的LINQ查詢的表來檢查,如果您有任何權利之前。看看這個例子(爲簡單起見,我在LinqPad做了,請加System.Data.Entity.dll,並通過F4其命名空間在運行之前):

void Main() 
{ 
    var dc=this; 
    var sql="SELECT TOP 1 " 
       + "HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'ANY') DoIHaveAnyRights;"; 
    var result=dc.ExecuteStoreQuery<Rights>(sql); 
    if (result1.DoIHaveAnyRights==1) 
    { 
     Console.WriteLine("OK"); // ok 
    } 
    else 
    { 
     // no rights: Show error etc. 
     Console.WriteLine("No rights"); // ok 
    } 
} 

public class Rights 
{ 
    public Int32 DoIHaveAnyRights { get; set; } 
} 

同樣,你也可以使用查詢從第一部分我的答案,如:

var sql="select top 1 case when cnt.NoRightsCount=0 then 1 else 0 end " 
+"as DoIHaveAnyRights " 
+"from (SELECT count(1) NoRightsCount FROM sys.procedures t " 
+"where HAS_PERMS_BY_NAME(" 
+"QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' + QUOTENAME(t.name)" 
+",'OBJECT', 'EXECUTE')<>1) cnt"; 

這個查詢將檢查是否有您的數據庫中的存儲過程,而您沒有權限來執行 - 在這種情況下,返回值將是result1.DoIHaveAnyRights!=1

我覺得你的想法,玩的可能性:請記住,EF需要訪問所有的數據庫表,存儲過程等你映射到 - 你可以使用上面的代碼,你之前檢查訪問它們。不幸的是,目前沒有更簡單的方法來做到這一點。

+1

+1的EF除 – SpaceghostAli 2014-10-21 15:47:59

相關問題