2016-07-15 8 views
0

Mit phpMyAdmin und MySQL v5.5.49 betrachten:MySQL UNIQUE CONSTRAINT failing in CREATE TABLE mit nachfolgender INSERT

CREATE TABLE op_sys (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    name VARCHAR(255) NOT NULL, 
    version VARCHAR(255) NOT NULL, 
    -- UNIQUE KEY name_version (name, version) 
    -- CONSTRAINT name_version UNIQUE (name, version) 
    -- UNIQUE(name, version) 
    -- CONSTRAINT UNIQUE(name, version) 
)ENGINE=InnoDB; 

ich alle vier der kommentierten heraus versucht habe versucht einfach INSERT INTO sys_op für doppelte Werte zu stoppen " Name "und" Version ". Alle vier werden ohne Fehler verarbeitet.

der Einsatz in:

INSERT INTO op_sys(name, version) 
VALUES ('ANDROID','ANDROID'); 

führt "erfolgreich". ANDROID ANDROID ist jetzt eine Zeile. Wo bin ich falsch gelaufen oder welchen Schritt kenne ich nicht? Ich habe das MySQL-Handbuch und einige verschiedene Beiträge hier überprüft, die zu sagen scheinen, dass ich es richtig mache ... Danke.

Antwort

2

Sie scheinen falsch zu verstehen, was UNIQUE KEY bedeutet:

ein eindeutiger Index erstellt eine Einschränkung, so dass alle Werte im Index unterscheiden müssen. Ein Fehler tritt auf, wenn Sie versuchen, eine neue Zeile mit einem Schlüsselwert hinzuzufügen, der einer vorhandenen Zeile entspricht. Für alle Engines erlaubt ein UNIQUE Index mehrere NULL-Werte für Spalten, die NULL enthalten können.

Wenn Ihre Tabelle UNIQUE(name, version) hat, dann können Sie tun:

INSERT INTO op_sys(name, version) VALUES ('ANDROID','ANDROID'); 

Aber das nächste Mal, wenn Sie es tun, wird es scheitern, weil die Tabelle bereits einen Datensatz mit dem gleichen Paar (Name hält, Version) wie im Datensatz, den Sie einfügen möchten.

Einfügen eines Datensatzes zu verhindern, die den gleichen Wert für name und version` hat, könnten Sie ein verwenden trigger:

CREATE TRIGGER different_values BEFORE INSERT ON op_sys 
FOR EACH ROW BEGIN 
DECLARE identical_values CONDITION FOR SQLSTATE '45000'; 
IF NEW.name = NEW.version THEN 
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Identical values for name and version'; 
END IF; 
END; 

Es vor jedem INSERT auf dem Tisch sys_op, und wenn die name und version Felder laufen Halten Sie identische Werte, es wird einen Fehler generieren und die Einfügung wird fehlschlagen.

Der Fehler zurückgegeben sieht wie folgt aus:

ERROR 1644 (45000): Identical values for name and version 

Dokumentation:
- CREATE INDEX
- CREATE TRIGGER
- SIGNAL

+0

Danke, genau das habe ich gesucht. Prost! – Chris

2

Eine mehrspaltige eindeutigen Index verhindert, dass Sie die gleichen zwei Werte haben für diese 2 Felder zwischen den Aufzeichnungen. Das bedeutet, Sie können nicht 2 Datensätze haben, wobei Name und Version 'ANDROID', 'ANDROID' sind. Ein eindeutiger Index verhindert jedoch nicht, dass diese Felder in einer einzelnen Zeile den gleichen Wert haben.

Sie müssen dieses Steuerelement entweder auf Anwendungsebene implementieren, wo Sie überprüfen, ob die 2 Feldwerte gleich sind, und wenn ja, dann führen Sie die Einfügung nicht durch.

In der Datenbank-Ebene können Sie vor dem Einfügen einen Trigger anzeigen und den Wert der beiden Felder überprüfen und eine benutzerdefinierte Fehlermeldung mit dem Befehl signal auslösen.

Aber ich habe so ein de ja vu Gefühl. Als ob du diese Frage schon einmal gestellt hättest und du kein if() in php machen könntest ...

+0

Nein, zum ersten Mal. Ja, einfach auf der PHP-Seite - überprüfen Sie einfach, ob der Wert in der Spalte vor der Ausführung der Einfügung ist. Ich werde Trigger untersuchen, da dies scheint, was ich vermisse. Vielen Dank! – Chris

Verwandte Themen