如果您使用以下方法获得某些视图的定义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
有一个函数叫sysconv
.
这些视图使用函数“sysconv”,您可以从此视图中选择值而不会收到任何错误消息。
select * from sys.columns;
但是如果我尝试类似的东西:
select sysconv(bit, 375 & 8);
我收到错误:
sysconv 不是可识别的内置函数名称
正如 Martin Smith 指出的那样,此功能可以替换为convert (bit, 375 & 8)
,但我想知道为什么我可以从此视图中选择值,但我不能在我的查询中使用它,即使 SSMS 通过更改前景颜色将其识别为命令?
视图 sys.columns 是一个系统视图。这个视图是由master数据库中的sys用户提供给你的,是一个没有登录的数据库用户。
sys 用户有自己的模式 sys,然后用于链接所有 sys.* 对象。
从 sys.* 对象中进行选择的权限是通过公共 SQL Server 角色的成员身份授予您的。SQL Server 角色 public 对所有 sys.* 架构对象具有 SELECT 权限。
这就是您被授予权限的方式
select * from sys.columns
。如果您不是公共服务器角色的成员,那么您无权访问任何 sys.* 对象。
系统用户(脚本)
系统架构(脚本)
公共服务器角色(脚本)
公共数据库角色
还有一个
public
数据库角色,它以某种方式链接到服务器角色。如果您查询sys.database_principals
master 数据库中的(视图),那么您会看到有一个public
与服务器角色具有相同 ID 的主体,public
即 0。我假设这是 database_role public 和 server_role 之间缺失的链接上市。编辑:添加了一些关于数据库角色“public”的信息
引用SQL Server 中的服务器和数据库角色,部分:“公共角色”
如果您
public
在 master 数据库中检索数据库角色的权限,您将获得以下清单:询问:
结果:
回到您使用 sys.colums 视图的示例:您已被授予从视图中选择的权限,但您无权直接实际执行 sysconv 函数,这是结果集中列的定义. 它已经从你窥探的眼睛隐藏。