【问题标题】:Default value is GUID in SQL Server table column默认值为 SQL Server 表列中的 GUID
【发布时间】:2016-03-22 07:14:18
【问题描述】:

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

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

【问题讨论】:

  • 问题是什么???
  • 为什么 GIANGGUID 列的值为 00000000-0000-0000-0000-000000000000?
  • 大多数时候在 SQL Server 中使用 GUID 作为主键是一种不好的做法,请参阅此答案stackoverflow.com/questions/11938044/…
  • 我们需要确切知道如何插入包含 00000000-0000-0000-0000-000000000000 GUID 的行。无论您是在添加默认值之前还是之后插入它。从你的问题来看,这并不是很清楚。 (此外,如果您使用 GUID 作为主键,则需要小心;需要考虑很多变量,但 NEWSEQUENTIALID() 可能比 NEWID() 更好。甚至可能是简单的递增整数,如果你能管理的话。)
  • 你在使用 ORM 吗?如果有,是哪一个?无论如何,它看起来好像您的插入显式地插入了该值,因此默认值永远不会进入它。

标签: sql-server guid


【解决方案1】:

这里发生了几件事。

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

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,并且 newid() 也会通过此 ALTER 添加:

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)。

样本数据:

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-0000000000000 并且接下来的行将无法插入,因为它重复了主键,问题是当我设置默认值或绑定是newid()或newsequentialid()时,主键的值为00000000-0000-0000-0000-000000000000。默认我的表没有主键
  • 如何插入新行?您的代码可能将其替换为 000000。
  • 我没有编辑代码的权限。我只是被允许在跟踪表中添加一列是 GUID
  • 用于插入新行的代码可能会添加0000。使用什么软件在表格中插入行?
  • 我添加了一个新字段是GIANGGUID,它不依赖软件插入数据,因为它是由newid()或newsequentialid()自动生成的
【解决方案2】:

SQL server 中无法获取默认值,使用下面的转换值获取default guid

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

结果

00000000-0000-0000-0000-000000000000

【讨论】:

    【解决方案3】:

    我花了很长时间试图弄清楚这一点。看来您需要以下格式才能使派生列成为 GUID。 (DT_GUID) "{00000000-0000-0000-0000-000000000000}"

    【讨论】:

      【解决方案4】:

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

      大多数时候,在 SQL Server 中使用 GUID 作为主键是一种不好的做法。

      【讨论】:

      • "默认值仅适用于新插入的行。"我认为这取决于该列是否被声明为 NULLable。
      • 我不知道你真的可以说“大多数时候”这是不好的做法。每种都有优点和缺点,您可以通过谷歌搜索“guid 或 int 主键”找到很多博客文章。
      • 使用 SQL Server,如果您有一个 guid 作为主键并且该字段上的聚集索引(默认情况下,当您创建主键时)它将随着时间的推移导致性能问题
      猜你喜欢
      • 2014-08-18
      • 1970-01-01
      • 2015-08-04
      • 1970-01-01
      • 1970-01-01
      • 2014-10-24
      • 2012-03-25
      • 2018-12-31
      • 1970-01-01
      相关资源
      最近更新 更多