【问题标题】:Check that user belongs to db role检查用户是否属于 db 角色
【发布时间】:2011-01-20 21:53:02
【问题描述】:

我在这里拿了一些代码: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。 为什么 ???

【问题讨论】:

    标签: tsql


    【解决方案1】:

    您需要为每个过程参数定义长度属性。如果您将存储过程声明的开头更改为以下内容,它将返回正确的响应:

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

    如果没有长度属性,SQL Server 会自动将变量的长度定义为 1,因此用户和角色将分别与“o”和“m”进行匹配。 SQL Server 在处理没有长度说明符的变量时的行为不一致 - 有时它们的长度为 30,有时它们的长度为 1。最好始终指定字符串变量的长度属性。有关详细信息,请参阅以下 SQL 博客文章:

    【讨论】:

    • 感谢您的意见,圣殿骑士。对不起,长时间的回答。我不知道我应该将您的答案标记为有用和其他内容...
    【解决方案2】:

    这段代码不好,因为如果用户是一个组的成员,那么它可能会返回 false,那么它就是一个角色的成员。

    使用内置函数 IS_MEMBER() -- 这更简单且始终准确。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-24
      • 2018-06-10
      • 2021-02-24
      • 2019-04-30
      • 1970-01-01
      • 1970-01-01
      • 2012-07-28
      相关资源
      最近更新 更多