Enr*_*eta 5 sql-server system-tables
我正在编写一个将映射到 C# 类的查询,并且在获取查询列的类型时,导致sys.columns中的某些列可以为 NULL
在同一个 sys.columns 中,还有其他非空的
注意:这些列有点
我认为它们应该总是 NOT NULL,因为 SQL Server 必须知道列的属性。
那么,为什么有些/那些列sys.columns可以NULL和/或在哪些情况下它们会是?
你是对的,结果永远不可能NULL。从快速调查中,看看sys.columns. 如果我运行:
SELECT OBJECT_DEFINITION(OBJECT_ID(N'sys.columns'));
Run Code Online (Sandbox Code Playgroud)
我看到这个:
...
sysconv(bit, 1 - (c.status & 1)) AS is_nullable, -- CPM_NOTNULL
...
FROM sys.syscolpars c
...
Run Code Online (Sandbox Code Playgroud)
如果我更改为 DAC 连接,则可以查看此处的列:
SELECT name, is_nullable
FROM sys.all_columns
WHERE [object_id] = OBJECT_ID(N'sys.syscolpars')
AND name = N'status';
Run Code Online (Sandbox Code Playgroud)
结果:
name is_nullable
------ -----------
status 0
Run Code Online (Sandbox Code Playgroud)
所以源绝对不能为空,对吗?但是,如果您对 执行相同操作sys.columns,则涉及周围表达式的列将c.status被标记为is_nullable = 1。这更多地反映了所涉及的表达式/数据类型,而不是NULL值的实际可能性。
我最初认为可能SYSCONV()做了一些与CONVERT()(我们不能使用前者来检查,但我认为它可能在内部工作更像TRY_CONVERT())不同的东西。事实并非如此,事实上,即使没有任何内部知识,也很容易重现:
CREATE TABLE dbo.foo(bit_column bit NOT NULL);
GO
CREATE VIEW dbo.bar
AS -- nullable?
SELECT bit_col1 = CONVERT(bit, 1 - (bit_column & 1)), -- YES
bit_col2 = bit_column & 1, -- no convert -- NO
bit_col3 = 1 - bit_column & 1 -- YES
FROM dbo.foo;
GO
SELECT name, is_nullable
FROM sys.dm_exec_describe_first_result_set
(N'SELECT * FROM dbo.bar', NULL, 1);
GO
DROP TABLE dbo.foo;
DROP VIEW dbo.bar;
Run Code Online (Sandbox Code Playgroud)
结果:
name is_nullable
-------- -----------
bit_col1 1
bit_col2 0
bit_col3 1
Run Code Online (Sandbox Code Playgroud)
说了这么多,不知道该给你什么建议。你可以有条件地硬编码这个特定的列是不可为空的,不管元数据是什么,或者你可以安全地使用它并使用元数据告诉你的东西(这将在未来基础定义发生变化的情况下证明你版本)。
| 归档时间: |
|
| 查看次数: |
1089 次 |
| 最近记录: |