有没有办法使用 sysconv() 内置函数?

McN*_*ets 5 sql-server t-sql

如果您使用以下方法获取某些视图的定义sys.sp_helptext

exec sys.sp_helptext 'sys.columns'

CREATE VIEW sys.columns
AS
  SELECT c.id                                                             AS object_id,
         c.NAME,
         c.colid                                                          AS column_id,
         c.xtype                                                          AS system_type_id,
         c.utype                                                          AS user_type_id,
         c.length                                                         AS max_length,
         c.prec                                                           AS PRECISION,
         c.scale,
         CONVERT(SYSNAME, CollationPropertyFromId(c.collationid, 'name')) AS collation_name,
         sysconv(bit, 1 - ( c.status & 1 ))                               AS is_nullable,-- CPM_NOTNULL  
         sysconv(bit, c.status & 2)                                       AS is_ansi_padded,-- CPM_NOTRIM  
         sysconv(bit, c.status & 8)                                       AS is_rowguidcol,-- CPM_ROWGUIDCOL  
         sysconv(bit, c.status & 4)                                       AS is_identity,-- CPM_IDENTCOL  
         sysconv(bit, c.status & 16)                                      AS is_computed,-- CPM_COMPUTED  
         sysconv(bit, c.status & 32)                                      AS is_filestream,-- CPM_FILESTREAM  
         sysconv(bit, c.status & 0x020000)                                AS is_replicated,-- CPM_REPLICAT  
         sysconv(bit, c.status & 0x040000)                                AS is_non_sql_subscribed,-- CPM_NONSQSSUB  
         sysconv(bit, c.status & 0x080000)                                AS is_merge_published,-- CPM_MERGEREPL  
         sysconv(bit, c.status & 0x100000)                                AS is_dts_replicated,-- CPM_REPLDTS  
         sysconv(bit, c.status & 2048)                                    AS is_xml_document,-- CPM_XML_DOC   
         c.xmlns                                                          AS xml_collection_id,
         c.dflt                                                           AS default_object_id,
         c.chk                                                            AS rule_object_id,
         sysconv(bit, c.status & 0x1000000)                               AS is_sparse,-- CPM_SPARSE  
         sysconv(bit, c.status & 0x2000000)                               AS is_column_set -- CPM_SPARSECOLUMNSET  
  FROM   sys.syscolpars c
  WHERE  number = 0
         AND has_access('CO', c.id) = 1 
Run Code Online (Sandbox Code Playgroud)

有一个函数叫做sysconv.

这些视图使用函数“sysconv”,您可以从此视图中选择值,而不会收到任何错误消息。

select * from sys.columns;
Run Code Online (Sandbox Code Playgroud)

但如果我尝试类似的事情:

select sysconv(bit, 375 & 8);
Run Code Online (Sandbox Code Playgroud)

我收到错误:

sysconv 不是可识别的内置函数名称

正如 Martin Smith 指出的,这个函数可以替换为convert (bit, 375 & 8),但我想知道为什么我可以从此视图中选择值,并且不能在查询中使用它,即使 SSMS 通过更改前景色将其识别为命令?

Joh*_* N. 2

视图 sys.columns 是一个系统视图。这个视图是由master数据库中的sys用户提供给您的,该用户是一个没有登录的数据库用户。

sys 用户有自己的模式 sys,然后用于链接所有 sys.* 对象。

从 sys.* 对象中进行选择的权限是通过公共 SQL Server 角色的成员身份授予您的。SQL Server 角色 public 对所有 sys.* 架构对象具有 SELECT 权限。

这就是您被授予权限的方式select * from sys.columns

如果您不是公共服务器角色的成员,则您无权访问任何 sys.* 对象。

sys 用户(脚本)

USE [master]
GO

/****** Object:  User [sys]    Script Date: 16.12.2016 15:57:08 ******/
CREATE USER [sys]
GO
Run Code Online (Sandbox Code Playgroud)

系统架构(脚本)

USE [master]
GO

/****** Object:  Schema [sys]    Script Date: 16.12.2016 15:57:35 ******/
CREATE SCHEMA [sys]
GO
Run Code Online (Sandbox Code Playgroud)

公共服务器角色(脚本)

USE [master]
GO

/****** Object:  ServerRole [public]    Script Date: 16.12.2016 16:05:05 ******/
CREATE SERVER ROLE [public]
GO
Run Code Online (Sandbox Code Playgroud)

公共数据库角色

还有一个public数据库角色,它以某种方式链接到服务器角色。如果您在 master 数据库中查询sys.database_principals(视图),那么您将看到有一个public与服务器角色具有相同 id 的主体public,即 0。我假设这是 database_role public 和 server_role 之间缺少的链接民众。

编辑:添加了一些有关数据库角色“public”的信息

公共角色包含在每个数据库中,其中包括系统数据库。无法删除它,也无法向其中添加或删除用户。授予公共角色的权限将被所有其他用户和角色继承,因为它们默认属于公共角色。仅授予 public 您希望所有用户都拥有的权限。

引用SQL Server 中的服务器和数据库角色,部分:“公共角色”

如果您检索主数据库中数据库角色的权限,public您将获得以下列表:

询问:

SELECT 
   OBJECT_NAME(dp.major_id) AS OBJECT , 
   USER_NAME(dp.grantee_principal_id) AS grantee, 
   USER_NAME(dp.grantor_principal_id) AS grantor, 
  dp.permission_name
FROM sys.database_permissions AS dp 
WHERE dp.grantee_principal_id = 0
Run Code Online (Sandbox Code Playgroud)

结果:

sp_MSalreadyhavegeneration  public dbo EXECUTE
sp_MSwritemergeperfcounter  public dbo EXECUTE
TABLE_PRIVILEGES            public dbo SELECT
sp_replsetsyncstatus        public dbo EXECUTE
sp_replshowcmds             public dbo EXECUTE
sp_publishdb                public dbo EXECUTE
dm_pdw_nodes_os_tasks       public dbo SELECT
...
[truncated]
Run Code Online (Sandbox Code Playgroud)

回到 sys.colums 视图的示例:您已被授予从视图中进行 SELECT 的权限,但您没有实际直接执行 sysconv 函数的权限,该函数是结果集中列的定义。它已经被隐藏起来,不被你窥探。