我需要向一个已经存在的表中添加一个列,并将其设置为主键。我使用其他软件添加新数据。为什么列GIANGGUID
的值为00000000-0000-0000-0000-000000000000
?
ALTER TABLE dbo.Test
ADD [GIANGGUID] UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY;
我需要向一个已经存在的表中添加一个列,并将其设置为主键。我使用其他软件添加新数据。为什么列GIANGGUID
的值为00000000-0000-0000-0000-000000000000
?
ALTER TABLE dbo.Test
ADD [GIANGGUID] UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY;
这里正在发生几件事情。
如果你使用以下查询仅添加一个带默认值的列:
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;
除非有未提及的原因导致其这样做或转换它,否则没有理由最终以 00000000-0000-0000-0000-000000000000
结束。
现在,如果我们把这个问题放在一边,您不应该考虑使用 UNIQUEIDENTIFIER 作为主键。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,并且不会尝试自动插入任何内容。
在SQL Server中无法获取默认值,使用以下转换值来获取默认GUID
select CAST( cast(0 as binary) as uniqueidentifier)
Result
00000000-0000-0000-0000-000000000000
NEWSEQUENTIALID()
可能比NEWID()
更好。如果可以管理,最好还是使用简单的递增整数。) - Matt Gibson