Vous n'êtes pas identifié(e).
Pages : 1
Bonjour à tous,
C'est mon premier post ;-)
A l'occasion d'un développement, je découvre Postgresql et j'ai un problème avec les vues. J'ai besoin d'utiliser des vues modifiables composées de plusieurs tables. Lors d'un INSERT, il me faut alimenter une première table et ensuite une seconde avec la valeur (autoincrémentée) de la clé primaire de la première table.
En consultant les docs, j'ai bien compris qu'il faut définir une règle sur la vue, redéfinir le INSERT et exécuter deux requêtes (en les séparant par un ";"). Mais comment récupérer la valeur de la clé primaire de la première table pour le second INSERT ? Il y a bien RETURNING mais comment l'utiliser dans ce contexte ?
Merci d'avance pour votre aide
Olivier
Hors ligne
Si la valeur de la clé primaire est gérée automatiquement par une séquence, il est possible d'utiliser la fonction currval pour connaître la nouvelle valeur de la séquence, donc en fait la valeur du dernier élément inséré.
Guillaume.
Hors ligne
Merci pour cette réponse,
ok, mais cette technique ne peut elle pas poser de problèmes en cas d'accès multiples sur la première table ?
Lorsque 2 requêtes SQL sont lancées à la suite au sein d'une règle, leur exécution est-elle exclusive ? Supposons qu'une première requête sur la vue déclenche le INSERT, le code SQL (INSERT dans la la table A et INSERT (avec curval(seq_table_A)) dans la table B est lancé. Si durant ce laps de temps, une nouvelle requête INSERT est fait sur la table A, le résultat de curval(sql_table_A) ne risque t'il pas d'être erroné ? Faut il utiliser une transaction (BEGIN et COMMIT) autour des deux requêtes pour préserver leur contexte ?
Olivier ;-)
Hors ligne
Pour tester la solution currval(), j'ai écrit la règle suivante :
CREATE RULE insertEquipe AS ON INSERT TO listeequipes DO INSTEAD (
INSERT INTO equipes(cle,cle_theme,siteweb,description) VALUES(default,NEW.cle_theme,new.siteweb,NEW.description);
INSERT INTO noms(cle,cle_equipe,nom,debut) VALUES(default,CURRVAL('equipes_cle_seq'),NEW.nom,NEW.debut);
);
Le code SQL ne fonctionne pas. J'obtiens différents messages d'erreur qui semble provenir de la syntaxe de la règle.
Error : ERROR: syntax error at end of input
LINE 2: ...n) VALUES(default,NEW.cle_theme,new.siteweb,new.description)
^
Error : ERROR: NEW used in query that is not in a rule
Error : ERROR: syntax error at or near ")"
LINE 1: )
^
Pourtant dans le doc de Postgresql, il est bien écrit que l'on peut placer différentes commandes dans une règle.
CREATE [ OR REPLACE ] RULE nom as on evenement
TO table [ where condition ]
DO [ ALSO | INSTEAD ] { NOTHING | commande | ( commande ; commande ... ) }
Une idée ? merci d'avance
Olivier
PS: j'ai un serveur 8.3 (au cas où...)
Hors ligne
J'ai résolu mon problème. En fait, ce n'était pas la requête en elle-même mais Navicat. j'utilise ce logiciel pour travailler avec la base de données et c'est lui qui générait les messages d'erreur. Visiblement, il ne supporte pas plusieurs requêtes SQL dans la définition d'une règle.
Par contre, avec pgAdmin III, ça fonctionne parfaitement.
Olivier ;-)
Hors ligne
ok, mais cette technique ne peut elle pas poser de problèmes en cas d'accès multiples sur la première table ?
Lorsque 2 requêtes SQL sont lancées à la suite au sein d'une règle, leur exécution est-elle exclusive ? Supposons qu'une première requête sur la vue déclenche le INSERT, le code SQL (INSERT dans la la table A et INSERT (avec curval(seq_table_A)) dans la table B est lancé. Si durant ce laps de temps, une nouvelle requête INSERT est fait sur la table A, le résultat de curval(sql_table_A) ne risque t'il pas d'être erroné ? Faut il utiliser une transaction (BEGIN et COMMIT) autour des deux requêtes pour préserver leur contexte ?
Non l'exécution n'est pas exclusive mais ça ne change rien au résultat de currval('sequence') puisque c'est la valeur pour la session en cours.
@DanielVerite
http://blog-postgresql.verite.pro/
Hors ligne
Pages : 1