AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 291400
Accepted
Evan Carroll
Evan Carroll
Asked: 2021-05-12 14:20:58 +0800 CST2021-05-12 14:20:58 +0800 CST 2021-05-12 14:20:58 +0800 CST

SQL Server 的 is_nullable 有什么意义吗?

  • 772

SQL Server 有一个类型标志,称为is_nullable您可以在sys.types. 目前,(SQL Server 2019)它只设置为FALSE两种类型,sys.timestamp和sys.sysname. 对sys.timestamp这种类型似乎接受null。在sys.sysname它没有。这种行为有什么解释吗?

你可以看到这些类型

SELECT * FROM sys.types WHERE is_nullable = 0;  
SELECT TYPEPROPERTY('timestamp', 'AllowsNull');  -- returns 0

你可以像这样使用它,

CREATE TABLE foo ( a sys.timestamp );
INSERT INTO foo (a) VALUES ( null );

请注意,如果您使用,这将不起作用sys.sysname

Msg 515 Level 16 State 2 Line 1
Cannot insert the value NULL into column 'a', table 'dbo.foo'; column does not allow nulls. INSERT fails.
Msg 3621 Level 0 State 0 Line 1
The statement has been terminated.

如果您创建用户定义的数据类型,它也将不起作用,NOT NULL

CREATE TYPE bar FROM int NOT NULL;

这只是对用户的提示吗?

sql-server datatypes
  • 2 2 个回答
  • 208 Views

2 个回答

  • Voted
  1. Paul White
    2021-05-12T17:38:19+08:002021-05-12T17:38:19+08:00

    你的问题的答案是肯定的。

    该列指定数据类型的默认可空性,如果用户不表达偏好,例如在具有显式或规范的CREATE TABLE语句中,这可能很重要。可悲的是,该信息仅存在于旧兼容性视图的文档中:NULLNOT NULLsys.systypes

    允许空值(位)

    指示此数据类型的默认可空性。如果使用CREATE TABLE或指定可空性,则此默认值将被覆盖ALTER TABLE。|

    例如,可以覆盖该类型的默认NOT NULL行为sysname:

    DECLARE @T table (s sysname NULL);
    INSERT @T (s) VALUES (NULL);
    SELECT s FROM @T AS T;
    
    s
    无效的

    timestamp类型(首选名称rowversion)由于其用于检测行更改而具有额外的特殊行为。有关更多详细信息,请参见其他答案。您仍然可以以相同的方式覆盖其可空性,但实际上无法为时间戳/行版本属性存储 NULL。

    有几个复杂的层来确定属性可空性。我不在这里重复一些细节,而是向您推荐为什么您应该始终指定列是否接受Phil 因子的空值以获取背景信息和其他阅读材料。

    • 7
  2. Best Answer
    Tibor Karaszi
    2021-05-13T01:13:05+08:002021-05-13T01:13:05+08:00

    让我重新表述这个问题,以确保我们在同一页面上:

    时间戳类型的元数据表示它不接受 NULL,但如果您创建表时未指定可空性,则可以在 INSERT 上为该列指定 NULL。为什么?

    如果您从表中选择,您将看到在 INSERT 之后该值不为空。您拥有生成的“时间戳”(或 rowversion,如果您更喜欢该名称)。即,INSERT 上的 NULL 是没有意义的,这意味着使用了“默认”(可以这么说)。

    可以讨论一下时间戳类型的元数据属性是否应该反映我们是否可以在 INSERT 上指定 null,或者我们最终是否可以在该列中实际具有NULL。

    我想,当 Sybase 几十年前设计系统表时,我们必须在场才能知道答案。我不是。:-)

    因此,简而言之:时间戳类型的列不允许在表中为空,并且基于此可以争辩说元数据是正确的。

    (顺便说一句,我首先虽然这是一个向后兼容的东西,所以我启动了 6.5 版本的 SQL Server 进行测试。我几乎也启动了 4.2 版本。但后来我做了一个 SELECT 并没有直到那时我注意到该值根本不是 NULL。)

    这是我使用的 T-SQL(2019 年),FWIW:

    USE tempdb
    
    DROP TABLE IF EXISTS myTable;
    DROP TYPE IF EXISTS myTypeYesNull;
    DROP TYPE IF EXISTS myTypeNoNull;
    
    CREATE TYPE myTypeYesNull FROM int NULL;
    CREATE TYPE myTypeNoNull FROM int NOT NULL;
    GO
    
    CREATE TABLE myTable (yesNull myTypeYesNull, noNull myTypeNoNull, ts timestamp, sname sysname);
    GO
    
    SELECT name, is_nullable FROM sys.types WHERE name IN ('myTypeYesNull', 'myTypeNoNull', 'timestamp', 'sysname')
    
    SELECT 
     COLUMNPROPERTY(OBJECT_ID('myTable'), 'yesNull', 'AllowsNull') AS yesNull
    ,COLUMNPROPERTY(OBJECT_ID('myTable'), 'noNull', 'AllowsNull') AS noNull
    ,COLUMNPROPERTY(OBJECT_ID('myTable'), 'ts', 'AllowsNull') AS ts
    ,COLUMNPROPERTY(OBJECT_ID('myTable'), 'sname', 'AllowsNull') AS sname;
    
    --The ts column accepts NULL even though table meta-data states differently
    INSERT INTO myTable (yesNull, noNull, ts, sname)
    VALUES(NULL, 1, NULL, 'x')
    
    SELECT * FROM myTable
    
    ----------------------------------------------------------------------
    
    --Code executable on really old versions
    DROP TABLE myTable 
    GO
    SELECT name, allownulls FROM systypes WHERE name = 'sysname'
    CREATE TABLE myTable(ts timestamp NULL)
    GO
    
    --Doesn't fail on 6.5
    INSERT INTO myTable(ts) VALUES(null)
    SELECT * FROM myTable
    
    • 5

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve