2016-06-23 18 views
2

I haben die folgende Tabelle:Abrufen zuletzt eingefügte ID für InnoDB Verbundschlüsseltabelle

CREATE TABLE `my_table` (
    composite_pk1 INT NOT NULL , 
    composite_pk2 INT NOT NULL , 
    data VARCHAR(255) NOT NULL , 
    primary key (composite_pk1, composite_pk2) 
) ENGINE=InnoDB; 

Für eine gegebene composite_pk1 wünsche ich composite_pk2 als Autoinkrement Primärschlüssel zu handeln. Ich möchte nicht, um die Tabelle sperren, und als solchen Plan auf einen Auslöser, wie die Verwendung von folgenden:

DELIMITER $$ 

CREATE TRIGGER my_trigger BEFORE INSERT ON my_table 
FOR EACH ROW BEGIN 
    SET NEW.composite_pk2 = (
     SELECT IFNULL(MAX(composite_pk2), 0) + 1 
     FROM issue_log 
     WHERE composite_pk1 = NEW.composite_pk1 
); 

END $$ 

Ich kann jetzt ein Datensatz einfügen:

$stmt=$myDB->prepare('INSERT INTO my_table(composite_pk1, data) VALUES (?,?)'); 
$stmt->execute([123,'hello']); 

Wie erhalte ich die letzten eingefügt composite_pk2? PDO::lastInsertId funktioniert nur mit nativen Autoinkrement-Tabellen (d. H. Nicht mit dem Trigger-Ansatz). Ich „könnte“ später eine SELECT-Abfrage tun, um den Max-Wert zu erhalten, jedoch gibt es keine Garantie, dass ein weiteren Rekord in schlich hat

+0

Es gibt wirklich keinen guten Weg, dies leider zu tun. Das andere Problem, dem Sie möglicherweise gegenüberstehen, ist der Fall, in dem die MAX-Funktion einen Wert zurückgibt, den eine andere update/insert-Anweisung aufgrund der Lesekonsistenz gerade verwendet hat. Sie können Streit für diese Nummer haben. Ist die Reihenfolge dieses composite_pk2 wichtig? –

+0

@TGray Wird der Trigger nicht sicherstellen, dass keine Updates/Inserts eingefügt werden? Was meinst du mit "Konsistenz lesen"? In Bezug auf die Reihenfolge der 'Composite_pk2' ist wichtig, was meinst du? Danke – user1032531

+0

1 - nein, der Trigger sperrt keinen Wert, was bedeutet, dass jemand, der an einem komplett anderen Datensatz arbeitet, auch den Maximalwert (Wert) während der Arbeit erhalten hat. 2 - Lesekonsistenz bedeutet "Ich arbeite an einer Kopie der Daten, während jemand anders an einer Kopie arbeitet - wenn sich etwas ändert, während ich es ansehe, weiß ich nicht, bis mein Auslöser fehlschlägt (zum Beispiel)". 3 - Muss das composite_pk2 geordnet werden - 1, 2, 3, 4, ...? Wenn nicht, können Sie uuid() anstelle einer numerisch definierten Funktion verwenden http://stackoverflow.com/questions/4933296/get -the-generated-uuid-nach-einfügen-php –

Antwort

1

Sie composite_pk2 mit auto_increment einen eindeutigen Schlüssel machen.

CREATE TABLE `my_table` (
    composite_pk1 INT NOT NULL , 
    composite_pk2 INT NOT NULL unique auto_increment, 
    data VARCHAR(255) NOT NULL , 
    primary key (composite_pk1, composite_pk2) 
) ENGINE=InnoDB; 

Jetzt last_insert_id() gibt die kürzlich erstellte ID für composite_pk2 zurück.

+0

Mit InnoDB Maschine? – user1032531

+0

@ user1032531, ja, nach der [doc] (http://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_last-insert-id), 'last_insert_id()' gibt die automatisch inkrementierte ID zurück. – Fabricator

+0

Ich schwor, ich habe gelesen, dass Sie das mit InnoDB nicht können, aber Ihre Lösung scheint zu funktionieren. Vielen Dank! Was ist der Grund für den eindeutigen Index für composite_pk2? – user1032531