2010-02-25 69 views
1

我花了一些代碼在這裏:Check if role consists of particular user in DB?檢查用戶屬於DB角色

SELECT * 
      FROM sys.database_role_members AS RM 
      JOIN sys.database_principals AS U 
      ON RM.member_principal_id = U.principal_id 
      JOIN sys.database_principals AS R 
      ON RM.role_principal_id = R.principal_id 
      WHERE U.name = 'operator1' 
      AND R.name = 'myrole1' 

該查詢返回1行。這意味着用戶'operator1'屬於角色'myrole1'。 現在我試圖創建一個存儲過程是:

CREATE PROCEDURE [dbo].[Proc1] 
(
    @userName varchar, 
    @roleName varchar 
) 
AS 

IF EXISTS(SELECT * 
      FROM sys.database_role_members AS RM 
      JOIN sys.database_principals AS U 
      ON RM.member_principal_id = U.principal_id 
      JOIN sys.database_principals AS R 
      ON RM.role_principal_id = R.principal_id 
      WHERE U.name = @userName 
      AND R.name = @roleName) 
      RETURN 0 
ELSE RETURN -1 

我使用標準的命令從SQL Server 2008「執行存儲過程」

DECLARE @return_value int 

EXEC @return_value = [dbo].[Proc1] 
     @userName = N'operator1', 
     @roleName = N'myrole1' 

SELECT 'Return Value' = @return_value 

GO 

它總是返回-1。 爲什麼 ???

回答

2

您需要爲每個過程參數定義長度屬性。如果你改變你的存儲過程聲明的開頭爲以下,它將返回正確的響應:

CREATE PROCEDURE [dbo].[Proc1] 
(
    @userName varchar(255), 
    @roleName varchar(255) 
) 
AS 

沒有長度的屬性時,SQL Server自動定義的變量爲1的長度,這樣用戶和角色分別與「o」和「m」匹配。 SQL Server在處理變量時沒有使用長度說明符的行爲是不一致的 - 有時它們的長度爲30,有時它們的長度爲1.最好的做法是始終在字符串變量上指定長度屬性。請參閱下面的SQL博客文章以瞭解更多信息:

http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/09/bad-habits-to-kick-declaring-varchar-without-length.aspx

+0

感謝您的輸入,Templar。 對不起,長時間的答案。我不知道我應該把你的答案標記爲有用的和其他的東西...... – 2010-03-29 13:21:47

0

此代碼是不好的,因爲它可以返回false,如果用戶是一組,然後是角色的成員的成員。

用戶內置函數IS_MEMBER() - 這是非常簡單,總是可以保證。