ฉันจะสร้างข้อ จำกัด ที่ไม่ซ้ำที่อนุญาตให้เป็นโมฆะได้อย่างไร


620

ฉันต้องการมีข้อ จำกัด ที่ไม่ซ้ำกันในคอลัมน์ที่ฉันจะเติมด้วย GUID อย่างไรก็ตามข้อมูลของฉันมีค่า Null สำหรับคอลัมน์นี้ ฉันจะสร้างข้อ จำกัด ที่อนุญาตให้มีค่า Null หลายค่าได้อย่างไร

นี่คือสถานการณ์ตัวอย่างเช่น พิจารณาสคีมานี้:

CREATE TABLE People (
  Id INT CONSTRAINT PK_MyTable PRIMARY KEY IDENTITY,
  Name NVARCHAR(250) NOT NULL,
  LibraryCardId UNIQUEIDENTIFIER NULL,
  CONSTRAINT UQ_People_LibraryCardId UNIQUE (LibraryCardId)
)

จากนั้นดูรหัสนี้สำหรับสิ่งที่ฉันพยายามที่จะบรรลุ:

-- This works fine:
INSERT INTO People (Name, LibraryCardId) 
 VALUES ('John Doe', 'AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA');

-- This also works fine, obviously:
INSERT INTO People (Name, LibraryCardId) 
VALUES ('Marie Doe', 'BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB');

-- This would *correctly* fail:
--INSERT INTO People (Name, LibraryCardId) 
--VALUES ('John Doe the Second', 'AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA');

-- This works fine this one first time:
INSERT INTO People (Name, LibraryCardId) 
VALUES ('Richard Roe', NULL);

-- THE PROBLEM: This fails even though I'd like to be able to do this:
INSERT INTO People (Name, LibraryCardId) 
VALUES ('Marcus Roe', NULL);

คำสั่งสุดท้ายล้มเหลวพร้อมข้อความ:

การละเมิดข้อ จำกัด UNIQUE KEY 'UQ_People_LibraryCardId' ไม่สามารถแทรกคีย์ซ้ำในวัตถุ 'dbo.People'

ฉันจะเปลี่ยนสคีมาของฉันและ / หรือข้อ จำกัด ที่ไม่ซ้ำกันเพื่อให้สามารถใช้หลายNULLค่าได้อย่างไรในขณะที่ยังคงตรวจสอบความเป็นเอกลักษณ์ของข้อมูลจริง


เชื่อมต่อปัญหาเพื่อความเข้ากันได้มาตรฐานในการลงคะแนนสำหรับ: connect.microsoft.com/SQLServer/Feedback/Details/299229
Vadzim


ข้อ จำกัด ที่ไม่ซ้ำและอนุญาตให้มี NULL ? มันเป็นสามัญสำนึก เป็นไปไม่ได้
flik

13
@flik ไม่ควรอ้างถึง "สามัญสำนึก" ดีกว่า นั่นไม่ใช่เหตุผลที่ถูกต้อง โดยเฉพาะอย่างยิ่งเมื่อพิจารณาว่าnullไม่ใช่ค่า แต่ไม่มีค่า ต่อ SQL มาตรฐานที่ไม่ถือว่าเท่ากับnull nullเหตุใดจึงnullต้องมีการละเมิดที่ไม่ซ้ำกันหลายรายการ
Frédéric

คำตอบ:


144

SQL Server 2008 +

คุณสามารถสร้างดัชนีที่ไม่ซ้ำใครที่ยอมรับ NULL หลายอันพร้อมกับWHEREclause ดูคำตอบด้านล่าง

ก่อนที่จะ SQL Server 2008

คุณไม่สามารถสร้างข้อ จำกัด UNIQUE และอนุญาตให้ NULL ได้ คุณต้องตั้งค่าเริ่มต้นเป็น NEWID ()

อัพเดตค่าที่มีอยู่เป็น NEWID () โดยที่ NULL ก่อนสร้างข้อ จำกัด UNIQUE


2
และนี่จะเป็นการเพิ่มคุณค่าให้กับแถวที่มีอยู่ย้อนหลังถ้าอย่างนั้นนี่คือสิ่งที่ฉันต้องทำขอบคุณ?
สจวร์ต

1
คุณจะต้องเรียกใช้คำสั่ง UPDATE การตั้งค่าที่มีอยู่เพื่อ newid () ที่สนามที่มีอยู่เป็นโมฆะ
โฮเซลิโอ

54
หากคุณใช้ SQL Server 2008 หรือใหม่กว่าให้ดูคำตอบด้านล่างพร้อม upvotes มากกว่า 100 รายการ คุณสามารถเพิ่มส่วนคำสั่ง WHERE ในข้อ จำกัด เฉพาะของคุณ
Darren Griffith

1
ปัญหานี้พบมาก ADO.NET DataTables เช่นกัน ดังนั้นแม้ฉันสามารถอนุญาตให้มีค่าว่างในเขตข้อมูลสำรองโดยใช้วิธีนี้ DataTable จะไม่ให้ฉันเก็บ NULL ในคอลัมน์ที่ไม่ซ้ำกันในตอนแรก หากใครรู้วิธีแก้ปัญหาสำหรับสิ่งนั้นโปรดโพสต์ไว้ที่นี่
dotNET

6
พวกให้แน่ใจว่าคุณเลื่อนลงและอ่านคำตอบกับ 600 upvotes มันไม่ได้เป็นเพียงแค่กว่า 100
ส่องสว่าง

1288

สิ่งที่คุณกำลังมองหานั้นเป็นส่วนหนึ่งของมาตรฐาน ANSI SQL: 92, SQL: 1999 และ SQL: 2003 นั่นคือข้อ จำกัด UNIQUE ต้องไม่อนุญาตให้ทำซ้ำค่าที่ไม่ใช่ค่า NULL ซ้ำ แต่ยอมรับค่า NULL หลายค่า

ในโลก Microsoft ของ SQL Server อย่างไรก็ตาม NULL เดียวได้รับอนุญาต แต่ NULL หลายรายการไม่ได้ ...

ในSQL Server 2008คุณสามารถกำหนดดัชนีกรองที่ไม่ซ้ำกันโดยขึ้นอยู่กับเพรดิเคตที่แยกค่า NULLs:

CREATE UNIQUE NONCLUSTERED INDEX idx_yourcolumn_notnull
ON YourTable(yourcolumn)
WHERE yourcolumn IS NOT NULL;

ในเวอร์ชันก่อนหน้านี้คุณสามารถใช้ VIEWS โดยใช้คำสั่ง NOT NULL เพื่อบังคับใช้ข้อ จำกัด


3
นี่อาจเป็นวิธีที่ดีที่สุดในการทำเช่นนี้ ไม่แน่ใจว่ามีผลกระทบต่อการทำงานหรือไม่? ใคร?
Simon_Weaver

3
ฉันพยายามทำสิ่งนี้ใน SQL Server 2008 Express edition และฉันได้รับข้อผิดพลาดดังนี้สร้าง UNIQUE NONCLUSTERED INDEX UC_MailingId ON [SLS-CP] .dbo.MasterFileEntry (MailingId) ซึ่ง MailingId ไม่ได้เป็นผลลัพธ์ใน: ข่าวสารเกี่ยวกับ 156 ระดับ 15, สถานะ 1, บรรทัดที่ 3 ไม่ถูกต้องใกล้กับคำหลัก 'WHERE' ถ้าฉันลบส่วนคำสั่งที่ DDL ทำงานได้ดี แต่แน่นอนไม่ทำตามที่ฉันต้องการ ความคิดใด ๆ
Kenneth Baltrinic

4
คุณจะไม่สามารถสร้างคีย์ต่างประเทศเพื่อปิดดัชนีที่ไม่ซ้ำเช่นเดียวกับที่คุณสามารถปิดข้อ จำกัด ที่ไม่ซ้ำได้ (อย่างน้อย SSMS บ่นกับฉันตอนที่ฉันพยายาม) มันจะดีมากถ้ามีคอลัมน์ nullable ที่ไม่ซ้ำกันเสมอ (เมื่อไม่ใช่ null) เป็นแหล่งของความสัมพันธ์ Foreign Key
Vaccano

8
คำตอบที่ดีอย่างแท้จริง น่าเสียดายที่มันถูกซ่อนไว้โดยคนที่ยอมรับว่าเป็นคำตอบ โซลูชันนี้แทบไม่ได้รับความสนใจของฉัน แต่มันก็เหมือนกับงานมหัศจรรย์ในการใช้งานของฉันในตอนนี้
Coral Doe

2
อีกทางเลือกหนึ่งสำหรับ SQL 2005 และต่ำกว่าคือคอลัมน์คำนวณที่รู้จักกันในชื่อ "Nullbuster" stackoverflow.com/a/191729/132461มันช่วยคุณไม่ให้ยุ่งเหยิงฐานข้อมูลด้วยมุมมองอื่นคุณเพียงแค่มีคอลัมน์อื่นแทน - โดยปกติแล้วจะมีชื่อเป็นคอลัมน์ ใส่ดัชนีที่ไม่ซ้ำกัน (หรือข้อ จำกัด ในการแสดงเจตนาทางธุรกิจ) บน ColumnA-Nullbuster และจะบังคับใช้เอกลักษณ์ใน ColumnA
DanO

34

SQL Server 2008 และใหม่กว่า

เพียงกรองดัชนีที่ไม่ซ้ำกัน:

CREATE UNIQUE NONCLUSTERED INDEX UQ_Party_SamAccountName
ON dbo.Party(SamAccountName)
WHERE SamAccountName IS NOT NULL;

ในรุ่นที่ต่ำกว่ามุมมองที่เป็นรูปธรรมยังไม่จำเป็น

สำหรับ SQL Server 2005 และรุ่นก่อนหน้าคุณสามารถทำได้โดยไม่มีมุมมอง ฉันเพิ่งเพิ่มข้อ จำกัด ที่ไม่เหมือนใครเช่นที่คุณขอไปยังหนึ่งในตารางของฉัน เนื่องจากฉันต้องการเอกลักษณ์ในคอลัมน์SamAccountNameแต่ฉันต้องการอนุญาตให้ NULL หลายตัวฉันใช้คอลัมน์ materialized แทนมุมมอง materialized:

ALTER TABLE dbo.Party ADD SamAccountNameUnique
   AS (Coalesce(SamAccountName, Convert(varchar(11), PartyID)))
ALTER TABLE dbo.Party ADD CONSTRAINT UQ_Party_SamAccountName
   UNIQUE (SamAccountNameUnique)

คุณเพียงแค่ใส่บางอย่างในคอลัมน์ที่คำนวณแล้วซึ่งจะรับประกันว่าไม่ซ้ำกันทั่วทั้งตารางเมื่อคอลัมน์ที่ไม่ซ้ำกันที่ต้องการจริงเป็น NULL ในกรณีนี้PartyIDคือคอลัมน์ข้อมูลประจำตัวและการเป็นตัวเลขจะไม่ตรงกันเลยSamAccountNameดังนั้นจึงใช้งานได้สำหรับฉัน คุณสามารถลองใช้วิธีการของคุณเอง - ให้แน่ใจว่าคุณเข้าใจโดเมนของข้อมูลของคุณเพื่อไม่ให้มีการแยกกับข้อมูลจริง ซึ่งอาจเป็นเรื่องง่ายเหมือนกับการใส่อักขระที่แตกต่างเช่นนี้:

Coalesce('n' + SamAccountName, 'p' + Convert(varchar(11), PartyID))

แม้ว่าจะPartyIDกลายเป็นไม่ใช่ตัวเลขสักวันหนึ่งและสามารถตรงกับ a SamAccountName, ตอนนี้มันจะไม่สำคัญ

โปรดทราบว่าการมีดัชนีรวมถึงคอลัมน์ที่คำนวณทำให้เกิดผลลัพธ์นิพจน์แต่ละรายการที่จะบันทึกลงดิสก์พร้อมข้อมูลอื่น ๆ ในตารางซึ่งใช้พื้นที่ดิสก์เพิ่มเติม

โปรดทราบว่าหากคุณไม่ต้องการดัชนีคุณยังสามารถบันทึก CPU ได้โดยทำให้นิพจน์ถูกคำนวณล่วงหน้าไปยังดิสก์โดยเพิ่มคำหลักPERSISTEDลงในส่วนท้ายของนิยามนิพจน์คอลัมน์

ใน SQL Server 2008 ขึ้นไปให้ใช้วิธีการกรองที่แน่นอนแทนหากคุณสามารถทำได้!

การทะเลาะวิวาท

โปรดทราบว่าผู้เชี่ยวชาญด้านฐานข้อมูลบางคนจะเห็นสิ่งนี้เป็น "ตัวแทนตัวแทน" ซึ่งมีปัญหาอย่างแน่นอน (ส่วนใหญ่เกิดจากปัญหาเกี่ยวกับการพยายามพิจารณาว่าบางสิ่งเป็นมูลค่าที่แท้จริงหรือมูลค่าตัวแทนสำหรับข้อมูลที่ขาดหายไปซึ่งอาจเป็นปัญหาได้ ด้วยจำนวนตัวแทนตัวแทนที่ไม่ใช่ค่า NULL คูณอย่างบ้าคลั่ง)

อย่างไรก็ตามฉันเชื่อว่ากรณีนี้แตกต่างกัน คอลัมน์ที่คำนวณที่ฉันเพิ่มจะไม่ถูกใช้เพื่อกำหนดอะไร มันไม่มีความหมายของตัวเองและเข้ารหัสข้อมูลที่ไม่พบแยกต่างหากในคอลัมน์อื่น ๆ ที่กำหนดไว้อย่างถูกต้อง ไม่ควรเลือกหรือใช้

ดังนั้นเรื่องราวของฉันคือว่านี่ไม่ใช่ตัวแทน NULL และฉันก็เกาะติดมัน! เนื่องจากเราไม่ต้องการค่าที่ไม่ใช่ค่า NULL เพื่อจุดประสงค์อื่นนอกเหนือจากการหลอกลวงUNIQUEดัชนีให้ละเว้นค่า NULL กรณีการใช้งานของเราไม่มีปัญหาที่เกิดขึ้นกับการสร้าง NULL ตัวแทน

ทั้งหมดที่กล่าวว่าผมมีปัญหากับการใช้มุมมองการจัดทำดัชนีไม่มีแทน SCHEMABINDINGแต่จะนำปัญหาบางอย่างกับมันเช่นความต้องการของการใช้ ขอให้สนุกเพิ่มคอลัมน์ใหม่ลงในตารางฐานของคุณ (อย่างน้อยที่สุดคุณจะต้องวางดัชนีแล้วปล่อยมุมมองหรือเปลี่ยนมุมมองเพื่อไม่ให้ถูกผูกสคีมา) ดูแบบเต็มรูปแบบ (ยาว) รายการของข้อกำหนดสำหรับการสร้างมุมมองที่จัดทำดัชนีใน SQL Server (2005) (หรือรุ่นที่ใหม่กว่า) (2000)

ปรับปรุง

หากคอลัมน์ของคุณเป็นตัวเลขอาจมีความท้าทายในการตรวจสอบให้แน่ใจว่าข้อ จำกัด ที่ไม่ซ้ำใครใช้Coalesceไม่ส่งผลให้เกิดการชน ในกรณีนั้นมีตัวเลือกบางอย่าง หนึ่งอาจใช้จำนวนลบเพื่อวาง "ตัวแทน NULLs" เฉพาะในช่วงลบและ "ค่าจริง" เฉพาะในช่วงบวก อีกวิธีหนึ่งคือสามารถใช้รูปแบบต่อไปนี้ ในตารางIssue(ที่IssueIDเป็นPRIMARY KEY) มีอาจจะหรืออาจจะไม่ได้เป็นTicketIDแต่ถ้ามีก็จะต้องไม่ซ้ำกัน

ALTER TABLE dbo.Issue ADD TicketUnique
   AS (CASE WHEN TicketID IS NULL THEN IssueID END);
ALTER TABLE dbo.Issue ADD CONSTRAINT UQ_Issue_Ticket_AllowNull
   UNIQUE (TicketID, TicketUnique);

ถ้า IssueID 1 มีตั๋ว 123 UNIQUEข้อ จำกัด จะเป็นค่า (123, NULL) ถ้า IssueID 2 ไม่มีตั๋วมันจะเปิดใช้งาน (NULL, 2) ความคิดบางอย่างจะแสดงให้เห็นว่าข้อ จำกัด นี้ไม่สามารถทำซ้ำสำหรับแถวใด ๆ ในตารางและยังอนุญาตให้มี NULL หลายตัว


16

สำหรับผู้ที่ใช้Microsoft SQL Server Managerและต้องการสร้างดัชนีที่ไม่ซ้ำใคร แต่ไม่มีค่าคุณสามารถสร้างดัชนีเฉพาะของคุณได้ตามปกติในคุณสมบัติดัชนีสำหรับดัชนีใหม่ของคุณเลือก "ตัวกรอง" จากแผงด้านซ้ายจากนั้นป้อน ตัวกรองของคุณ (ซึ่งเป็นส่วนคำสั่งของคุณ) คุณควรอ่านบางสิ่งเช่นนี้:

([YourColumnName] IS NOT NULL)

ใช้งานได้กับ MSSQL 2012


วิธีสร้างดัชนีที่กรองภายใต้ Microsoft SQL Server Management Studio อธิบายไว้ที่นี่และทำงานได้อย่างสมบูรณ์แบบ: msdn.microsoft.com/en-us/library/cc280372.aspx
Jan

9

เมื่อฉันใช้ดัชนีเฉพาะด้านล่าง:

CREATE UNIQUE NONCLUSTERED INDEX idx_badgeid_notnull
ON employee(badgeid)
WHERE badgeid IS NOT NULL;

การอัปเดตและการแทรกที่ไม่ใช่ค่า null ทุกครั้งล้มเหลวโดยมีข้อผิดพลาดด้านล่าง:

การอัปเดตล้มเหลวเนื่องจากตัวเลือก SET ต่อไปนี้มีการตั้งค่าไม่ถูกต้อง: 'ARITHABORT'

ฉันพบสิ่งนี้ในMSDN

SET ARITHABORT จะต้องเป็น ON เมื่อคุณสร้างหรือเปลี่ยนแปลงดัชนีในคอลัมน์ที่คำนวณหรือมุมมองที่จัดทำดัชนี หาก SET ARITHABORT ปิดใช้งานให้สร้างอัปเดต INSERT และลบคำสั่งบนตารางที่มีดัชนีในคอลัมน์ที่คำนวณหรือมุมมองที่จัดทำดัชนีจะล้มเหลว

ดังนั้นเพื่อให้มันทำงานได้อย่างถูกต้องฉันทำอย่างนี้

คลิกขวา [ฐานข้อมูล] -> คุณสมบัติ -> ตัวเลือก -> ตัวเลือกอื่น ๆ -> Misscellaneous -> ยกเลิกการใช้งานทางคณิตศาสตร์ -> จริง

ฉันเชื่อว่าเป็นไปได้ที่จะตั้งค่าตัวเลือกนี้ในการใช้รหัส

ALTER DATABASE "DBNAME" SET ARITHABORT ON

แต่ฉันยังไม่ได้ทดสอบ


6

สร้างมุมมองที่เลือกเฉพาะที่ไม่ใช่NULLคอลัมน์และสร้างUNIQUE INDEXในมุมมอง:

CREATE VIEW myview
AS
SELECT  *
FROM    mytable
WHERE   mycolumn IS NOT NULL

CREATE UNIQUE INDEX ux_myview_mycolumn ON myview (mycolumn)

โปรดทราบว่าคุณจะต้องดำเนินการINSERTและUPDATEดูในมุมมองแทนตาราง

คุณสามารถทำได้ด้วยINSTEAD OFทริกเกอร์:

CREATE TRIGGER trg_mytable_insert ON mytable
INSTEAD OF INSERT
AS
BEGIN
        INSERT
        INTO    myview
        SELECT  *
        FROM    inserted
END

ดังนั้นฉันต้องเปลี่ยน Dal เพื่อแทรกลงในมุมมองหรือไม่
จวร์ต

1
คุณสามารถสร้างทริกเกอร์ INSTEAD OF INSERT
Quassnoi

6

มันสามารถทำได้ในการออกแบบเช่นกัน

คลิกขวาที่ดัชนี> คุณสมบัติเพื่อรับหน้าต่างนี้

การจับกุม


ทางเลือกที่ดีมากถ้าคุณสามารถเข้าถึงนักออกแบบได้
ฟรานซิสโก

แม้ว่าอย่างที่ฉันเพิ่งค้นพบเมื่อคุณมีข้อมูลในตารางของคุณคุณจะไม่สามารถใช้นักออกแบบได้อีกต่อไป ดูเหมือนว่าจะไม่สนใจตัวกรองและพบกับการปรับปรุงตารางใด ๆ ที่พยายามทำพร้อมกับข้อความ "ไม่อนุญาตให้ใช้คีย์ซ้ำ"
MortimerCat

4

เป็นไปได้ที่จะสร้างข้อ จำกัด ที่ไม่ซ้ำกันในมุมมองแบบจัดทำดัชนี

คุณสามารถสร้างมุมมองดังนี้:

CREATE VIEW dbo.VIEW_OfYourTable WITH SCHEMABINDING AS
SELECT YourUniqueColumnWithNullValues FROM dbo.YourTable
WHERE YourUniqueColumnWithNullValues IS NOT NULL;

และข้อ จำกัด ที่ไม่เหมือนใครเช่นนี้:

CREATE UNIQUE CLUSTERED INDEX UIX_VIEW_OFYOURTABLE 
  ON dbo.VIEW_OfYourTable(YourUniqueColumnWithNullValues)

2

อาจพิจารณาINSTEAD OFทริกเกอร์ "" และตรวจสอบด้วยตัวเองเหรอ? ด้วยดัชนีที่ไม่เป็นคลัสเตอร์ (ไม่ซ้ำกัน) ในคอลัมน์เพื่อเปิดใช้งานการค้นหา


1

ตามที่ระบุไว้ก่อนหน้านี้ SQL Server ไม่ได้ดำเนินการตามมาตรฐาน ANSI UNIQUE CONSTRAINTเมื่อมันมาถึง มีตั๋วใน Microsoft Connectสำหรับสิ่งนี้ตั้งแต่ปี 2007 ตามที่แนะนำไว้ที่นี่และที่นี่ตัวเลือกที่ดีที่สุด ณ วันนี้คือการใช้ดัชนีที่กรองตามที่ระบุในคำตอบอื่นหรือคอลัมน์ที่คำนวณเช่น:

CREATE TABLE [Orders] (
  [OrderId] INT IDENTITY(1,1) NOT NULL,
  [TrackingId] varchar(11) NULL,
  ...
  [ComputedUniqueTrackingId] AS (
      CASE WHEN [TrackingId] IS NULL
      THEN '#' + cast([OrderId] as varchar(12))
      ELSE [TrackingId_Unique] END
  ),
  CONSTRAINT [UQ_TrackingId] UNIQUE ([ComputedUniqueTrackingId])
)

1

คุณสามารถสร้างทริกเกอร์INSTEAD OFเพื่อตรวจสอบเงื่อนไขและข้อผิดพลาดที่เฉพาะเจาะจงได้ การสร้างดัชนีอาจมีค่าใช้จ่ายสูงในตารางที่มีขนาดใหญ่กว่า

นี่คือตัวอย่าง:

CREATE TRIGGER PONY.trg_pony_unique_name ON PONY.tbl_pony
 INSTEAD OF INSERT, UPDATE
 AS
BEGIN
 IF EXISTS(
    SELECT TOP (1) 1 
    FROM inserted i
    GROUP BY i.pony_name
    HAVING COUNT(1) > 1     
    ) 
     OR EXISTS(
    SELECT TOP (1) 1 
    FROM PONY.tbl_pony t
    INNER JOIN inserted i
    ON i.pony_name = t.pony_name
    )
    THROW 911911, 'A pony must have a name as unique as s/he is. --PAS', 16;
 ELSE
    INSERT INTO PONY.tbl_pony (pony_name, stable_id, pet_human_id)
    SELECT pony_name, stable_id, pet_human_id
    FROM inserted
 END

-1

คุณไม่สามารถทำได้ด้วยUNIQUEข้อ จำกัด แต่คุณสามารถทำสิ่งนี้ได้ในทริกเกอร์

    CREATE TRIGGER [dbo].[OnInsertMyTableTrigger]
   ON  [dbo].[MyTable]
   INSTEAD OF INSERT
AS 
BEGIN
    SET NOCOUNT ON;

    DECLARE @Column1 INT;
    DECLARE @Column2 INT; -- allow nulls on this column

    SELECT @Column1=Column1, @Column2=Column2 FROM inserted;

    -- Check if an existing record already exists, if not allow the insert.
    IF NOT EXISTS(SELECT * FROM dbo.MyTable WHERE Column1=@Column1 AND Column2=@Column2 @Column2 IS NOT NULL)
    BEGIN
        INSERT INTO dbo.MyTable (Column1, Column2)
            SELECT @Column2, @Column2;
    END
    ELSE
    BEGIN
        RAISERROR('The unique constraint applies on Column1 %d, AND Column2 %d, unless Column2 is NULL.', 16, 1, @Column1, @Column2);
        ROLLBACK TRANSACTION;   
    END

END

-1
CREATE UNIQUE NONCLUSTERED INDEX [UIX_COLUMN_NAME]
ON [dbo].[Employee]([Username] ASC) WHERE ([Username] IS NOT NULL) 
WITH (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON, PAD_INDEX = OFF, SORT_IN_TEMPDB = OFF, 
DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, STATISTICS_NORECOMPUTE = OFF, ONLINE = OFF, 
MAXDOP = 0) ON [PRIMARY];

-1

รหัสนี้ถ้าคุณทำแบบฟอร์มการลงทะเบียนกับกล่องข้อความและใช้การแทรกและกล่องข้อความของคุณว่างเปล่าและคุณคลิกที่ปุ่มส่ง

CREATE UNIQUE NONCLUSTERED INDEX [IX_tableName_Column]
ON [dbo].[tableName]([columnName] ASC) WHERE [columnName] !=`''`;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.