我在这里采用了一些代码:Check if role consists of particular user in 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。 为什么 ???
答案 0 :(得分:2)
您需要为每个过程参数定义length属性。如果将存储过程声明的开头更改为以下内容,则会返回正确的响应:
CREATE PROCEDURE [dbo].[Proc1]
(
@userName varchar(255),
@roleName varchar(255)
)
AS
如果没有length属性,SQL Server会自动将变量的长度定义为1,因此用户和角色分别与“o”和“m”匹配。 SQL Server在没有长度说明符的情况下处理变量的行为是不一致的 - 有时它们的长度为30,有时它们的长度为1.最佳做法是始终在字符串变量上指定长度属性。有关更多信息,请参阅以下SQL博客文章:
答案 1 :(得分:0)
此代码不好,因为如果用户是组的成员,那么它可以返回false,然后该组成为角色的成员。
使用内置函数 IS_MEMBER() - 这更加简单并且总是适用。