问题 SQL Server表列中的默认值为GUID


我需要在已存在的表中添加一列,并将其设置为主键。我使用其他软件添加新数据。为什么列 GIANGGUID 有价值 00000000-0000-0000-0000-000000000000 ?

ALTER TABLE dbo.Test 
   ADD [GIANGGUID] UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY;

4577
2017-12-16 08:30


起源

问题是什么? - Julien Vavasseur
为什么列GIANGGUID的值为00000000-0000-0000-0000-000000000000? - Giang Nguyen
大多数时候使用GUID作为SQL Server中的主键是一个不好的实践,请参阅此答案 stackoverflow.com/questions/11938044/... - Thomas
我们需要确切地知道如何插入包含00000000-0000-0000-0000-000000000000 GUID的行。无论您是在添加默认值之前还是之后插入的。你的问题并不是很清楚。 (另外,如果你使用GUID作为主键,你需要小心;需要考虑很多变量,但是 NEWSEQUENTIALID() 可能是比较好的选择 NEWID()。如果你可以管理它,那么更好的可能是一个简单的递增整数。) - Matt Gibson
你在使用ORM吗?如果是这样的话?它看起来好像你的插入显式插入该值,所以默认情况下永远不会进入它。 - Martin Smith


答案:


这里发生了一些事情。

如果您只是使用此查询添加具有默认值的列:

ALTER TABLE #Test ADD [GIANGGUID] uniqueidentifier DEFAULT NEWID();

您将获得现有列的NULL值,因为允许NULL并且newid()用于新插入的行:

id  name    GIANGGUID
0   A       NULL
1   B       NULL
2   C       NULL

现在,如果添加一个带有NOT NULL的新列:

ALTER TABLE #Test ADD [GIANGGUID] uniqueidentifier NOT NULL DEFAULT NEWID();

由于列不能为NULL,因此使用DEFAULT约束并为每个现有行插入newid():

id  name    GIANGGUID
0   A       52C70279-B3A4-4DE6-A612-F1F32875743F
1   B       3005D9BE-5389-4870-BAA9-82E658552282
2   C       E50FDD26-A8FD-43BD-A8F0-3FDA83EFF5D9

添加主键时会发生同样的情况,因为PK不能为NULL,并且在此ALTER中也会添加newid():

ALTER TABLE #Test ADD [GIANGGUID] uniqueidentifier NOT NULL DEFAULT NEWID()-- PRIMARY KEY;
  • 使用您的查询,将为新行和现有行插入newid()。
  • 使用上面的其他查询,您将获得NULL或newid()。

没有理由忍受 00000000-0000-0000-0000-000000000000 除非没有提到的东西做或改变它。

现在,如果我们不考虑这个问题,你不应该考虑使用UNIQUEIDENTIFIER作为主键。 GUID是:

  • 不窄
  • 随机虽然可以使用顺序GUID。

如果由于某些原因需要随机且独特的内容(例如表中的GUID),则可以在没有PK的情况下保留此列,并在PK时添加额外的唯一和顺序ID列(bigint with identity)。

样本数据:

CREATE TABLE #Test(id int, name varchar(10));
INSERT INTO #Test(id, name) values
    (0, 'A')
    , (1, 'B')
    , (2, 'C');

编辑以解决软件插入问题... (看到 GUID 00000000-0000-0000-0000-000000000000导致合并索引违规

重命名表格:

EXEC sp_rename 'dbo.test', 'test_data'

添加新列:

ALTER TABLE dbo.Test_data ADD [GIANGGUID] UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY;

要么:

ALTER TABLE dbo.Test_data ADD [GIANGGUID] bigint identity(0, 1) PRIMARY KEY;

创建一个没有GIANGGUID的视图:

CREATE VIEW dbo.test AS
    SELECT col1, col2, ... FROM dbo.test_data

当软件进行插入时,它不会看到GIANGGUID,也不会尝试自动插入内容。


15
2017-12-16 09:08



我添加了一个列是GIANGGUID并为它设置了一个主键,但是当我添加几行数据时,第一行值为00000000-0000-0000-0000-000000000000并且下一行将无法插入,因为它重复了主键,问题是当我设置默认值或绑定是newid()或newsequentialid()时,主键的值是00000000-0000-0000-0000-000000000000。默认我的表没有主键 - Giang Nguyen
你如何插入新行?你的代码可能用000000替换它。 - Julien Vavasseur
我没有编辑代码的权限。我只是被允许添加一个列是GUID到跟踪表 - Giang Nguyen
用于插入新行的代码可能会添加0000.用什么软件在表中插入行? - Julien Vavasseur
我添加了一个新字段是GIANGGUID,它不依赖于软件来插入数据,因为它是由newid()或newsequentialid()自动生成的 - Giang Nguyen


在使用GUId作为主要内容之前,您应该看一下这篇文章:

大多数时候使用GUID作为SQL Server的主键是一个不好的实践。


0
2017-12-16 08:42



“默认值仅适用于新插入的行。”我认为这取决于列是否被声明为NULL。 - Matt Gibson
我编辑了我的帖子 - Thomas


我花了很长时间试图解决这个问题。您似乎需要以下格式才能将派生列作为GUID。 (DT_GUID)“{00000000-0000-0000-0000-000000000000}”


0
2018-03-09 16:35