IS_ROLEMEMBER错误地为数据库角色成员返回0?

时间:2013-11-12 08:18:16

标签: sql-server ssms

运行SQL Server 2012的本地实例。

我创建了一个自定义角色:

CREATE ROLE [my_user] AUTHORIZATION [dbo]

对于我的所有用户(本地Windows用户和SQL用户),我已为我的数据库指定了此角色(在User Mappings设置下)。因此,以下查询应返回1:

SELECT IS_ROLEMEMBER('my_user')

对于我经过Windows身份验证的用户,它确实返回1,但只要我以 SQL用户身份登录,就会返回0 。我已经三次检查过SQL用户确实有这个角色。我在这里缺少什么?

更新

进行了更多测试。这当然是奇怪的行为。我执行了以下步骤:

  1. 在我的本地SQL Server我创建了一个用户test的数据库sa。已添加角色my_user
  2. sa中以Management Studio登录,并将MYDOMAIN\MyUser添加到此角色。
  3. 使用Windows身份验证重新登录并执行IS_ROLEMEMBER('my_user')返回0。
  4. 使用sa(指定用户名)和Windows用户尝试查询。同样的问题。
  5. 尝试重新启动SQL Server,以防万一。
  6. 这没有任何意义!如果我右键单击该角色,我可以看到我的Windows用户确实是其中的一员。 IS_ROLEMEMBER功能有缺陷!当我运行以下查询时,它显示我的用户确实是数据库角色的成员:

    SELECT
        USER_NAME(memberuid), USER_NAME(groupuid)
    FROM
        sys.sysmembers
    WHERE
        USER_NAME(groupuid) = 'my_user'
    

    这也显示了我的会员资格:

    select r.name as role_name, m.name as member_name from sys.database_role_members rm 
    inner join sys.database_principals r on rm.role_principal_id = r.principal_id
    inner join sys.database_principals m on rm.member_principal_id = m.principal_id
    

    其他一些信息:

    • 我在域名上,但目前已断开连接。我连接时也看到了这个问题。
    • 运行Windows 8.1 64位。

    更新2

    如果我按照某些人的建议显式指定了主体,我会收到此错误(执行为sa):

    SELECT IS_ROLEMEMBER('my_user', 'MYDOMAIN\UserX')
    
    Msg 15404, Level 16, State 19, Line 1
    Could not obtain information about Windows NT group/user 'MYDOMAIN\UserX',
    error code 0x54b.
    

    可能IS_ROLEMEMBER遇到同样的问题,但是不打印错误吗?

3 个答案:

答案 0 :(得分:4)

我刚遇到同样的问题......我发现有问题的用户也分配了服务器角色。当我删除除了' public'之外的所有服务器角色时,突然is_rolemember查询开始正确报告1而不是零.....我来回测试了几次以确认。

答案 1 :(得分:3)

也有这个问题。事实证明我必须删除sysadmin服务器角色,然后才能工作。

取自:https://docs.microsoft.com/en-us/sql/t-sql/functions/is-member-transact-sql

  

sysadmin固定服务器角色的成员以dbo用户身份输入每个数据库。检查sysadmin固定服务器角色成员的权限,检查dbo的权限,而不是原始登录。由于dbo无法添加到数据库角色且在Windows组中不存在,因此dbo将始终返回0(如果角色不存在,则返回NULL)。

答案 2 :(得分:2)

尝试明确指定主体。

SELECT IS_ROLEMEMBER('my_user', 'SqlLogin')

我测试了这个,它返回了1。

CREATE DATABASE TestDatabase;
GO

USE TestDatabase;
GO

CREATE ROLE TestRole AUTHORIZATION dbo;
GO

CREATE USER TestUser WITHOUT LOGIN;
GO

EXEC sp_addrolemember 'TestRole', 'TestUser';
GO

SELECT IS_ROLEMEMBER('TestRole', 'TestUser');
GO