NULL记录SQL Server的奇怪主键问题

Posted

技术标签:

【中文标题】NULL记录SQL Server的奇怪主键问题【英文标题】:Strange Primary key issue with NULL record SQL Server 【发布时间】:2017-11-27 23:26:11 【问题描述】:

我有一个 SQL Server 2016 数据库,我在其中发现了一个奇怪的问题,或者我可能遗漏了一些东西。

在 varchar 列上具有主键 NOT NULL 的表中,如果我输入值为 N'' 的 INSERT,则允许一次 NULL 值。如果我立即对该列使用 NULL,则会引发错误,无法插入 NULL。

N'' 是否被认为是主键列的一些有效字符?

这里是重现问题的 TSQL。

CREATE TABLE [dbo].[testprmarykeynull]( 
[EmailId] [varchar](20) NOT NULL PRIMARY KEY CLUSTERED
( 
[EmailId] ASC 
)
)


INSERT INTO testprmarykeynull VALUES('test@gmail.com');
INSERT INTO testprmarykeynull VALUES(N''); - Successfully insert this for the first time and the second time throws duplicate error. But from my understanding this should fail the first time itself since it's a NULL value. 
INSERT INTO testprmarykeynull VALUES(NULL); - Fails though even if I try with the first NULL

【问题讨论】:

【参考方案1】:

MS SQL Server 中的空字符串不是null(与oracle 不同,例如) - 请参阅此SQLFiddle 以获得演示。

因此,它的行为与任何其他值一样 - 您插入到主键列中的第一个值会很好,而第二个值将失败,因为它违反了列的唯一性。

【讨论】:

second one 你指的是NULL 对吧?那么它应该违反主键非空约束 @Squirrel no - 我的意思是您第二次尝试插入空字符串 ('')。当你第一次成功时,如果你尝试再次插入一个空字符串,你将失败,因为它违反了唯一性。【参考方案2】:

NULLN'' 在 SQL Server 中绝对不一样 - 它们从来没有,也永远不会。

N'' 是一个长度为 0 的 NVARCHAR 值。NULL 是“缺少值”。

有很多方法可以使这种差异变得清晰。 例子:

SELECT LEN(N'')      -- returns 0
     , LEN(NULL)     -- returns NULL because almost any operation on NULL returns NULL

     , ISNULL(N'' , N'Hello')   -- returns N'' because N'' is a value
     , ISNULL(NULL, N'Hello')   -- returns N'Hello' because NULL is "not a value"

【讨论】:

以上是关于NULL记录SQL Server的奇怪主键问题的主要内容,如果未能解决你的问题,请参考以下文章

sqlserver外键关系有啥用?

sqlserver2008 啥是唯一键? 怎样设置唯一键

请问SQL server 中的主键和外键的作用

由于截断/删除导致 SQL Server 主键冲突?

如何使MongoDB的列成为SQL Server中发生的主键,避免重复记录?

SQL Server:主键与外键设置与相关理解