SQL Server查询public角色登录账号返回异常结果问题咨询
关于
IS_SRVROLEMEMBER检查public角色的问题 首先直接给结论:你看到的这个返回结果绝对不是正常行为,而且用public角色来检查服务器读取权限也不是恰当的方式。下面分两部分给你拆解:
一、为什么检查public角色会返回0?
SQL Server里的public服务器角色是个特殊角色——所有登录账号默认都会自动加入这个角色,而且你根本无法手动移除任何登录的public成员身份(就算你在界面上“取消勾选”,实际上系统也不会生效)。所以理论上,只要@login_name是一个存在的有效登录,SELECT IS_SRVROLEMEMBER ('public', @login_name)应该总是返回1才对。
你遇到返回0的情况,大概率是这几个原因之一:
- 登录名格式错误:如果是Windows域账号,必须传入完整的
域名\用户名格式(比如CORP\JohnDoe);SQL登录要确保拼写完全准确(虽然SQL Server默认不区分大小写,但某些严格配置下可能有影响)。 - 执行查询的权限不足:要查看其他登录的服务器角色成员信息,执行查询的账号需要拥有
VIEW DEFINITION服务器权限,或者属于sysadmin、securityadmin这类高权限角色。如果当前账号权限不够,查询会返回不准确的结果(甚至返回NULL)。 - 登录账号不存在:如果
@login_name对应的登录已经被删除,或者从来没有创建过,函数自然会返回0。
二、检查服务器读取权限的正确姿势
用public角色来判断读取权限完全不靠谱,因为public的默认权限非常有限(仅能访问少数系统视图的基础信息),而且所有登录都属于它,根本无法区分不同用户的权限差异。
根据你的需求,推荐这些更准确的方法:
- 检查服务器级元数据读取权限:比如要判断是否能查看所有数据库列表,可以用
HAS_PERMS_BY_NAME函数:
返回1表示具备该权限,0表示没有。SELECT HAS_PERMS_BY_NAME(NULL, 'SERVER', 'VIEW ANY DATABASE') - 检查特定数据库的读取权限:如果是要判断能否读取某个数据库的数据,应该检查数据库级的角色(比如
db_datareader)或者直接的SELECT权限:-- 检查是否属于db_datareader角色 SELECT IS_ROLEMEMBER('db_datareader', @login_name, 'YourDatabaseName') -- 或者直接检查SELECT权限 SELECT HAS_PERMS_BY_NAME('YourDatabaseName', 'DATABASE', 'SELECT') - 验证实际操作权限:最直接的方式是尝试执行目标读取操作(比如
SELECT * FROM YourDatabase.dbo.YourTable),通过是否报错来判断权限——这种方式最准确,因为权限可能来自角色、直接授权甚至隐含权限(比如sysadmin的所有权限)。
内容的提问来源于stack exchange,提问作者user3750325
相关产品推荐
相关产品推荐

