Die erste Verteidigungslinie, die verhindert, dass ungültige Daten in Ihre Tabellen gelangen, sind die Datentypen der Spalten.
Wenn ein Prozess versucht, eine Spalte auf einen Wert einzufügen oder zu aktualisieren, der außerhalb des Bereichs des Datentyps liegt (oder NULL
wenn die Spalte NULL
s nicht zulässt ), schlägt der Vorgang sofort fehl, ohne dass Sie zusätzliche Arbeit leisten müssen.
Die Auswahl des Datentyps ist einer der wichtigsten Aspekte des Tabellendesigns.
Da Sie kein Schema veröffentlicht haben, werde ich eines basierend auf den von Ihnen angegebenen Informationen erstellen:
CREATE TABLE [dbo].[Tests]
(
ID int IDENTITY(1, 1) PRIMARY KEY,
Test_mode bit NOT NULL, /* Based on only seeing 0/1. Maybe tinyint? */
Active bit NULL
);
Basierend auf diesem Design sind die verfügbaren Kombinationen bereits auf Folgendes beschränkt:
Testmodus aktiv
0 NULL
0 0
0 1
1 NULL
1 0
1 1
Alles andere führt dazu, dass ein Fehler ausgelöst wird. (Was gut ist.)
Gibt es eine Möglichkeit, den Wert von Test_mode auf 0 zu ändern, wenn eine 1 in Active eingefügt wird?
ODER
Wenn Test_mode 1 ist, darf das Einfügen / Aktualisieren von Active nicht zugelassen werden
ODER
Wirf einen Fehler aus, wenn Test_mode 1 ist und versucht wird, Active einzufügen / zu aktualisieren.
Aktiv kann nur NULL, 1, 0 UND nur 1 mit Test_mode als 0 sein.
Sie haben 4 verschiedene Möglichkeiten angegeben, um zu der zulässigen Wertekombination zu gelangen ( na ja , irgendwie). Dies sind sehr unterschiedliche Strategien mit sehr unterschiedlichen Implementierungsverhalten.
Ich bevorzuge die Verwendung von sogenannten deklarativen Einschränkungen. Mit anderen Worten, das Tabellenschema und die zugehörigen Objekte begrenzen die zulässigen Werte, indem explizit angegeben wird , was zulässig ist (oder manchmal, was nicht zulässig ist). Tatsächlich sind die Spaltendatentypen selbst eine Art deklarative Einschränkung. Je näher die Werte an den Tabellendaten liegen, desto einfacher und zuverlässiger können sie eingeschränkt werden. (Im Gegensatz dazu würde eine nicht deklarative oder aktive Einschränkung implementiert, indem ein Teil von T-SQL geschrieben wird, normalerweise entweder ein Tabellenauslöser oder ein Teil einer gespeicherten Prozedur.)
Die ersten drei Optionen können nur mit nicht deklarativen Mitteln implementiert werden. Der letzte ist jedoch deklarativ, also konzentrieren wir uns darauf:
Active
kann nur NULL, 1, 0 UND nur 1 mit Test_mode
als 0 sein.
Dies definiert, was Sie tatsächlich wollen, dh die zulässigen Wertekombinationen in der Tabelle. Beachten Sie, dass die gültigen Kombinationen nur von Spaltenwerten in derselben Zeile abhängen . Dies ist wichtig, da hiermit festgelegt wird, mit welchen Mechanismen die Einschränkung implementiert werden kann.
In diesem Fall können wir eine CHECK
Einschränkung verwenden , bei der es sich um einen True / False-Test handelt, der anhand der Spaltenwerte 1 einer Zeile feststellt, ob eine Zeile gültig oder ungültig ist . Wenn der Test fehlschlägt, schlägt der Vorgang, bei dem versucht wurde, die Zeile zu ändern, mit einem Fehler fehl.
ALTER TABLE [dbo].[Tests] WITH CHECK
ADD CONSTRAINT CC_Tests_TestMode_Active
CHECK ((Test_mode != 0) OR ((Active IS NOT NULL) AND (Active = 1)));
Sie werden feststellen, dass ich das Prädikat so konstruiert habe, dass es auch dann weiter funktioniert, wenn Test_mode
es sich tatsächlich um einen (nicht nullbaren) Ganzzahltyp handelt. Das IS NOT NULL
Teil ist erforderlich, da CHECK
Einschränkungen Zeilen zulassen, in denen das Prädikat ausgewertet wird undefined
.
1 Sie können verwendet werden, um außerhalb der aktuellen Zeile zu prüfen, aber dies ist eine schlechte Praxis, und darauf werde ich hier nicht näher eingehen. Verwenden Sie stattdessen einen Auslöser.