SQL Server表列的默认值是GUID。

26

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

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

1
什么是问题? - Julien Vavasseur
为什么列GIANGGUID的值为00000000-0000-0000-0000-000000000000? - Giang Nguyen
2
大多数情况下,在 SQL Server 中使用 GUID 作为主键是一种不良实践,请参阅此答案 https://dev59.com/Xmct5IYBdhLWcg3wpO7H。 - Thomas
我们需要确切地知道您如何插入具有00000000-0000-0000-0000-000000000000 GUID的行,以及您是在添加默认值之前还是之后插入的。从您的问题中并不清楚。 (此外,如果您将GUID用作主键,则需要小心;有很多变量需要考虑,但NEWSEQUENTIALID()可能比NEWID()更好。如果可以管理,最好还是使用简单的递增整数。) - Matt Gibson
1
你使用ORM吗?如果是的话,使用的是哪一个?无论如何,看起来你的插入操作是显式地插入了该值,所以默认值不会生效。 - Martin Smith
显示剩余3条评论
3个回答

36

这里正在发生几件事情。

如果你使用以下查询仅添加一个带默认值的列:

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

当添加主键时,同样的情况也会发生,因为主键不允许为空,所以在 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,并添加一个额外的唯一和连续的ID列(具有标识)作为您的PK。

样例数据:

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

修改以绕过软件插入问题...(请参见GUID of 00000000-0000-0000-0000-000000000000 causing merge index violation

将该表重命名:

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,并且不会尝试自动插入任何内容。


我添加了一个名为GIANGGUID的列并为其设置了主键,但是当我添加几行数据时,第一行的值是00000000-0000-0000-0000-000000000000,而接下来的行将无法插入,因为它们重复了主键。问题在于当我设置默认值或绑定为newid()或newsequentialid()时,主键的值为00000000-0000-0000-0000-000000000000。默认情况下,我的表没有主键。 - Giang Nguyen
我没有编辑代码的权限,只被允许在追踪表中添加一个GUID列。 - Giang Nguyen
插入新行所使用的代码可能会添加 0000。您在表中插入行时使用的软件是什么? - Julien Vavasseur
我添加了一个新字段GIANGGUID,它不依赖于软件插入数据,因为它是由newid()或newsequentialid()自动生成的。 - Giang Nguyen
一个 bigint identy(0, 1) 对你来说是一个选项吗? - Julien Vavasseur
显示剩余6条评论

2

在SQL Server中无法获取默认值,使用以下转换值来获取默认GUID

select CAST( cast(0 as binary) as uniqueidentifier)

Result

00000000-0000-0000-0000-000000000000

0
我花了很长时间来试图弄清楚这个问题。看起来,你需要使用以下格式才能使派生列成为 GUID。(DT_GUID) "{00000000-0000-0000-0000-000000000000}"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接