Ich habe eine Situation, in der ich eine eindeutige Einschränkung für eine Reihe von Spalten erzwingen muss, aber nur für einen Wert einer Spalte.
So habe ich zum Beispiel eine Tabelle wie Table (ID, Name, RecordStatus).
RecordStatus kann nur den Wert 1 oder 2 (aktiv oder gelöscht) haben, und ich möchte nur dann eine eindeutige Einschränkung für (ID, RecordStatus) erstellen, wenn RecordStatus = 1 ist, da es mir egal ist, ob mehrere gelöschte Datensätze mit demselben vorhanden sind ICH WÜRDE.
Kann ich das tun, abgesehen vom Schreiben von Triggern?
Ich verwende SQL Server 2005.
sql
sql-server
sql-server-2005
np-hart
quelle
quelle
Antworten:
Fügen Sie eine solche Prüfbedingung hinzu. Der Unterschied besteht darin, dass Sie false zurückgeben, wenn Status = 1 und Count> 0.
http://msdn.microsoft.com/en-us/library/ms188258.aspx
quelle
Siehe, der gefilterte Index . Aus der Dokumentation (Schwerpunkt Mine):
Und hier ist ein Beispiel, das einen eindeutigen Index mit einem Filterprädikat kombiniert:
Dies erzwingt im Wesentlichen Einzigartigkeit ,
ID
wennRecordStatus
ist1
.Nach der Erstellung dieses Index führt eine Verletzung der Eindeutigkeit zu einem Arror:
Hinweis: Der gefilterte Index wurde in SQL Server 2008 eingeführt. Frühere Versionen von SQL Server finden Sie in dieser Antwort .
quelle
ansi_padding
gefilterte Indizes benötigt. Stellen Sie daher sicher, dass diese Option durch Ausführen aktiviert ist,SET ANSI_PADDING ON
bevor Sie einen gefilterten Index erstellen.Sie können die gelöschten Datensätze in eine Tabelle verschieben, in der die Einschränkung fehlt, und möglicherweise eine Ansicht mit UNION der beiden Tabellen verwenden, um das Erscheinungsbild einer einzelnen Tabelle beizubehalten.
quelle
Sie können dies auf eine wirklich hackige Art und Weise tun ...
Erstellen Sie eine schemabundene Ansicht für Ihre Tabelle.
ANSICHT ERSTELLEN Was auch immer SELECT * FROM Table WHERE RecordStatus = 1
Erstellen Sie nun eine eindeutige Einschränkung für die Ansicht mit den gewünschten Feldern.
Ein Hinweis zu schemabunden Ansichten: Wenn Sie die zugrunde liegenden Tabellen ändern, müssen Sie die Ansicht neu erstellen. Viele Fallstricke deswegen.
quelle
Da Sie Duplikate zulassen, funktioniert eine eindeutige Einschränkung nicht. Sie können eine Prüfbedingung für die RecordStatus-Spalte und eine gespeicherte Prozedur für INSERT erstellen, die die vorhandenen aktiven Datensätze überprüft, bevor Sie doppelte IDs einfügen.
quelle
Wenn Sie NULL nicht wie von Bill vorgeschlagen als RecordStatus verwenden können, können Sie seine Idee mit einem funktionsbasierten Index kombinieren. Erstellen Sie eine Funktion, die NULL zurückgibt, wenn der RecordStatus nicht einer der Werte ist, die Sie in Ihrer Einschränkung berücksichtigen möchten (und ansonsten der RecordStatus), und erstellen Sie darüber einen Index.
Dies hat den Vorteil, dass Sie andere Zeilen in der Tabelle in Ihrer Einschränkung nicht explizit untersuchen müssen, was zu Leistungsproblemen führen kann.
Ich sollte sagen, dass ich SQL Server überhaupt nicht kenne, aber ich habe diesen Ansatz in Oracle erfolgreich angewendet.
quelle