Sql-Server

意外的唯一約束違規

  • January 15, 2018

給定以下 CREATE TABLE 語句:

CREATE TABLE [dbo].[Unit]
(
   [id]                SMALLINT       NOT NULL IDENTITY(1,1),
   [name]              VARCHAR(100)   NOT NULL,

   CONSTRAINT [PK_Unit] PRIMARY KEY CLUSTERED ([id]),
   CONSTRAINT [UQ_Unit_Name] UNIQUE ([name])
)

如何在不違反 UNIQUE 約束的情況下允許以下兩個字元串共存?

INSERT INTO dbo.Unit (Name) VALUES('e³m³/day') 
INSERT INTO dbo.Unit (Name) VALUES('e3m3/day') 

任何見解表示讚賞。

編輯

目前排序規則是Latin1_General_CI_AS

編輯

除非有人有更好的選擇,否則我可能不得不使用 Latin1_General_BIN 並在我需要的幾個地方手動處理 CI ……如果沒有提供更好的解決方案,將把它轉換為答案。

為什麼不將該列排序為區分大小寫?我認為你不需要訴諸二進制。這似乎工作正常,只需注意它可能會影響排序、比較、聯合等:

CREATE TABLE [dbo].[Unit]
(
   [id]                SMALLINT       NOT NULL IDENTITY(1,1),
   [name]              VARCHAR(100)   COLLATE Latin1_General_CS_AS NOT NULL ,

   CONSTRAINT [PK_Unit] PRIMARY KEY CLUSTERED ([id]),
   CONSTRAINT [UQ_Unit_Name] UNIQUE ([name])
);
GO

INSERT INTO dbo.Unit (Name) VALUES('e³m³/day') 
INSERT INTO dbo.Unit (Name) VALUES('e3m3/day') 

結果:

1 row(s) affected.
1 row(s) affected.

現在,這適用於您問題中的範例,但是很難說它是否適用於您的整個需求集。您可能有與您不同但在區分大小寫方面沒有區別對待的字元,例如:

INSERT INTO dbo.Unit (Name) VALUES('ß')
INSERT INTO dbo.Unit (Name) VALUES('ss')

結果:

1 row(s) affected.

然後:

消息 2627,級別 14,狀態 1,第 2 行

違反 UNIQUE KEY 約束“UQ_Unit_Name”。無法在對象“dbo.Unit”中插入重複鍵。重複鍵值為 (ss)。

該語句已終止。

在這種情況下,您可能最終需要使用二進製文件。

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