HAS_PERMS_BY_NAME (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例

评估当前用户对安全对象的有效权限。 相关函数为 fn_my_permissions

Transact-SQL 语法约定

语法

HAS_PERMS_BY_NAME ( securable , securable_class , permission    
    [ , sub-securable ] [ , sub-securable_class ] )  

注意

若要查看 SQL Server 2014 (12.x) 及更早版本的 Transact-SQL 语法,请参阅早期版本文档

参数

securable
安全对象的名称。 如果安全对象是服务器本身,则此值应设置为 NULL。 securable 是 sysname 类型的标量表达式。 没有默认值。

securable_class
测试权限的安全对象的类名。 securable_class 是 nvarchar(60) 类型的标量表达式

在 Azure SQL 数据库 中,securable_class 参数必须设置为以下值之一:DATABASE、OBJECT、ROLE、SCHEMA 或 USER

permission
类型为 sysname 的非空标量表达式,表示要检查的权限名称。 没有默认值。 权限名称 ANY 是通配符。

sub-securable
类型为 sysname 的可选标量表达式,表示测试权限的安全对象子实体的名称。 默认值为 NULL。

注意

子安全对象不能使用 '[sub name]' 形式的括号。 请改用 'sub name'

sub-securable_class
类型为 nvarchar(60) 的可选标量表达式,表示测试权限的安全对象子实体的类。 默认值为 NULL。

在 Azure SQL 数据库 中,只有在 securable_class 参数设置为 OBJECT 时 sub-securable_class 参数才有效。 如果 securable_class 参数设置为 OBJECT,则 sub-securable_class 参数必须设置为 COLUMN

返回类型

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 权限吗?

适用于:SQL Server 2008 (10.0.x) 及更高版本

SELECT HAS_PERMS_BY_NAME(null, null, 'VIEW SERVER STATE');  

B. 我可以 IMPERSONATE 服务器主体 Ps 吗?

适用于:SQL Server 2008 (10.0.x) 及更高版本

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 中创建过程和表吗?

以下示例需要在 ALTER 中具有 S 权限,在数据库中具有 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. 我对 AdventureWorks2022 中的 SalesPerson 表有 INSERT 权限吗?

以下示例假定 AdventureWorks2022 为我的当前数据库上下文,并使用由两部分组成的名称。

SELECT HAS_PERMS_BY_NAME('Sales.SalesPerson', 'OBJECT', 'INSERT');  

以下示例对我的当前数据库上下文未做任何假定,并使用由三部分组成的名称。

SELECT HAS_PERMS_BY_NAME('AdventureWorks2022.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');  

另请参阅

权限(数据库引擎)
安全对象
权限层次结构(数据库引擎)
sys.fn_builtin_permissions (Transact-SQL)
安全性目录视图 (Transact-SQL)