如果您使用以下方法获取某些视图的定义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 通过更改前景色将其识别为命令?
视图 sys.columns 是一个系统视图。这个视图是由master数据库中的sys用户提供给您的,该用户是一个没有登录的数据库用户。
sys 用户有自己的模式 sys,然后用于链接所有 sys.* 对象。
从 sys.* 对象中进行选择的权限是通过公共 SQL Server 角色的成员身份授予您的。SQL Server 角色 public 对所有 sys.* 架构对象具有 SELECT 权限。
这就是您被授予权限的方式select * from sys.columns
。
如果您不是公共服务器角色的成员,则您无权访问任何 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 函数的权限,该函数是结果集中列的定义。它已经被隐藏起来,不被你窥探。
归档时间: |
|
查看次数: |
1197 次 |
最近记录: |