HAS_PERMS_BY_NAME (Transact-SQL)
评估当前用户对安全对象的有效权限。相关函数为 fn_my_permissions。
语法
HAS_PERMS_BY_NAME ( securable , securable_class , permission
[ , sub-securable ] [ , sub-securable_class ] )
参数
securable
安全对象的名称。如果安全对象是服务器本身,则此值应设置为 NULL。securable 是类型为 sysname 的标量表达式。没有默认值。securable_class
测试权限的安全对象的类名。securable_class 是类型为 nvarchar(60) 的标量表达式。permission
类型为 sysname 的非空标量表达式,表示要检查的权限名称。没有默认值。权限名称 ANY 是通配符。sub-securable
类型为 sysname 的可选标量表达式,表示测试权限的安全对象子实体的名称。默认值为 NULL。注意 在 SQL Server 直到 SQL Server 2008 Service Pack 2 的版本中,子安全对象不能使用 '[sub name]' 形式的括号。请改用 'sub name'。
sub-securable_class
类型为 nvarchar(60) 的可选标量表达式,表示测试权限的安全对象子实体的类。默认值为 NULL。
返回类型
int
如果查询失败,则返回 NULL。
注释
此内置函数将测试当前主体对于指定的安全对象是否具有特定的有效权限。如果用户具有针对安全对象的有效权限,HAS_PERMS_BY_NAME 返回 1;如果用户不具有针对安全对象的有效权限,返回 0;如果安全对象类或权限无效,返回 NULL。有效权限可以是下列任意一种:
直接授予主体并且不被拒绝的权限。
由主体持有的更高级权限暗含的、且不被拒绝的权限。
授予主体所属的角色或组的、且不被拒绝的权限。
由主体所属的角色或组持有的、且不被拒绝的权限。
权限评估始终在调用方的安全上下文中执行。若要确定某些其他用户是否具有有效权限,调用方必须对此用户具有 IMPERSONATE 权限。
对于架构级实体,可接受由一部分、两部分或三部分组成的非空名称。对于数据库级实体,只接受由一部分组成的名称,Null 表示“当前数据库”。对于服务器本身,则需要一个 Null(表示“当前服务器”)。此函数无法针对尚未创建服务器级主体的已链接服务器或 Windows 用户进行权限检查。
以下查询将返回内置安全对象类的列表:
SELECT class_desc FROM sys.fn_builtin_permissions(default)
使用以下排序规则:
当前数据库排序规则:包括架构未包含的安全对象的数据库级安全对象;由一部分或两部分组成的架构范围内的安全对象;使用由三部分组成的名称时的目标数据库。
master 数据库排序规则:服务器级安全对象。
列级别检查不支持“ANY”。必须指定合适的权限。
示例
A. 我具有服务器级 VIEW SERVER STATE 权限吗?
SELECT HAS_PERMS_BY_NAME(null, null, 'VIEW SERVER STATE');
B. 我可以 IMPERSONATE 服务器主体 Ps 吗?
SELECT HAS_PERMS_BY_NAME('Ps', 'LOGIN', 'IMPERSONATE');
C. 我在当前数据库中具有任何权限吗?
SELECT HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'ANY');
D. 数据库主体 Pd 在当前数据库中具有任何权限吗?
假定调用方对主体 Pd 有 IMPERSONATE 权限。
EXECUTE AS user = 'Pd'
GO
SELECT HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'ANY');
GO
REVERT;
GO
E. 我可以在架构 S 中创建过程和表吗?
以下示例需要在 S 中具有 ALTER 权限,在数据库中具有 CREATE PROCEDURE 权限,表的情况与此类似。
SELECT HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'CREATE PROCEDURE')
& HAS_PERMS_BY_NAME('S', 'SCHEMA', 'ALTER') AS _can_create_procs,
HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'CREATE TABLE') &
HAS_PERMS_BY_NAME('S', 'SCHEMA', 'ALTER') AS _can_create_tables;
F. 我对哪些表具有 SELECT 权限?
SELECT HAS_PERMS_BY_NAME
(QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + QUOTENAME(name),
'OBJECT', 'SELECT') AS have_select, * FROM sys.tables
G. 我对 AdventureWorks2008R2 中的 SalesPerson 表有 INSERT 权限吗?
以下示例假定 AdventureWorks2008R2 为我的当前数据库上下文,并使用由两部分组成的名称。
SELECT HAS_PERMS_BY_NAME('Sales.SalesPerson', 'OBJECT', 'INSERT');
以下示例对我的当前数据库上下文未做任何假定,并使用由三部分组成的名称。
SELECT HAS_PERMS_BY_NAME('AdventureWorks2008R2.Sales.SalesPerson',
'OBJECT', 'INSERT');
H. 我对 T 表的哪些列有 SELECT 权限?
SELECT name AS column_name,
HAS_PERMS_BY_NAME('T', 'OBJECT', 'SELECT', name, 'COLUMN')
AS can_select
FROM sys.columns AS c
WHERE c.object_id=object_id('T');