Wenn Sie einen CHECK
erstellen Einschränkung in SQL Server, denken Sie vielleicht nicht einmal darüber nach, ob es sich um eine Einschränkung auf Tabellenebene oder eine Einschränkung auf Spaltenebene handelt.
Ein CHECK
auf Tabellenebene Einschränkung gilt für die Tabelle, während eine Einschränkung auf Spaltenebene für eine bestimmte Spalte gilt. Mit einem CHECK
auf Tabellenebene Einschränkung, es ist die Zeile, die überprüft wird, wenn die Daten überprüft werden. Mit einem CHECK
auf Spaltenebene Einschränkung, es ist die spezifische Spalte, die überprüft wird.
Im Allgemeinen wissen Sie anhand der Definition, die Sie ihr geben, ob die Einschränkung, die Sie erstellen, eine Einschränkung auf Tabellen- oder Spaltenebene ist. Wenn nur eine Spalte im Ausdruck überprüft wird, handelt es sich um eine Einschränkung auf Spaltenebene. Andernfalls handelt es sich um eine Einschränkung auf Tabellenebene.
Aber woher wissen Sie, ob Ihre bestehenden Einschränkungen auf Spalten- oder Tabellenebene liegen?
Sie können eines der folgenden Codebeispiele ausführen, um zu bestimmen, ob Ihre vorhandenen Einschränkungen auf Spalten- oder Tabellenebene liegen. Diese rufen alle CHECK
ab Einschränkungen für die aktuelle Datenbank, aber Sie können immer ein WHERE
verwenden -Klausel, um sie auf eine bestimmte Einschränkung einzugrenzen.
Beispiel 1 – Grundlegende Abfrage
Hier ist eine einfache Abfrage, die grundlegende Informationen über alle CHECK
zurückgibt Beschränkungen in der aktuellen Datenbank.
Hier frage ich die sys.check_constraints
ab Systemansicht (die eine Zeile für jedes Objekt zurückgibt, das ein CHECK
ist Einschränkung, mit sys.objects.type = 'C'
). Ich gebe nur vier Spalten zurück (aber Sie können so viele Spalten zurückgeben, wie Sie möchten).
SELECT Name, OBJECT_NAME(parent_object_id) AS 'Table', parent_column_id, Definition FROM sys.check_constraints;
Ergebnis:
+-----------------+----------------+--------------------+----------------------------------------+ | Name | Table | parent_column_id | Definition | |-----------------+----------------+--------------------+----------------------------------------| | chkPrice | ConstraintTest | 2 | ([Price]>(0)) | | chkValidEndDate | ConstraintTest | 0 | ([EndDate]>=[StartDate]) | | chkTeamSize | ConstraintTest | 3 | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | Occupation | 3 | ([JobTitle]<>'Digital Nomad') | +-----------------+----------------+--------------------+----------------------------------------+
Der schnellste Weg, um zu bestimmen, welche Einschränkungen Einschränkungen auf Tabellenebene sind, besteht darin, nach der Null zu suchen (
0
) in der
parent_column_id
Säule. Alles mit einer Null ist ein CHECK
auf Tabellenebene Zwang. Ein Wert ungleich Null zeigt an, dass es sich um einen CHECK
auf Spaltenebene handelt Einschränkung, die für die Spalte mit dem angegebenen ID-Wert definiert ist.
In diesem Beispiel gibt es also drei Einschränkungen auf Spaltenebene und eine Einschränkung auf Tabellenebene.
Beachten Sie, dass es zwei Einschränkungen mit derselben parent_column_id gibt (3), diese beiden Einschränkungen stammen jedoch aus unterschiedlichen Tabellen. Die 3 bezieht sich auf die dritte Spalte ihrer jeweiligen Tabellen.
Wie bereits erwähnt, wenn Sie nur Informationen zu einer bestimmten Einschränkung wünschen, verwenden Sie ein WHERE
Klausel:
SELECT Name, OBJECT_NAME(parent_object_id) AS 'Table', parent_column_id, Definition FROM sys.check_constraints WHERE name = 'chkPrice';
Ergebnis:
+----------+----------------+--------------------+---------------+ | Name | Table | parent_column_id | Definition | |----------+----------------+--------------------+---------------| | chkPrice | ConstraintTest | 2 | ([Price]>(0)) | +----------+----------------+--------------------+---------------+
Beispiel 2 – Verbessern Sie die Abfrage
Wir können das vorherige Beispiel verbessern, indem wir den Namen der übergeordneten Spalte zurückgeben, anstatt nur ihre ID. Dies gibt natürlich nur den Spaltennamen für Einschränkungen auf Spaltenebene zurück. Für Einschränkungen auf Tabellenebene wird NULL zurückgegeben.
SELECT cc.name AS 'Constraint', o.name AS 'Table', ac.name AS 'Column', cc.Definition AS 'Constraint Definition' FROM sys.check_constraints cc LEFT OUTER JOIN sys.objects o ON cc.parent_object_id = o.object_id LEFT OUTER JOIN sys.all_columns ac ON cc.parent_column_id = ac.column_id AND cc.parent_object_id = ac.object_id;
Ergebnis:
+-----------------+----------------+----------+----------------------------------------+ | Constraint | Table | Column | Constraint Definition | |-----------------+----------------+----------+----------------------------------------| | chkPrice | ConstraintTest | Price | ([Price]>(0)) | | chkValidEndDate | ConstraintTest | NULL | ([EndDate]>=[StartDate]) | | chkTeamSize | ConstraintTest | TeamSize | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | Occupation | JobTitle | ([JobTitle]<>'Digital Nomad') | +-----------------+----------------+----------+----------------------------------------+
Beispiel 3 – Weitere Verbesserungen
Lassen Sie uns die Abfrage noch etwas optimieren:
SELECT cc.name AS 'Constraint', cc.is_disabled AS 'Disabled?', CASE WHEN cc.parent_column_id = 0 THEN 'Table-level' ELSE 'Column-level' END AS 'Table/Column', o.name AS 'Table', ISNULL(ac.name, '(n/a)') AS 'Column', cc.Definition AS 'Constraint Definition' FROM sys.check_constraints cc LEFT OUTER JOIN sys.objects o ON cc.parent_object_id = o.object_id LEFT OUTER JOIN sys.all_columns ac ON cc.parent_column_id = ac.column_id AND cc.parent_object_id = ac.object_id;
Ergebnis:
+-----------------+-------------+----------------+----------------+----------+----------------------------------------+ | Constraint | Disabled? | Table/Column | Table | Column | Constraint Definition | |-----------------+-------------+----------------+----------------+----------+----------------------------------------| | chkPrice | 0 | Column-level | ConstraintTest | Price | ([Price]>(0)) | | chkValidEndDate | 0 | Table-level | ConstraintTest | (n/a) | ([EndDate]>=[StartDate]) | | chkTeamSize | 0 | Column-level | ConstraintTest | TeamSize | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | 0 | Column-level | Occupation | JobTitle | ([JobTitle]<>'Digital Nomad') | +-----------------+-------------+----------------+----------------+----------+----------------------------------------+
Ich habe also jetzt den Text „Spaltenebene“ oder „Tabellenebene“ zurückgegeben, je nachdem, um welche es sich handelt.
Ich verwende auch ISNULL()
Funktion, um alle NULL-Werte in „(n/a)“ umzuwandeln.
Und ich habe auch is_disabled hinzugefügt Spalte in die Liste, nur für den Fall, dass eine der Einschränkungen deaktiviert wurde. Sie könnten dieser Spalte immer die gleiche Behandlung zuweisen wie der parent_column_id Spalte und zeigen Sie „Ja“ oder „Nein“ oder „Aktiviert“ oder „Deaktiviert“ oder ähnliches an.