Sql-Server

SQL(在我的例子中是 SQL Server)如何評估多列上的唯一約束?

  • June 11, 2022

給定下表

CREATE TABLE example (
   id int NOT NULL IDENTITY(1,1),
   strA NVARCHAR(10) NULL,
   strB NVARCHAR(10) NULL,
 CONSTRAINT [pk_id] PRIMARY KEY (id)
 CONSTRAINT [unq_str_combo] UNIQUE (strA, strB)
 CONSTRAINT [chk_one_is_null] CHECK ((strA IS NULL AND strB IS NOT NULL) OR (strA IS NOT NULL AND strB IS NULL))
);

SQL 如何確定 strA 和 strB 列中的值組合是否是唯一組合?

INSERT以下任何陳述是否應失敗?

INSERT INTO dbo.example (strA, strB) VALUES ('abc', NULL);    -- A
INSERT INTO dbo.example (strA, strB) VALUES (NULL, 'def');    -- B
INSERT INTO dbo.example (strA, strB) VALUES (NULL, 'abc');    -- C
INSERT INTO dbo.example (strA, strB) VALUES ('def', NULL);    -- D

在表創建(或 by )期間是否有辦法ALTER TABLE添加檢查或其他一些約束,以便INSERT語句 forCD失敗?

SQL 如何確定 strA 和 strB 列中的值組合是否是唯一組合?

這兩列分別進行比較。如果對於兩個不同的行,兩個strA值比較相等並且兩個strB值比較相等,則違反 ( strA , strB ) 的唯一性。

在 SQL Server 中,檢查唯一索引和約束時,NULL 比較等於另一個 NULL。這不是 SQL 標準規定的 NULL 行為,但它不會改變。

在表創建(或 by )期間是否有辦法ALTER TABLE添加檢查或其他一些約束,以便INSERT語句 forCD失敗?

這可以通過對計算列的唯一約束來完成:

CREATE TABLE example 
(
   id int NOT NULL IDENTITY(1,1),
   strA nvarchar(10) NULL,
   strB nvarchar(10) NULL,
   string AS COALESCE(strA, strB) 
       CONSTRAINT [unique strA strB] UNIQUE,

   CONSTRAINT [pk_id] PRIMARY KEY (id),
   CONSTRAINT [chk_one_is_null] CHECK (
       (strA IS NULL AND strB IS NOT NULL) 
       OR (strA IS NOT NULL AND strB IS NULL))
);

在互斥的 StrA 和 StrB 列上實現唯一約束的一種方法是在計算列上使用唯一索引。下面的範例使用此方法而不是您問題中的複合列唯一約束。

CREATE TABLE example (
   id int NOT NULL IDENTITY(1,1),
   strA NVARCHAR(10) NULL,
   strB NVARCHAR(10) NULL,
   str_combo AS COALESCE(strA,strB)
 CONSTRAINT [pk_id] PRIMARY KEY (id)
 ,CONSTRAINT [unq_str_combo] UNIQUE (str_combo)
 ,CONSTRAINT [chk_one_is_null] CHECK ((strA IS NULL AND strB IS NOT NULL) OR (strA IS NOT NULL AND strB IS NULL))
);

INSERT INTO dbo.example (strA, strB) VALUES ('abc', NULL);    -- A
INSERT INTO dbo.example (strA, strB) VALUES (NULL, 'def');    -- B
INSERT INTO dbo.example (strA, strB) VALUES (NULL, 'abc');    -- C
INSERT INTO dbo.example (strA, strB) VALUES ('def', NULL);    -- D

結果:

(1 row affected)

(1 row affected)
Msg 2627, Level 14, State 1, Line 14
Violation of UNIQUE KEY constraint 'unq_str_combo'. Cannot insert duplicate key in object 'dbo.example'. The duplicate key value is (abc).
The statement has been terminated.
Msg 2627, Level 14, State 1, Line 15
Violation of UNIQUE KEY constraint 'unq_str_combo'. Cannot insert duplicate key in object 'dbo.example'. The duplicate key value is (def).
The statement has been terminated.

引用自:https://dba.stackexchange.com/questions/313207