MYSQL5 Insert Duplicate Key trotzdem ID Bekommen?
baeckerman83
- datenbank
1 dedlfix
Hiho!
Ich bin gerade dabei eine Procedure zu schreiben. Diese soll mir einen Namen in die Datenbank schreiben und die ID des Namen ausgeben. Wenn der Name noch nicht in der Datenbank steht funktioniert es schon. Mein Problem ist jetzt wie komme ich an die ID wenn der Name schon in der Datenbank steht.
Das hier habe ich, scheint mir aber nicht sinnvoll und geht auch nicht. Ich denke mal da gibts was einfaches, mir fehlen nur die richtigen Begriffe.
CREATE PROCEDURE p\_insert\_name
(name varchar(100))
BEGIN
insert ignore into speicher(speicher_name) VALUE (name);
SELECT LAST_INSERT_ID() as id_eintrag;
IF id_eintrag=0 THEN
SELECT id_speicher as id_eintrag from speicher WHERE speicher_name like name;
END IF;
END
Tach!
Ich bin gerade dabei eine Procedure zu schreiben. Diese soll mir einen Namen in die Datenbank schreiben und die ID des Namen ausgeben. Wenn der Name noch nicht in der Datenbank steht funktioniert es schon. Mein Problem ist jetzt wie komme ich an die ID wenn der Name schon in der Datenbank steht.
Man kann in Stored Procedures mit Condition Handling auf Fehler reagieren. Da könntest du auf den Dupliate Key testen und reagieren. Das ist aber in deinem Fall nicht nötig, denn LAST_INSERT_ID() liefert mit 0 einen auswertbaren Wert, wenn das Insert nichts neues hinzugefügt hat.
CREATE PROCEDURE
p\_insert\_name
(name varchar(100))
BEGIN
insert ignore into speicher(speicher_name) VALUE (name);
SELECT LAST_INSERT_ID() as id_eintrag;
IF id_eintrag=0 THEN
Es würde mich wundern, wenn id_eintrag derart genutzt werden kann. SELECT liefert eine Menge mit 0 bis mehreren Datensätzen, id_eintrag müsste eigentlich eine ganze Spalte sein. Aber das IF will einen Einzelwert haben. Ob es wirklich auf den einen Wert einer einzeiligen Ergebnismenge zugreift statt eine nicht vorhandene Variable anzumeckern? (Wobei ich mich hier irren kann, ich hab noch nicht viel mit Stored Procedures gearbeitet.) Ich würde zuerst mit IF LAST_INSERT_ID()=0 prüfen und dann ent-oder-weder weitermachen.
SELECT id_speicher as id_eintrag from speicher WHERE speicher_name like name;
Du willst ja keine ungefähre Übereinstimmung sondern eine exakte, also nimm keinen Joker-Vergleich sondern einen mit =
END IF;
END
Dein eigentliches Problem dürfte das Resultset im Ignore-Fall sein, denn das besteht aus dem Ergebnis beider SELECTs, ist als ein multiples Resultset, das man beim Abfragen gesondert behandeln muss. Du musst dafür sorgen, dass in jedem Fall nur ein SELECT zur Ausführung gelangt. Alle anderen können zwar stattfinden, müssen aber ihr Ergebnis INTO eine Variable abliefern.
Ich würde ja eine Function statt einer Procedure nehmen, wenn das Ergebnis nur aus einem Wert, nämlich der ID, bestehen soll. Das kann man gezielt mit RETURN zurückgeben und muss nicht bis zum Statement-Ende noch ungewollte Resultsets ansammeln.
dedlfix.
Danke für deine Antwort diese hat mir geholfen und ich habe es jetzt. :)