J'essaie d'envelopper toutes mes transactions qui devraient être tout-ou-rien dans J'ai 3 tables, une pour les images, une pour commencer code> et commettez code>, mais je ne sais pas comment faire cela dans Des cas comme les suivants. albums code>, et une pour les relations entre eux, nommément album_images code>. La manière dont le système fonctionne est qu'un utilisateur peut créer un album et le remplir avec ses images en une seule opération. Le SQL est le suivant: P> BEGIN;
INSERT INTO albums [...]; -- Create a new album row
SELECT id AS album_id FROM albums WHERE [...]; -- Get that rows ID
-- Now use album_id in the next statement
INSERT INTO album_images (album_id, image_id) [...];
COMMIT;
4 Réponses :
Postgres fournit une clause "retour" utilisée dans un insert pour récupérer facilement la clé primaire nouvellement créée. P>
http://www.postgresql.org/docs/8.3/ Interactive / sql-insert.html p>
Quelques exemples: http://6c62.net/blog/?p=48 p>
Merci, mais mon problème n'est pas tant d'obtenir cet identifiant, mais avec l'utiliser dans la prochaine déclaration. Que sélectionnez code> dans mon exemple est le code de travail réel qui retournera la bonne pièce d'identité. Ou ai-je mal compris quelque chose? Ces exemples sont un peu sur ma tête.
Lorsque j'essaie d'utiliser un retour nommé à l'intérieur d'une autre déclaration de la transaction, il jette une "colonne Unkknow" error ... Je ne pense pas que les variables thoses soient partagées dans la transaction.
Autre alternative à l'insert ... Clause de retour mentionnée par Cody, vous pouvez utiliser la valeur actuelle de la séquence associée à la colonne ID:
BEGIN; INSERT INTO albums [...]; INSERT INTO album_images (lastval(), image_id) [...]; COMMIT;
HM, les deux exemples produisent des erreurs de syntaxe à proximité ou à proximité "(" code> pour moi. Même si l'une d'entre elles fonctionnera finalement, je suppose qu'il n'ya aucun moyen d'utiliser la valeur de album_id Code> de mon Sélectionnez CODE>?
Est lastval code> spécifique à la transaction ou pourrait-il être modifié par une autre transaction simultanée?
C'est spécifique à la connexion i> (= session)
@a_horse_with_no_name Pour pouvoir renvoyer la valeur erronée si une autre (partage la connexion) insérée simultanément
@Tobiakinyemi: votre hypothèse est fausse. Utilisation de lastval () code> directement après une insertion est B> SA SA SA SA SA SA SA SAFE, tout comme en utilisant Curval () code> est. Si vous avez une application dans laquelle il est possible que certains code soient un insert et une autre partie effectue une insertion différente à l'aide de la même connexion physique avant que la première transaction ne soit appelée lastval () code> alors je soutiendrais que votre code est cassé. Mais même dans cette situation, Curval () Code> serait en sécurité supposant que les deux inserts utilisent des tables différentes.
Disons que deux utilisateurs s'inscrivent à votre site Web à exactement en même temps, que leurs transactions ne pouvaient-elles pas être entrecoupées - menant à des insertions corrompues en raison de la condition de race?
Ces deux transactions utiliseraient deux connexions physiques différentes. Vous ne pouvez pas avoir deux transactions indépendantes parallèles sur une seule connexion physique
Donc, lastval () code> est efficacement spécifique à la transaction (comme une seule transaction peut fonctionner par connexion)?
Non, c'est spécifique à la session. Il renvoie toujours la dernière valeur générée par une séquence. Si vous avez dix insertions dans dix tables, SlastVal retournera celui de l'insert final. S'il vous plaît lire le manuel, c'est tout expliqué là-bas
Donc, ce n'est pas robuste alors, comme cela pourrait renvoyer la mauvaise valeur ...
Si est B> robuste si vous l'utilisez correctement. C'est comme dire "Supprimer n'est pas robuste parce qu'il pourrait supprimer la mauvaise ligne"
Ce que nous voulons faire est de sélectionner l'identifiant spécifique juste inséré. Lastval est une mise en œuvre hacky, et est sujette à une erreur - simplement en ayant un autre insert simultané ... c'est pourquoi je dis que cela n'est pas robuste. La solution que j'ai affichée n'est pas sujette à ce problème et fonctionne en outre plus logiquement: var a_id = insert_a (...); insertion_a_b (a_id, ...) code> par opposition à insert_a (...); insertion_a_b (get_the_id_of_the_last_thing_inserted_on_this_con Nection (), ...) code>
Vous pouvez obtenir l'identifiant de la ligne insérée comme ceci renvoie l'album_id après l'insertion. p> p>
Plus précisément, l'OP souhaite d'utiliser le ID code> dans l'instruction suivante de la transaction. Le retour de la clause code> ne résout pas cela indépendamment.
L'accès manuel des séquences n'est pas idéal renvoyé code> a été utile, cependant, les 2 autres réponses ne savaient pas / expliquer comment l'appliquer ici < / p> p>
" Accessible manuellement des séquences n'est pas une solution robuste" i> - oui c'est.
@A_HORSE_WITH_NO_NAME a changé mon verbiage
Vous devez au moins supprimer le ; code> après la CTE pour faire une déclaration correcte.