Einschränkungen (Constraints) in Firebird und InterBase
_NOTICE: Dieses Dokument ist ein Kapitel aus dem Buch “The InterBase World”, das von Alexey Kovyazin und Serg Vostrikov geschrieben wurde.
Dieses Kapitel ist den Constraints von InterBase- und Firebird-Datenbanken gewidmet. Datenbank-Constraints sind Regeln, die Beziehungen zwischen Tabellen definieren und Daten in einer Datenbank prüfen und ändern können. Diese Regeln werden als spezielle Datenbankobjekte realisiert. Der Hauptvorteil der Verwendung von Constraints besteht in der Möglichkeit, Datenprüfungen und einen Teil der Geschäftslogik der Anwendung auf Datenbankebene zu implementieren, d.h. sie zu zentralisieren und zu vereinfachen, um die Entwicklung von Datenbankanwendungen einfacher und zuverlässiger zu machen.
Anfängende Entwickler vernachlässigen oft die Verwendung von Datenbank-Constraints, da sie der Meinung sind, dass diese die kreative Arbeit behindern. Tatsächlich beruht eine solche Meinung jedoch auf unzureichenden Kenntnissen der Theorie und Praxis des Datenbankdesigns.
Gleichzeitig wagen es die erfahrensten Designer, auf die Verwendung bestimmter Arten von Constraints zu verzichten, wodurch ihre Anwendungen an Geschwindigkeit gewinnen. Die Erfahrung von Experten-Designern ermöglicht es ihnen, die Arbeit des Servers sehr gut zu verstehen und sein Verhalten in komplizierten Fällen präzise vorherzusagen. Daher ist es für InterBase-Anfänger besser, nicht auf ähnliche Handlungen erfahrener Kollegen zurückzugreifen.
In diesem Buch betrachten wir das Datenbankdesign nicht. Für weitere Informationen zu diesem Thema siehe die Literaturliste am Ende des Buches. Hier werden wir nur alle Arten von Constraints in InterBase-Datenbanken durchgehen und Beispiele für ihre Anwendung betrachten.
Arten von Constraints in einer Datenbank
Es gibt folgende Arten von Constraints in InterBase-Datenbanken:
- PRIMARY KEY;
- UNIQUE KEY;
- FOREIGN KEY
- kann automatische Trigger - ON UPDATE und ON DELETE - einschalten;
- CHECK
In den vorherigen Kapiteln haben wir einige dieser Constraints erwähnt, da es für die logische Darstellung des Materials notwendig war, aber jetzt werden wir ihre Syntax, Anwendung und Implementierung genauer betrachten. Datenbank-Constraints sind von zwei Arten - basierend auf einem Feld und basierend auf mehreren Feldern der Tabelle. Die Syntax beider Arten von Constraints ist unten angegeben.
= [CONSTRAINT constraint]
[ …]
= {UNIQUE | PRIMARY KEY
| CHECK ( )
| REFERENCES other_table [( other_col [, other_col …])]
[ON DELETE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}]
[ON UPDATE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}]
}
Die Syntax von Constraints, die auf mehreren Feldern basieren, ist die folgende:
= [CONSTRAINT constraint]
[< tconstraint> …]
= {{PRIMARY KEY | UNIQUE} ( col [, col …])
| FOREIGN KEY ( col [, col …]) REFERENCES other_table[( other_col [, other_col …])]
[ON DELETE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}]
[ON UPDATE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}]
| CHECK ( )}
Der Unterschied in der Syntax zwischen Constraints, die auf einem Feld und auf mehreren Feldern basieren, ist offensichtlich - im letzten Fall können wir mehrere Felder angeben, die in den Constraint einbezogen werden. Im Fall eines auf einem Feld basierenden Constraints beziehen sich alle beschriebenen Optionen nur auf das aktuelle Feld. Sicherlich haben diese beiden Arten von Constraints eine unterschiedliche Anwendungsweise: Constraints, die auf einem Feld basieren, werden einfach zur Definition des erforderlichen Feldes hinzugefügt, und Constraints, die auf mehreren Feldern basieren, werden nach einem Komma in der allgemeinen Definition der Tabelle angegeben. Detaillierte Beispiele werden in den folgenden Teilen dieses Kapitels gegeben.
Beispiel eines typischen Constraints
Tatsächlich sind Constraints, die auf einem Feld basieren, ein Sonderfall von Constraints, die auf mehreren Feldern basieren.
Das Beispiel für die Erstellung eines Primary-Key-Constraints mit diesen zwei verschiedenen Ansätzen ist unten angegeben. Lassen Sie uns eine Tabelle erstellen, die nur ein Feld enthält, und ihr ein Primary-Key-Constraint zuweisen.
Hier ist das Beispiel des Primary Key unter Verwendung der Syntax eines auf einem Feld basierenden Constraints:
CREATE TABLE test1( ID_PK INTEGER CONSTRAINT pktest NOT NULL PRIMARY KEY); In diesem Beispiel wird ein Primary Key mit dem Namen pktest für das Feld ID_PK erstellt. Als Ergebnis haben wir eine ziemlich kompakte Beschreibung in einer Zeile. Wir können die Syntax von Constraints, die auf mehreren Feldern basieren, für denselben Zweck verwenden: CREATE TABLE test2( ID_PK INTEGER NOT NULL, CONSTRAINT pktst PRIMARY KEY (ID_PK));
Erstellen von Constraints
Betrachten wir die Erstellung von Constraints genauer. Als erstes in der Beschreibung der allgemeinen Syntax von Constraints kommt die Option [CONSTRAINT constraint]. Wie Sie sehen können, steht diese Option in eckigen Klammern, d.h. sie ist optional.
Mit dieser Option können Sie dem erstellten Constraint einen Namen geben, sowohl bei der Anwendung der Syntax von Constraints, die auf einem Feld basieren, als auch bei Constraints, die auf mehreren Feldern basieren. Wenn Sie keinen Namen für den Constraint angegeben haben, generiert InterBase automatisch einen. Dennoch ist es besser, dem erstellten Constraint einen Namen zu geben, um die Lesbarkeit des Datenbankschemas zu verbessern und die Verwaltung von Constraints später zu vereinfachen.
Nachdem Sie dem Constraint einen Namen gegeben haben, sollte sein Typ definiert werden. Betrachten wir die verschiedenen Arten von Constraints in der Reihenfolge, in der sie in der Beschreibung der allgemeinen Syntax von Constraints angegeben sind.
Primär- und Unique-Keys
Primärschlüssel sind eine der Hauptarten von Datenbank-Constraints. Sie werden für die eindeutige Identifizierung von Datensätzen in der Tabelle verwendet. Nehmen wir an, wir speichern eine Liste von Personen in einer Datenbank. Es ist durchaus möglich, dass es zwei (oder mehr) Personen mit demselben Nachnamen, Vornamen und Vatersnamen gibt. Wie können wir eine Person von einer anderen unterscheiden (sicherlich geht es darum, eine Person von einer anderen gemäß den in einer Datenbank gespeicherten Informationen zu unterscheiden)?
In diesem Fall wird “Person” durch einen Datensatz in der Tabelle repräsentiert, daher können wir eine allgemeinere Frage stellen - wie können wir einen Datensatz in (irgendeiner) Tabelle von einem anderen Datensatz in derselben Tabelle unterscheiden. Zu diesem Zweck werden Constraints - Primärschlüssel - verwendet. Der Primärschlüssel repräsentiert ein oder mehrere Felder in der Tabelle, deren Kombination für jeden Datensatz eindeutig ist. Es gibt keine sich wiederholenden Werte eines Primärschlüssels für eine Tabelle.
Unique-Keys erfüllen dieselbe Funktion - sie dienen ebenfalls der eindeutigen Identifizierung von Datensätzen in der Tabelle. Der Unterschied zwischen Primär- und Unique-Keys besteht darin, dass es in der Tabelle nur einen Primärschlüssel geben kann, während es mehrere Unique-Keys geben kann. Es wird darauf hingewiesen, dass sowohl ein Primär- als auch ein Unique-Key als Referenzbasis für Fremdschlüssel verwendet werden können (siehe weiter unten).
Die formale Beschreibung der Begriffe Primär- und Unique-Key sowie anderer wichtiger Definitionen finden Sie im Anhang “Glossar” am Ende des Buches. Die Syntax zum Erstellen eines Primär- und Unique-Keys basierend auf einem einzelnen Feld ist die folgende:
< pkukconstraint > = [CONSTRAINT constraint] {PRIMARY KEY | UNIQUE}
Beispiele für Primär- und Unique-Keys:
CREATE TABLE pkuk( pk NUMERIC(15,0) NOT NULL PRIMARY KEY, /*ein Primärschlüssel*/
uk1 VARCHAR(50) NOT NULL UNIQUE,/*ein Unique-Key */
uk2 INTEGER NOT NULL UNIQUE /\* noch ein Unique-Key */);
Syntax zum Erstellen von Primär- und Unique-Keys basierend auf mehreren Feldern:
= [CONSTRAINT constraint] {PRIMARY KEY | UNIQUE} ( col [, col …])
Diese Syntax ermöglicht es, Schlüssel auf der Grundlage einer Kombination von Feldern zu erstellen. Hier sind die Beispiele für die Erstellung von Primär- und Unique-Keys aus mehreren Feldern:
CREATE TABLE pkuk2( Number1 INTEGER NOT NULL, Name1 VARCHAR(50) NOT NULL, Kol INTEGER NOT NULL, Stoim NUMERIC(15,4) NOT NULL, CONSTRAINT pkt PRIMARY KEY (Number1, Name1), /*Primärschlüssel pkt basierend auf zwei Feldern*/ CONSTRAINT ukt1 UNIQUE (kol, Stoim)); /*Unique-Key ukt1 basierend auf zwei Feldern*/
Beachten Sie, dass alle Felder, die in Primär- und Unique-Keys enthalten sind, als NOT NULL deklariert werden sollten, da diese Schlüssel keinen undefinierten Wert haben können. Neben der Erstellung des Constraints von Primär- und Unique-Keys bei der Erstellung der Tabelle gibt es die Möglichkeit, Constraints zu einer bereits vorhandenen Tabelle hinzuzufügen. In diesem Fall wird die DDL-Anweisung ALTER TABLE verwendet. Die Syntax zum Hinzufügen von Primär- oder Unique-Key-Constraints zu einer vorhandenen Tabelle ähnelt der oben beschriebenen:
ALTER TABLE tablename ADD [CONSTRAINT constraint] {PRIMARY KEY | UNIQUE} ( col [, col …])
Betrachten wir das Beispiel der Erstellung von Primär- und Unique-Key mit ALTER TABLE:
CREATE TABLE pkalter( ID1 INTEGER NOT NULL, ID2 INTEGER NOT NULL, UID VARCHAR(24));
Dann fügen wir Schlüssel hinzu. Zuerst den Primärschlüssel:
ALTER TABLE pkalter ADD CONSTRAINT pkal1 PRIMARY KEY (id1, id2);
Dann den Unique-Key: ALTER TABLE pkalter ADD CONSTRAINT ukal UNIQUE (uid);
Es sollte angemerkt werden, dass nur der Besitzer dieser Tabelle oder der Systemadministrator SYSDBA (für weitere Details über die Besitzer und den SYSDBA-Benutzer siehe das Kapitel “Sicherheit in InterBase: Benutzer, ihre Funktionen und Rechte” - Teil 4) das Hinzufügen (sowie das Löschen) von Primär- und Unique-Keys zur Tabelle durchführen kann.
Fremdschlüssel
Der nächste häufig in InterBase-Datenbanken verwendete Constraint ist der Fremdschlüssel-Constraint. Dies ist ein sehr leistungsfähiges Werkzeug zur Gewährleistung der referenziellen Integrität in einer Datenbank, das es ermöglicht, nicht nur das Vorhandensein korrekter Referenzen in einer Datenbank zu überwachen, sondern diese Referenzen auch automatisch zu steuern!
Der Sinn der Erstellung eines Fremdschlüssels ist folgender: Wenn zwei Tabellen zur Speicherung zusammenhängender Informationen dienen, ist es notwendig, zu garantieren, dass diese Beziehung immer korrekt ist. Zum Beispiel das Dokument “Frachtbrief”, das einen allgemeinen Kopf (Datum, Nummer des Frachtbriefs usw.) und eine Reihe von Detaildatensätzen (Beschreibung der Waren, Menge usw.) enthält.
Zur Speicherung eines solchen Dokuments werden in einer Datenbank zwei Tabellen erstellt - eine für die Speicherung der Köpfe der Frachtbriefe und die zweite für die Speicherung des Inhalts des Frachtbriefs - Datensätze über Waren und ihre Menge. Solche Tabellen werden als Haupt- und Untertabelle oder Master-Tabelle und Detailtabelle bezeichnet.
Dem gesunden Menschenverstand zufolge kann der Inhalt des Frachtbriefs nicht ohne das Vorhandensein seines Kopfes existieren. Mit anderen Worten, wir können keinen Datensatz über die Waren einfügen, wenn wir den Kopf des Frachtbriefs nicht erstellt haben, und wir können keinen Datensatz des Kopfes löschen, wenn es Datensätze über die Waren gibt. Zur Realisierung eines solchen Verhaltens werden die Tabelle des Kopfes und die Tabelle der Details mit einem Fremdschlüssel-Constraint verbunden.
Betrachten wir den Sinn der Festlegung von Fremdschlüssel-Constraints am Beispiel der Tabellen, die Informationen über Frachtbriefe enthalten. Zu diesem Zweck erstellen wir zwei Tabellen zur Speicherung des Frachtbriefs - die Tabelle TITLE zur Speicherung des Kopfes und die Tabelle INVENTORY zur Speicherung der Informationen über die im Frachtbrief enthaltenen Waren.
CREATE TABLE TITLE( ID_TITLE INTEGER NOT NULL Primary Key, DateNakl DATE, NumNakl INTEGER, NoteNakl VARCHAR(255));
Beachten Sie, dass wir sofort einen Primärschlüssel in der Tabelle des Kopfes basierend auf dem Feld ID_TITLE definiert haben. Die restlichen Felder der TITLE-Tabelle enthalten triviale Informationen über den Frachtbriefkopf - Datum, Nummer, Kommentar.
Nun definieren wir die Tabelle zur Speicherung der Informationen über die im Frachtbrief enthaltenen Waren:
CREATE TABLE INVENTORY( ID_INVENTORY INTEGER NOT NULL PRIMARY KEY, FK_TITLE INTEGER NOT NULL, ProductName VARCHAR (255), Kolvo DOUBLE PRECISION, Positio INTEGER);
Schauen wir uns an, welche Felder in der INVENTORY-Tabelle enthalten sind. Erstens ist es ID_INVENTORY - ein Primärschlüssel dieser Tabelle. Dann folgt das ganzzahlige Feld FK_TITLE, das als Referenz auf den Bezeichner ID_TITLE des Kopfes in der Tabelle der Frachtbriefköpfe dient. Dann folgen die Felder ProductName, Kolvo und Positio, die die Beschreibung der Waren, ihre Menge und eine Position im Frachtbrief beschreiben. Das Feld FK_TITLE ist für unser Beispiel am wichtigsten. Wenn wir die Informationen über die Waren eines bestimmten Frachtbriefs ausgeben möchten, sollten wir die folgende Abfrage verwenden, in der der Parameter mas_ID_TITLE den Kopfbezeichner definiert:
SELECT * FROM INVENTORY I1 WHERE I1.FK_TITLE=?mas_ID_TITLE
In der beschriebenen Situation hindert praktisch nichts daran, die INVENTORY-Tabelle mit Datensätzen zu füllen, die auf nicht existierende Datensätze in der TITLE-Tabelle verweisen. Außerdem hindert nichts daran, den Kopf eines bereits vorhandenen Frachtbriefs zu löschen, wodurch die Datensätze über die Waren “herrenlos” werden können. Der Server wird nicht verbieten, alle diese Einfügungen und Löschungen auszuführen. Somit liegt die Kontrolle über die Datenintegrität in einer Datenbank vollständig bei der Client-Anwendung. Sie wissen jedoch, dass mehrere Anwendungen, die möglicherweise von verschiedenen Programmierern entwickelt wurden, mit einer Datenbank arbeiten können, was zu unterschiedlichen Dateninterpretationen und Fehlern führen kann. Folglich ist es unerlässlich, den expliziten Constraint festzulegen, dass nur solche Datensätze über die Waren, die die korrekte Referenz auf den Frachtbriefkopf haben, in die INVENTORY-Tabelle eingefügt werden können. Dies ist tatsächlich ein Fremdschlüssel-Constraint, der es ermöglicht, nur solche Werte in die in Constraints enthaltenen Felder einzufügen, die sich in der anderen Tabelle befinden.
Eine solche Einschränkung kann mithilfe eines Fremdschlüssels erstellt werden. Für das gegebene Beispiel müssen wir Fremdschlüssel-Einschränkungen für das Feld FK_TITLE festlegen und es mit dem Primärschlüssel ID_TITLE in TITLE verknüpfen. Wir können einer bereits vorhandenen Tabelle einen Fremdschlüssel mit dem folgenden Befehl hinzufügen:
ALTER TABLE INVENTORY ADD CONSTRAINT fktitle1 FOREIGN KEY(FK_TITLE) REFERENCES TITLE(ID_TITLE)
Beim Hinzufügen eines Fremdschlüssels tritt häufig der Fehler auf - Objekt wird verwendet. Das Problem besteht darin, dass wir zum Erstellen eines Fremdschlüssels die Datenbank im Alleinbetriebsmodus öffnen müssen - sodass keine anderen Benutzer gleichzeitig aktiv sind. Außerdem sollten wir uns nicht auf die geänderte Tabelle beziehen - dies kann den Fehler „Objekt wird verwendet“ verursachen.
Hier ist INVENTORY der Name der Tabelle, für die die Fremdschlüssel-Einschränkung festgelegt wird; fktitle1 ist der Name des Fremdschlüssels; FK_TITLE - die Felder, die den Fremdschlüssel bilden; TITLE ist der Name der Tabelle, die die Werte (die Referenzbasis) für den Fremdschlüssel liefert; ID_TITLE - Felder des Primär- oder Unique-Schlüssels in der Tabelle TITLE, die als Referenzbasis für den Fremdschlüssel dienen. Eine vollständige Syntax der Fremdschlüssel-Einschränkung (mit der Möglichkeit, Einschränkungen basierend auf mehreren Feldern zu erstellen) ist unten angegeben:
= [CONSTRAINT constraint] FOREIGN KEY ( col [, col …]) REFERENCES other_table [( other_col [, other_col …])] [ON DELETE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}] [ON UPDATE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}]
Wie Sie sehen, enthalten die Definitionen eine große Auswahl an Optionen. Betrachten wir zunächst eine grundlegende Definition eines Fremdschlüssels, die in realen Datenbanken am häufigsten verwendet wird, und analysieren dann die möglichen Optionen.
Eine deklarative Form einer Fremdschlüssel-Einschränkung wird am häufigsten verwendet, wenn eine Reihe von Feldern (col [, col …]), die die Einschränkung bilden, angegeben wird; sowie die other_table, die eine Liste möglicher Werte für den Fremdschlüssel in den Feldern [(other_col [, other_col …])] enthält.
Hier ist ein Beispiel für eine solche Definition beim Erstellen der Tabelle:
CREATE TABLE Inventory2( … FK_TABLE INTEGER NOT NULL CONSTRAINT fkinv REFERENCES TITLE(ID_TITLE) …);
Beachten Sie, dass in dieser Definition die Schlüsselwörter FOREIGN KEY weggelassen werden, und das einzige Feld FK_TITLE implizit als Fremdschlüssel verwendet wird. Eine vollständigere Form der Erstellung des Fremdschlüssels gleichzeitig mit der Tabelle ist im folgenden Beispiel angegeben:
CREATE TABLE Inventory2( … FK_TABLE INTEGER NOT NULL, CONSTRAINT fkinv FOREIGN KEY (FK_TABLE) REFERENCES TITLE(ID_TITLE) …);
Verwendung von NULL in Feldern eines Fremdschlüssels
In Feldern, auf deren Basis ein Fremdschlüssel erstellt wird, ist die Verwendung von NULL-Feldern zulässig. Diese Möglichkeit wurde hinzugefügt, um gegenseitige Referenzen zu ermöglichen. Wenn es beispielsweise zwei Tabellen gibt, die mithilfe von Fremdschlüsseln aufeinander verweisen. Wenn wir die leere Referenz (d. h. NULL) in diesen Fremdschlüsseln nicht zulassen, ist es unmöglich, Datensätze zu den verknüpften Tabellen hinzuzufügen: Um einen Datensatz zur ersten Tabelle hinzuzufügen, muss ein Datensatz in der zweiten Tabelle vorhanden sein, und umgekehrt.
Die Verwendung von NULL als leere Referenz ermöglicht die Erstellung gegenseitiger Referenzen zweier sich gegenseitig referenzierender Tabellen und auch die Speicherung hierarchischer Strukturen in relationalen Tabellen - dabei verweisen Wurzelknoten auf „leere“ Datensätze (d. h. enthalten einfach NULL).
Erweiterte Möglichkeiten der referenziellen Integritätsunterstützung mithilfe von Fremdschlüsseln
Normalerweise reicht die deklarative Variante einer Fremdschlüssel-Einschränkung aus; der Server überwacht nur, dass es unmöglich ist, falsche Werte in die Tabelle mit dem Fremdschlüssel einzufügen - oder, wenn man es versucht, ein Fehler auftritt. Aber InterBase ermöglicht die Ausführung einer Reihe automatischer Operationen beim Ändern/Löschen eines Fremdschlüssels. Zu diesem Zweck wird die folgende Reihe von Fremdschlüssel-Optionen verwendet:
[ON DELETE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}] [ON UPDATE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}]
Diese Optionen ermöglichen die Definition verschiedener Operationen beim Aktualisieren oder Löschen von Fremdschlüsselwerten.
Zum Beispiel können wir festlegen, dass beim Löschen eines Primärschlüssels in der Master-Tabelle alle Datensätze mit demselben Fremdschlüssel in der untergeordneten Tabelle gelöscht werden. In diesem Fall müssen wir einen Fremdschlüssel wie folgt definieren:
ALTER TABLE INVENTORY ADD CONSTRAINT fkautodel FOREIGN KEY (FK_TITLE) REFERENCES TITLE(ID_TITLE) ON DELETE CASCADE
Tatsächlich wird für die Implementierung dieser Operationen ein Systemtrigger verwendet, der bestimmte Operationen ausführt. In Tabelle 1.2 gibt es eine Beschreibung der Operationen verschiedener Optionen (beachten Sie, dass die Optionen NO ACTION|CASCADE|SET DEFAULT|SET NULL nicht in einem Satz ON XXX verwendet werden können).
Tabelle 1.2
| Ereignis | Operation | |||
| NO ACTION | CASCADE | SET DEFAULT | SET NULL | |
| ON DELETE | Beim Löschen eines Fremdschlüssels nichts tun - wird standardmäßig verwendet | Beim Löschen alle zugehörigen Datensätze aus der untergeordneten Tabelle löschen | Beim Ändern ein Fremdschlüsselfeld als Standardwert festlegen |
Beim Ändern ein Fremdschlüsselfeld auf NULL setzen |
| ON UPDATE | Beim Ändern nichts tun - wird standardmäßig verwendet | Beim Ändern eines Datensatzes alle zugehörigen Datensätze in der untergeordneten Tabelle ändern | Beim Löschen ein Fremdschlüsselfeld als Standardwert festlegen |
Beim Löschen ein Fremdschlüsselfeld auf NULL setzen |
Wenn wir nichts angeben oder NO ACTION angeben, müssen wir uns selbst um die Änderung eines Fremdschlüssels (im Falle einer Änderung eines Primärschlüssels) kümmern, und beim Löschen des Primärschlüssels sollten wir die Datensätze aus der untergeordneten Tabelle vorher löschen. Seien Sie bei der Verwendung der CASCADE-Option sehr vorsichtig: Ihre unachtsame Verwendung kann zum Löschen einer großen Anzahl zugehöriger Datensätze führen.
CHECK-Einschränkung
Eine der nützlichsten Einschränkungen in einer Datenbank ist die Check-Einschränkung. Ihre Funktion ist sehr einfach - den in die Tabelle eingefügten Wert auf eine beliebige Bedingung zu prüfen und je nach Erfüllung dieser Bedingung die Daten einzufügen oder nicht. Ihre Syntax ist recht einfach:
= [CONSTRAINT constraint] CHECK ( )}
Hier ist constraint der Name der Einschränkung; ist eine Suchbedingung, in der der eingefügte/aktualisierte Wert als Parameter verwendet werden kann. Wenn die Suchbedingung erfüllt ist, ist das Einfügen/Aktualisieren dieses Werts zulässig; wenn nicht - erscheint ein Fehler. Das einfachste Beispiel für eine Check-Einschränkung:
create table checktst( ID integer CHECK(ID>0));
Diese Check-Einschränkung bestimmt, ob der eingefügte/aktualisierte Wert des ID-Felds größer als null ist, und erlaubt je nach Ergebnis das Einfügen/Aktualisieren eines neuen Werts oder informiert über den Fehler (siehe Kapitel „Erweiterte Möglichkeiten der Sprache der InterBase-gespeicherten Prozeduren“ (Teil 1)).
Es gibt auch komplexere Varianten von Check-Einschränkungen. Eine vollständige Syntax der Suchbedingung ist die folgende:
= {
{ | ()}
| [NOT] BETWEEN AND
| [NOT] LIKE [ESCAPE ]
| [NOT] IN ( [ , …] | )
| IS [NOT] NULL
| {[NOT] {= | < | >} | >= | <=}
{ALL | SOME | ANY} ()
| EXISTS ( )
| SINGULAR ( )
| [NOT] CONTAINING
| [NOT] STARTING [WITH]
| ()
| NOT
| OR
| AND }
Somit bietet CHECK eine große Auswahl an Optionen zur Überprüfung eingefügter/aktualisierter Werte. Sie sollten die folgenden Einschränkungen bei der Verwendung von CHECK beachten:
- Die Daten für CHECK werden nur aus einem aktuellen Datensatz entnommen. Sie sollten die Daten für den Ausdruck in CHECK nicht aus anderen Datensätzen derselben Tabelle entnehmen - sie können von anderen Benutzern geändert werden
- Ein Feld darf nur eine CHECK-Einschränkung haben
- Wenn für die Felddefinition eine Domäne mit einer CHECK-Domäneneinschränkung verwendet wird, kann diese auf der Ebene eines konkreten Felds in der Tabelle nicht neu definiert werden. Es muss gesagt werden, dass CHECK durch Systemtrigger implementiert wird, daher müssen wir bei der Verwendung sehr langer Bedingungen vorsichtig sein, die die Prozesse des Einfügens und Aktualisierens von Datensätzen stark verlangsamen können.
Löschen von Einschränkungen
Sehr oft löschen wir verschiedene Einschränkungen aus den unterschiedlichsten Gründen. Um eine Einschränkung zu löschen, sollten wir die ALTER TABLE-Anweisung der folgenden Form verwenden: ALTER TABLE tablename DROP CONSTRAINT constraintname
constraintname ist der Name der Einschränkung, die gelöscht werden soll. Wenn beim Erstellen der Einschränkung ein bestimmter Name angegeben wurde, sollten wir diesen verwenden; wenn nicht, müssen wir ein beliebiges InterBase-Verwaltungstool öffnen, alle damit verbundenen Einschränkungen durchsuchen und herausfinden, welchen Systemnamen InterBase für die erforderliche Einschränkung generiert hat.
Es sollte beachtet werden, dass nur der Eigentümer der Tabelle oder der Systemadministrator SYSDBA die Einschränkungen löschen kann.