Answers:
ROWGUIDCOL
主要用于MERGE复制,也是必需的FILESTREAM
,但可用于任何您希望不可变列与主键分开的情况(例如,在主键值可以更改的情况下,但您仍然希望能够知道更改前后是哪一行)。
USE tempdb;
GO
CREATE TABLE dbo.example
(
name sysname PRIMARY KEY,
rowguid uniqueidentifier NOT NULL DEFAULT NEWID() ROWGUIDCOL
);
INSERT dbo.example(name) VALUES(N'bob'),(N'frank');
SELECT * FROM dbo.example;
UPDATE dbo.example SET name = N'pat' WHERE name = N'bob';
UPDATE dbo.example SET name = N'bob' WHERE name = N'frank';
SELECT * FROM dbo.example;
DROP TABLE dbo.example;
现在,如果复制,您的应用程序或您关注的是什么,它将注意到:
将列标记为,以ROWGUIDCOL
允许$ROWGUID
在查询中引用该列。这使查询更加通用,因为您无需在每个表中查找“唯一”列的含义(这对于@Aaron和@Martin分别指出的Replication和FileStream等功能非常有用。 )。您可以在应用程序层甚至是动态SQL中构造一个查询,该查询可以执行类似的操作SELECT $ROWGUID AS [ID] FROM {table_name}
并简单地遍历表列表。
只要记住该ROWGUIDCOL
名称并没有强制唯一性。您仍然需要通过主键,唯一索引或唯一约束来强制执行该操作。此选项也不强制列是不可变的。为此,您将需要对该AFTER UPDATE
列具有触发器或列级权限DENY UPDATE
。
例如:
SET NOCOUNT ON;
CREATE TABLE #RowGuidColTest
(
ID UNIQUEIDENTIFIER NOT NULL DEFAULT (NEWID()) ROWGUIDCOL,
SomeValue INT
);
INSERT INTO #RowGuidColTest (SomeValue) VALUES (12), (14), (1231);
DECLARE @Search UNIQUEIDENTIFIER;
SELECT TOP (1) @Search = $ROWGUID
FROM #RowGuidColTest;
SELECT @Search AS [@Search]
SELECT *, $ROWGUID AS [$ROWGUID]
FROM #RowGuidColTest;
SELECT *
FROM #RowGuidColTest
WHERE $ROWGUID = @Search;
-- No enforced uniqueness without a PK, Unique Index, or Unique Constraint.
UPDATE tmp
SET $ROWGUID = @Search
FROM #RowGuidColTest tmp
SELECT *
FROM #RowGuidColTest
WHERE $ROWGUID = @Search;
返回类似于以下内容的内容:
@Search
E7166D18-5003-4D20-8983-E2402472CF82
ID SomeValue $ROWGUID
E7166D18-5003-4D20-8983-E2402472CF82 12 E7166D18-5003-4D20-8983-E2402472CF82
44FD48A4-AF38-41BF-AE4E-8A12D26B5B57 14 44FD48A4-AF38-41BF-AE4E-8A12D26B5B57
2D50C5C7-1E43-4ADA-A03B-ED202FC88D20 1231 2D50C5C7-1E43-4ADA-A03B-ED202FC88D20
ID SomeValue
E7166D18-5003-4D20-8983-E2402472CF82 12
ID SomeValue
E7166D18-5003-4D20-8983-E2402472CF82 12
E7166D18-5003-4D20-8983-E2402472CF82 14
E7166D18-5003-4D20-8983-E2402472CF82 1231
同样,可以将其$IDENTITY
用于具有IDENTITY
列的表。