transaktionen und rückgabewerte

HI Leute,

ich programmier mit PHP und pg und versuch nun grad eine Transaktion durchzuführen, die zuerst etwas inserted und dann einen select macht um die neue Laufendenummer zurückzugeben.

“BEGIN;
insert into a (…)values(…);
select currval(a_sequenz);
COMMIT;”

wollte nun das result weiterverwenden… klappt nur nicht, wenn ich das Begin, Commit entferne funktionierts wieder gut. Woran könnte es liegen das das nicht mehr klappt?

Danek für eure Mühe!
Crypi

Ehrliche Antwort:
Die hast Transaktionen und deren Zusamenhänge noch nicht richtig verstanden!

Lösung:
Führe den Befehl "select currval(a_sequenz)]http://www.postgresql.org/docs/books/pghandbuch.html.de[/url]


mfg

fristo

Der Sinn steck doch darin zu garantieren, dass zwischen meinen Befehlen keine anderen ausgeführt werden oder nicht? Ich weiß dsa es klappt wenn ich den select nach das Kommit schreibe aber ist damit auch garantiert, das es wirklich die aktuelle Nummer ist?

Crypi
ps: den link kenne ich

hi,

mal ne dumme frage: du schreibst doch den datensatz in die datenbank => du hast alle infos und kannst den datensatz direkt wieder selektieren (stichwort: primary_key bzw. keys).

wieso selektiert du nicht einfach die id des datensatzen und selektierst als WHERE kriterium nach den eingefügten werten?

damit solltest du das problem umgehen, die richtige id erhalten und eine transaktion funktioniert auch (wobei die in deinem fall imo blödsinn ist).

cu tb.

Erkläre doch mal, wann Du “Laufendenummer” benötigst, während der Transaktion oder nach der Transaktion, und was Du mit “Laufendenummer” machst.



mfg

fristo

@xandrian: deinen post versteh ich nciht, ich soll alle anderen attribute selecten?beziehst du dich auf meinen anderen eintrag?


die laufendenummer wird beim insert erzeugt, diese soll dann zurück geliefert werden damit ich sie in meiner oberfläche(php) weiter verwenden kann. meine sorge ist, dass der unwahrscheinliche fall eintritt, dass nach meinem insert jemadn anders insertet und ich ne falsche laufendenummer zurück bekomme.

Crypi

hi,

nein ich bin schon richtig :wink:

du schreibt einen datensatz in die datenbank. dieser bekommt eine id die du weiter verwenden möchtest. da es ja u.u. probleme mit den curval geben könnte (wie du ja selbst geschrieben hast), was spricht dagegen, die id direkt aus der tabelle zu selektieren, auf die der insert geht? du machst also praktisch ein

SELECT id FROM a WHERE …

und nimmst als WHERE die daten die du gerade eingegeben hast. dann sollte das doch auch gehen.

jetzt verstanden was ich mein?

cu tb

btw: das buch gibt es auch hier im online shop… http://pg-forum.de/shop.php?id=251&action=detail&asin=3826613376 :wink:

naja bedingt, könnte ja sein das genau die gleochen daten schon einmal eingegeben wurden… ok unwahrscheinlich aber wer weiß.

warum geht denn das nicht? kannst du mir das erklären?

Crypi

was spricht eigentlich gehen folgende lösung (verfasst in pseudo code):

beginne transaktion;
$new_id = SELECT nextval('sequenz');
INSERT INTO a(...) VALUES($new_id, ...);
...
COMMIT; bzw. ROLLBACK;

{weiter arbeiten mit $new_id}

und wech… cu tb.

hab das jetzt anders gelöst.

ich hab alles was die laufendenummer brauchte in eine Transaktion gepackt. werd jetzt in der oberfläche ohne sie auskommen.


Danke für eure Hilfe!

Crypi

Der fehlende Rückgabewert liegt daran, dass die Rückgabe aus dem letzten Statement kommt, dem COMMIT;

Du solltest die Statements also getrennt absetzen.

Erst BEGIN;

dann die Abfragen, deren Ergebnisse Du speichern kannst
dann kannst Du z.B. schauen, ob eine der Abfragen in die Hose gegangen ist und setzt nach Bedarf

COMMIT; oder ROLLBACK; ab

Anschließend kannst Du mit den oben genannten Rückgabewerten arbeiten. Das ist zwar etwas mehr Aufwand, gibt Dir aber mehr Kontrolle über das, was Du machst.

Für Sequenzen braucht man gar keine Transaktionen, curr_val() bezieht sich sowieso auf die zuletzt innerhalb dieser Session generierte ID, egal, wieviele andere Leute noch Sequenznummern verbraucht haben.

Wenn man mit MAX() die ID sucht, muss man allerdings die Tabelle locken oder eine Transaktion verwenden, um die Änderungen abzukapseln …