Vous n'êtes pas identifié(e).
Pages : 1
Bonjour,
Je souhaiterais faire des "insert" sur une vue que j'ai créée auparavant.
Pour cela, j'ai crée une régle ON INSERT sur la vue :
CREATE RULE new10 AS ON INSERT TO BDALK_V75 DO insert into BDALK_V75 (T237_ID, CONTRIB_ID, CONTRIB_PWD, T237_DATE) values (10, 1, 'mdpoi', now())
Jusqu'ici tout se passe bien, la regle s'est correctement ajoutée.
Mon problème : comment utiliser cette régle ?
J'ai essayé : INSERT INTO BDALK_V75 (T237_ID, CONTRIB_ID, CONTRIB_PWD, T237_DATE) VALUES (22, 33, 'mmm', now()) mais il y a un message d'erreur : récursion indéfinie détectée. J'ai pas très bien compris l'utilisation des règles, je crois.
Pouvez vous m'éclaircir ce point ?
Hors ligne
La règle permet de dire que, si le moteur intercepte un INSERT sur la vue, l'INSERT doit se faire sur la table. Donc, la requête de création de la règle devrait plutôt être :
CREATE RULE new10 AS ON INSERT TO nom_de_la_vue DO insert into nom_de_la_table (col1_table, col2_table, col3_table) values (col_vue_correspondant_a_col1_table, col_vue_correspondant_a_col2_table, col_vue_correspondant_a_col3_table)
Guillaume.
Hors ligne
Ah ok, je comprend mieux. C'est vrai, c'est logique. La vue est une table virtuelle,
Hors ligne
par contre je n'ai aucun moyen de savoir a l'avance les tables concernées par la vue.
Y aurait il un moyen de connaitre les colonnes uniquement grace à une vue ?
Hors ligne
J'avoue que je ne comprends pas votre question. Vous pouvez détailler un peu votre cas d'utilisation ?
Guillaume.
Hors ligne
voila : j'ai une vue (avec des jointures sur plusieurs tables) et quand je l'execute j'obtiens une table avec des informations.
Ensuite a partir de cette table virtuelle, je souhaiterais y rajouter des informations comme un insert sur une table virtuelle
Hors ligne
On peut écrire plusieurs règles INSTEAD sur in INSERT, un UPDATE, un DELETE sur une vue :
http://www.postgresql.org/docs/8.3/inte … pdate.html (voir surtout la note de bas de page de Jamie Pate, que je trouve très pertinente)
Marc.
Hors ligne
J'ai compris cette règle en bas de page.
Mais ça ne résoud pas mon problème : en fait je veux pouvoir faire un insert sur un vue.
Je me suis dit qu'il était peut être possible de le faire avec les règles.
Avez vous une idée ?
Hors ligne
C'est ce qu'explique la règle en bas de page : comment faire des règles sur une vue comportant des jointures
Marc.
Hors ligne
La règle permet de dire que, si le moteur intercepte un INSERT sur la vue, l'INSERT doit se faire sur la table. Donc, la requête de création de la règle devrait plutôt être :
JE CROYAIS QU'ON POUVAIT PAS FAIRE DE INSERT SUR UNE VUE ????CREATE RULE new10 AS ON INSERT TO nom_de_la_vue DO insert into nom_de_la_table (col1_table, col2_table, col3_table) values (col_vue_correspondant_a_col1_table, col_vue_correspondant_a_col2_table, col_vue_correspondant_a_col3_table)
Hors ligne
On peut faire des insert sur une vue à condition d'avoir une règle qui remplace cet insert par un insert dans la bonne table.
Guillaume.
Hors ligne
Ok, mais pour déclencher l'événement.
Il faut que l'événement déclencheur de la règle soit correcte.
Syntaxiquement, insert into TABLE_VIEW_NAME .... => provoque une erreur, donc le moteur ne pourra pas détecter la règle.
Hors ligne
Avez-vous testé ?
Voici un exemple concret qui montre que cela fonctionne :
guillaume@laptop:~$ psql postgres
psql (8.4rc1)
Saisissez « help » pour l'aide.
postgres=# create database yenfou2000;
CREATE DATABASE
postgres=# \c yenfou2000
psql (8.4rc1)
Vous êtes maintenant connecté à la base de données « yenfou2000 ».
yenfou2000=# create table t1 (id serial, contenu text);
NOTICE: CREATE TABLE créera des séquences implicites « t1_id_seq » pour la colonne serial « t1.id »
CREATE TABLE
yenfou2000=# insert into t1 (contenu) values ('ligne 1'), ('ligne 2');
INSERT 0 2
yenfou2000=# select * from t1;
id | contenu
----+---------
1 | ligne 1
2 | ligne 2
(2 lignes)
yenfou2000=# create view v1 as select * from t1;
CREATE VIEW
yenfou2000=# select * from v1;
id | contenu
----+---------
1 | ligne 1
2 | ligne 2
(2 lignes)
yenfou2000=# insert into v1 (contenu) values ('ligne 3');
ERREUR: ne peut pas insérer dans une vue
ASTUCE : Vous avez besoin d'une règle ON INSERT DO INSTEAD.
yenfou2000=# create rule insertv1 as on insert to v1 do instead insert into t1 values (default, new.contenu);
CREATE RULE
yenfou2000=# insert into v1 (contenu) values ('ligne 3');
INSERT 0 1
yenfou2000=# select * from t1;
id | contenu
----+---------
1 | ligne 1
2 | ligne 2
3 | ligne 3
(3 lignes)
yenfou2000=# select * from v1;
id | contenu
----+---------
1 | ligne 1
2 | ligne 2
3 | ligne 3
(3 lignes)
Guillaume.
Hors ligne
Ok, cette exemple fonctionne bien, je pense pouvoir l'adapter a mon application.
Par contre, je comprend la fin de la regle :
create rule insertv1 as on insert to v1 do instead insert into t1 values (default, new.contenu);
Pk default ? Quel l'utilité du "new".
Hors ligne
Pk default ?
Parce que la colonne id est une colonne autoincrémentée sur la table. Je préfère garder ça. Maintenant, il est tout à fait possible d'indiquer NEW.id.
Quel l'utilité du "new"
NEW est le nom de la pseudo ligne à insérer. NEW.contenu correspond donc à la valeur fournie dans la clause VALUES du INSERT.
Guillaume.
Hors ligne
Pk default ?
Parce que la colonne id est une colonne autoincrémentée sur la table. Je préfère garder ça. Maintenant, il est tout à fait possible d'indiquer NEW.id.
Quel l'utilité du "new"
NEW est le nom de la pseudo ligne à insérer. NEW.contenu correspond donc à la valeur fournie dans la clause VALUES du INSERT.
Ok je comprend mieux merci
A la place de "default" est qu'on peut utiliser nextID de la sequence correspondante ? car toutes mes primary key sont basées sur des sequences. ?
Hors ligne
À priori oui. Mais le mot clé default fait la même chose. Ma colonne ID a comme valeur par défaut le résultat du nextval de la séquence associée.
Guillaume.
Hors ligne
Pages : 1