2009-11-25 8 views
30

Mögliche Duplizieren:
How do I create unique constraint that also allows nulls in sql serverSQL Server UNIQUE-Einschränkung mit doppelten NULLs

Ich habe eine Tabelle, wo ich brauche eine Spalte zu zwingen, eindeutige Werte zu haben. Diese Spalte muss nullfähig sein, und nach Geschäftslogik sollten mehrere NULL-Werte zulässig sein, während andere doppelte Werte nicht zulässig sind.

Die SQL Server-UNIQUE-Einschränkung ist in dieser Situation nicht sinnvoll, da NULL als reguläre Werte betrachtet wird, sodass doppelte NULL-Werte zurückgewiesen werden.

Momentan wird Wert Eindeutigkeit von der BLL gewährt, so dass ich nicht nach einem schmutzigen Hack suche, damit es funktioniert. Ich möchte nur wissen, ob es eine saubere Lösung gibt, um diese Einschränkung in der DB durchzusetzen.

Und ja, ich weiß, ich kann einen Trigger schreiben, um das zu tun: Ist ein Auslöser die einzige Lösung? (oder die beste Lösung überhaupt?)

Antwort

51

Wenn Sie SQL Server 2008 verwenden (funktioniert nicht für frühere Version) gibt es das Konzept eines gefilterten Index. Sie können den Index für eine gefilterte Teilmenge der Tabelle erstellen.

CREATE UNIQUE INDEX indexName ON tableName(columns) INCLUDE includeColumns 
WHERE columnName IS NOT NULL 
+0

Wir verwenden SQL Server 2008, das war's, danke. – Patonza

+0

Das funktioniert. Vielen Dank! –

+0

Was bedeutet includeColumns? – Tschallacka

1

Sie können eine Ansicht erstellen, in der Sie nur Nicht-Null-Werte auswählen und einen Index dafür erstellen. Hier

ist die Quelle - Creating Indexed Views

3

Wenn Sie SQL Server 2008 verwenden, haben Sie einen Blick in die gefilterte Indizes zu erreichen, was Sie wollen.

Für ältere Version von SQL Server, eine mögliche Alternative zu einem Trigger beinhaltet eine berechnete Spalte:

  1. Erstellen eine berechnete Spalte, die den Wert Ihrer „einzigartig“ Spalte verwendet, wenn es nicht NULL ist, sonst nutzt es der Wert der Primärschlüsselspalte der Zeile (oder einer Spalte, die eindeutig sein soll).
  2. Wenden Sie eine UNIQUE-Einschränkung auf die berechnete Spalte an.
+0

Sehr interessanter Trick die Verwendung einer berechneten Spalte. Es könnte ein Kollisionsproblem zwischen dem PK und dem tatsächlichen Feldwert geben, aber mit einigen Präfixen sollte es funktionieren. – Patonza

0

Sie UNIQUE in dieser Spalte verwendet werden soll, kann NULL sein und auch per Definition einzigartig. Hoffe, dass hilft.

+0

Ich muss die Constrint auf eine Varchar-Spalte anwenden, damit ich nicht UNIQUEIDENTIFIER verwenden kann. – Patonza

4

Duplikat von this question?

Der berechnete Spaltentrick ist weithin als "Nullbuster" bekannt; Steve Kass meine Notizen Kredit:

CREATE TABLE dupNulls (
pk int identity(1,1) primary key, 
X int NULL, 
nullbuster as (case when X is null then pk else 0 end), 
CONSTRAINT dupNulls_uqX UNIQUE (X,nullbuster) 
) 

Works auf SQL Server 2000. Sie müssen möglicherweise ARITHABORT auf z.B.

ALTER DATABASE MyDatabase SET ARITHABORT ON 
+0

Sieht ähnlich aus, war nicht in der Lage, diese Frage vor dem Posten zu finden. Wie auch immer, hier haben wir ein paar nette Antworten über TSQL2008 "gefilterte Indizes" (die ich nicht einmal kannte), also denke ich, es war die Duplizierung wert :) – Patonza

+0

Das kann zu nicht eindeutigen Werten führen - beachte, wo 'dupNulls .pk = 1, X = null && dupNulls.pk = 2, X = 2' –

+0

@Rowland Shaw: Die für die UNIQUE-Bedingung dupNulls_uqX verwendeten Werte lauten '(NULL, 1) && (2, 0)'. Ich sehe keinen doppelten Wert. – onedaywhen

Verwandte Themen