Vous n'êtes pas identifié(e).
Merci Marc, grace à ces exemples j'ai pu arranger mon code pour que la fonction et le trigger se créé dans postgres
CREATE FUNCTION fonction_increment_crearticle() RETURNS TRIGGER AS $$
BEGIN
UPDATE LGPUSERNEW
SET NBARTICLECREE = NBARTICLECREE+1
WHERE nom=current_user;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER fonction_increment_crearticle AFTER INSERT ON lgpsujet
FOR EACH ROW EXECUTE PROCEDURE fonction_increment_crearticle();Pour info LGPSUJET est la table réelle, alors que ALLSUJET est une vue sur LGPSUJET
par contre quand je fais un INSERT dans ALLSUJET, j'ai le message d'erreur suivant :
ERREUR: le contrôle a atteint la fin de la procédure trigger sans RETURN
CONTEXTE : fonction PL/pgsql « fonction_increment_crearticle »
je n'ai toujours pas compris à quoi sert précisément RETURNS. ici j'ai pas besoin de RETURNS mais si j'en met pas la fonction ne veut pas s'enregistrer. j'ai essayé avec RETURNS NULL, mais ça veut pas non plus
personne ne veut m'aider pour mon trigger ?
![]()
Marchera pas
Je parierais plutôt sur quelque chose comme ça :
UPDATE LGPUSERNEW SET NBARTICLECREE = tmp.count FROM ( SELECT auteur, count(*) FROM ALLSUJET GROUP BY auteur ) tmp WHERE tmp.auteur = nom;
je n'avais pas pensé à cette façon de procéder
ça fonctionne impeccablement, merci
------------------------------------------
par contre concernant les trigger, je suis toujours au point mort, j'ai pas compris grand chose aux explications qui ont été données ci-dessus. un exemple de code qui fonctionne me serait vraiment d'un grand secours, sachant que je dois faire d'autres triggers, dont un bcp plus complexe
revoici mon code :
CREATE FUNCTION fonction_increment_crearticle()
BEGIN
UPDATE LGPUTILS
SET NBARTICLECREE = NBARTICLECREE+1
WHERE nom=current_user;
END;CREATE TRIGGER fonction_increment_crearticle AFERT INSERT ON allsujet
FOR EACH ROW EXECUTE PROCEDURE fonction_increment_crearticle();
ma requête est sensée :
- lire la vue ALLSUJET groupée par auteur
- compter le nombre de sujets pour chacun d'eux
- et updater la colonne NBARTICLECREE de la vue LGPUSERNEW pour chacun d'eux
j'ai modifié ma requête en suivant vos conseils et maintenant j'ai une autre erreur:
UPDATE LGPUSERNEW SET NBARTICLECREE =
(SELECT count(numsujet)
FROM ALLSUJET
WHERE auteur =
(SELECT distinct auteur
FROM ALLSUJET,LGPUSERNEW
WHERE nom=auteur)
GROUP BY auteur) ;ERREUR: plus d'une ligne renvoyée par une sous-requête utilisée comme une expression
autre tentative :
UPDATE LGPUSERNEW SET NBARTICLECREE =
(SELECT count(numsujet)
FROM ALLSUJET
WHERE auteur =
(SELECT distinct nom
from LGPUSERNEW)
GROUP BY auteur );ERREUR: plus d'une ligne renvoyée par une sous-requête utilisée comme une expression
je craque....
-----------------------------------
et pour le trigger, voila ce que j'ai essayé de faire :
incrémentation automatique du compteur NBARTICLECREE d'un utilisateur à chaque fois qu'il fait un nouvel insert dans la vue ALLSUJET
CREATE FUNCTION fonction_increment_crearticle() RETURNS ????
BEGIN
UPDATE LGPUSERNEW
SET NBARTICLECREE = NBARTICLECREE+1
WHERE nom=current_user;
END;CREATE TRIGGER fonction_increment_crearticle AFERT INSERT ON allsujet
FOR EACH ROW EXECUTE PROCEDURE fonction_increment_crearticle();
je n'ai pas trouvé de doc suffisamment explicite (en français) qui explique si je dois mettre un returns ou pas... je suis en plein brouillard !
merci pour votre aide
toujours sur mon projet scolaire "réalisez la BD pour un mini-wiki" j'approche du bout mais je bloque.... voici mes tables
table des utilisateurs
DROP TABLE LGPUTILS CASCADE;
CREATE TABLE LGPUTILS
(NUMUSER SERIAL,
NOM VARCHAR(25) PRIMARY KEY,
PASSWORD VARCHAR(25) NOT NULL,
NBARTICLECREE INTEGER DEFAULT '0'
);-- droits d'accès pour la séquence (SERIAL)
GRANT USAGE on lgputils_numuser_seq to public;--création d'une vue qui permet de voir tous les attributs de la table
DROP VIEW LGPUSERNEW;
CREATE VIEW LGPUSERNEW AS SELECT * FROM LGPUTILS;grant select on LGPUSERNEW to public;
grant insert on LGPUSERNEW to public;
grant update on LGPUSERNEW to public;-- création d'une règle sur la vue "LGPUSERNEW"
-- permettant l'insertion de nouveaux utilisateurs avec automatisme : nom = compte utilisateur
DROP RULE usernew_insert on LGPUSERNEW CASCADE;
CREATE RULE usernew_insert AS ON INSERT TO LGPUSERNEW DO INSTEAD
INSERT INTO LGPUTILS VALUES
(default,
current_user,
NEW.PASSWORD);
table des sujets publiés :
DROP TABLE LGPSUJET CASCADE;
CREATE TABLE LGPSUJET
(NUMSUJET SERIAL PRIMARY KEY,
AUTEUR VARCHAR(25) REFERENCES LGPUTILS (NOM),
TITRE VARCHAR NOT NULL,
DATEPARUTION DATE DEFAULT current_date,
DATEMODIF DATE DEFAULT current_date,
AUTEURMODIF VARCHAR(25) REFERENCES LGPUTILS (NOM),
NUMBACKUP INTEGER DEFAULT '1',
NBVUE INTEGER DEFAULT '0',
TEXTE VARCHAR NOT NULL,
PROTECTION INTEGER DEFAULT '1' );-- droits d'accès pour la séquence (SERIAL)
GRANT USAGE on lgpsujet_numsujet_seq to public;-- création d'une vue qui permet de voir tous les sujets de la table
CREATE VIEW ALLSUJET AS SELECT * FROM LGPSUJET;
grant select on ALLSUJET to public;
grant insert on ALLSUJET to public;-- création d'une règle qui permet l'insertion de nouveaux sujets à travers la vue ALLSUJET
DROP RULE sujet_insert ON ALLSUJET;
CREATE RULE sujet_insert AS ON INSERT TO ALLSUJET DO INSTEAD
INSERT INTO LGPSUJET (auteur, titre, texte) VALUES
(current_user,
NEW.TITRE,
NEW.TEXTE);-- règle pour update du compteur "nbre d'article créés"
DROP RULE cpt_update on LGPUSER CASCADE;
CREATE RULE cpt_update AS ON UPDATE TO LGPUSERNEW
DO INSTEAD
UPDATE LGPUTILS
SET nbarticlecree= NEW.nbarticlecree
WHERE nom = old.nom;
______________________________________
Problème n°1 :
impossible de faire foncitonne ma requete ci-dessous, j'ai une erreur sur le WHERE de la ligne n°5 et je ne comprend pas pourquoi...
-- requete de mise à jour générale du compteur "nbre d'article créés"
-- en cas de suppression d'article
-- vues utilisées : LGPUSERNEW + ALLSUJET
UPDATE LGPUSERNEW SET NBARTICLECREE =
(SELECT count(auteur), nom
FROM ALLSUJET
GROUP BY auteur
WHERE auteur =
(SELECT distinct auteur
FROM ALLSUJET,LGPUSERNEW
WHERE nom=auteur) ) ;
Problème n°2 :
j'ai un trigger à faire dans lequel je dois mettre la requête ci-dessous
-- requete d'incrémentation du compteur "nbre d'article créés"
-- a insérer dans un trigger de type "after" se déclenchant après nouvel INSERT dans ALLSUJET
UPDATE LGPUSERNEW
SET NBARTICLECREE = NBARTICLECREE+1
WHERE nom=current_user;
Le soucis est qu'on a fait 2h sur les triggers sous Oracle, mais pas du tout sous Postgres, d'après ce que j'ai vu sur les forums la syntaxe est radicalement différente (fonction + trigger), j'ai essayé de le faire mais j'arrive à rien... suite à ça j'ai 2 autres triggers plus complexes à faire, un modèle serait bienvenu pcq là, je patauge royalement et la date de remise du projet avance à grand pas ![]()
merci d'avance pour votre aide
merci bcp pour cette lumineuse explication, j'essayerais ça demain car là, j'ai les paupières qui tombent ^^
EDIT : ça fonctionne nickel, encore merci
sujet clos
suite de mon mini-wiki sous postgres
table des utilisateurs :
DROP TABLE LGPUTILS CASCADE;
CREATE TABLE LGPUTILS
(NUMUSER SERIAL,
NOM VARCHAR(25) PRIMARY KEY,
PASSWORD VARCHAR(25) NOT NULL,
NBARTICLECREE INTEGER DEFAULT '0'
);-- droits d'accès pour la séquence (SERIAL)
GRANT USAGE on lgputils_numuser_seq to public;--création d'une vue qui permet de voir tous les attributs de la table
DROP VIEW LGPUSERNEW;
CREATE VIEW LGPUSERNEW AS SELECT * FROM LGPUTILS;grant select on LGPUSERNEW to public;
grant insert on LGPUSERNEW to public;
grant update on LGPUSERNEW to public;-- création d'une règle sur la vue "LGPUSERNEW"
-- permettant l'insertion de nouveaux utilisateurs avec automatisme : nom = compte utilisateur
DROP RULE usernew_insert on LGPUSERNEW CASCADE;
CREATE RULE usernew_insert AS ON INSERT TO LGPUSERNEW DO INSTEAD
INSERT INTO LGPUTILS VALUES
(default,
current_user,
NEW.PASSWORD);
table des sujets
DROP TABLE LGPSUJET CASCADE;
CREATE TABLE LGPSUJET
(NUMSUJET SERIAL PRIMARY KEY,
AUTEUR VARCHAR(25) REFERENCES LGPUTILS (NOM),
TITRE VARCHAR NOT NULL,
DATEPARUTION DATE DEFAULT current_date,
DATEMODIF DATE DEFAULT current_date,
AUTEURMODIF VARCHAR(25) REFERENCES LGPUTILS (NOM),
NUMBACKUP INTEGER DEFAULT '1',
NBVUE INTEGER DEFAULT '0',
TEXTE VARCHAR NOT NULL,
PROTECTION INTEGER DEFAULT '1'
);-- droits d'accès pour la séquence (SERIAL)
GRANT USAGE on lgpsujet_numsujet_seq to public;-- création d'une vue qui permet de voir tous les sujets de la table
CREATE VIEW ALLSUJET AS SELECT * FROM LGPSUJET;grant select on ALLSUJET to public;
grant insert on ALLSUJET to public;
l'idée est que lorsque un utilisateur créé un sujet l'insert se fait à travers une vue "ALLSUJET", la requete se présente sous cette forme :
INSERT INTO LGPSUJET (TITRE,TEXTE)
VALUES ('test-creation','texte muet');
- le n° de sujet est automatique avec la fonction "serial"
- le nom de l'auteur est automatique avec la fonction "current_user"
- les dates de parution et de modification prennent automatiquement la date du jour (DEFAULT current_date)
j'essaye donc de créer ma vue "ALLSUJET" :
DROP RULE sujet_insert ON ALLSUJET;
CREATE RULE sujet_insert AS ON INSERT TO ALLSUJET DO INSTEAD
INSERT INTO LGPSUJET VALUES
(default,
current_user,
NEW.TITRE,
NEW.TEXTE);
et là, c'est le drame :
ERREUR: la colonne « dateparution » est de type date mais l'expression est de type character varying
LIGNE 6 : NEW.TEXTE);
^
ASTUCE : Vous devez réécrire l'expression ou lui appliquer une transformation de type.
je ne comprend pas du tout l'erreur...
par acquis de conscience j'ai fait un test d'insert directement dans la table et ça fonctionne très bien :
INSERT INTO LGPSUJET (TITRE,TEXTE) VALUES ('test-creation','texte muet');
select * from lgpsujet;
numsujet | auteur | titre | dateparution | datemodif | auteurmodif | numbackup | nbvue | texte | protection
----------+--------+---------------+--------------+------------+-------------+-----------+-------+------------+------------
1 | | test-creation | 2012-01-07 | 2012-01-07 | | 1 | 0 | texte muet | 1
galère galère... ![]()
yesss, super, ça fonctionne, problème 2 résolu
un grand merci à toi ![]()
Pour mon projet je suis sensé passer à 100% par des vues pour toutes actions insert/update sur mes tables, ça fait parti du cahier des charges ![]()
j'ai suivi tes conseils et supprimé le doublon de règle, maintenant j'ai uniquement :
DROP RULE usernew_insert on LGPUSERNEW CASCADE;
CREATE RULE usernew_insert AS ON INSERT TO LGPUSERNEW DO INSTEAD
INSERT INTO LGPUTILS VALUES
(default,
current_user,
NEW.PASSWORD);
- Avec compte admin créateur des tables -
INSERT INTO LGPUSERNEW (password) VALUES ('testSansNom');
insert à travers la vue LGPUSERNEW sans préciser ni le n° d'utilisateur (incrémentation auto avec SERIAL) ni le nom d'utilisateur
ça marche, merci, un premier prb de réglé ![]()
- Avec compte userA -
INSERT INTO LGPUSERNEW (password) VALUES ('testSansNom');
ERREUR: droit refusé pour la séquence lgputils_numuser_seq
ça refuse de marcher, il semble que l'incrémentation automatique de numuser pose problème.... je ne comprend tjrs pas pourquoi
- Avec compte userA -
INSERT INTO LGPUSERNEW (nom,password) VALUES ('userA','PASS');
ERREUR: droit refusé pour la séquence lgputils_numuser_seq
même en précisant le nom d'utilisateur dans la requete, pas moyen de faire un insert
- Avec compte userA -
INSERT INTO LGPUSERNEW VALUES (1,'userA','PASS');
ERREUR: droit refusé pour la séquence lgputils_numuser_seq
même en précisant le numuser, pas moyen que ça marche
Bonjour à tous et meilleurs voeux
j'ai un projet à réaliser : un mini-wiki sans application, juste les tables à créer, faire les vues et les grants
voici ma table "comptes utilisateurs" créée avec le compte administrateur, sachant qu'après elle est sensée être utilisée par 3 comptes userA, userB et userC :
DROP TABLE LGPUTILS CASCADE;
CREATE TABLE LGPUTILS
(NUMUSER SERIAL PRIMARY KEY,
NOM VARCHAR(25) NOT NULL,
PASSWORD VARCHAR(25) NOT NULL,
NBARTICLECREE INTEGER DEFAULT '0'
);-- droits d'accès
grant select on LGPUTILS to public;
grant insert on LGPUTILS to public;
grant update on LGPUTILS to public;--création d'une vue qui permet de voir tous les attributs de la table
DROP VIEW LGPUSERNEW;
CREATE VIEW LGPUSERNEW AS SELECT * FROM LGPUTILS;
select * from LGPUSERNEW;grant select on LGPUSERNEW to public;
grant insert on LGPUSERNEW to public;
grant update on LGPUSERNEW to public;-- EDIT : doublon de règles supprimé suite à l'intervention de dverite
-- création d'une règle sur la vue "LGPUSERNEW" permettant l'insertion de nouveaux utilisateurs
-- avec attribut "nom" automatique en fonction du compte utilisateur qui fait l'insertion
DROP RULE usernew_insert2 on LGPUSERNEW CASCADE;
CREATE RULE usernew_insert2 AS ON INSERT TO LGPUSERNEW DO INSTEAD
INSERT INTO LGPUTILS VALUES
(default,
current_user,
NEW.PASSWORD);
**********************
EDIT : problème 1 résolu
Probleme 1:
avec le compte admin, pas de souci pour insérer dans la table les nouveaux "utilisateurs", du moment que je précise la colonne "nom"
ex : INSERT INTO LGPUTILS (nom,password) VALUES ('user1','PASS');
par contre ma règle usernew_insert2 refuse de fonctionner. pourtant la règle a bien été crée sans erreur.
ex : INSERT INTO LGPUSERNEW (password) VALUES ('pass');
>> ERREUR: une valeur NULL viole la contrainte NOT NULL de la colonne « nom »
**********************
Probleme 2:
à partir du compte utilisateur "userA", je parviens sans soucis à faire un select sur la table LGPUTILS et la vue LGPUSERNEW.
par contre quand j'essaye de faire un INSERT dans la table LGPUTILS ou dans la vue LGPUSERNEW ça ne marche qu'à moitié :
- si j'insère dans la table LGPUTILS en précisant le "numuser" ça marche :
INSERT INTO LGPUTILS VALUES (1,'userA','PASS');
- si j'insère dans la vue LGPUSERNEW en précisant le "numuser" ça ne marche pas :
INSERT INTO LGPUSERNEW VALUES (1,'userA','PASS');
ERREUR: droit refusé pour la séquence lgputils_numuser_seq
- si je ne précise pas le numuser (il est sensé se mettre tout seul avec la fonction SERIAL), ça ne marche pas non plus :
INSERT INTO LGPUTILS (nom,password) VALUES ('userA','PASS');
ERREUR: droit refusé pour la séquence lgputils_numuser_seq
je ne comprend pas, un petit coup de main serait bienvenu.
super, ça fonctionne, un grand merci ^^
depuis ma chambre d'étudiant, je passe par une Livebox en DHCP.
je doit déclarer donc déclarer l'adresse IP internet de la box dans mon fichier pg_hba.conf ?
comme ceci ? :
host all all IP-de-la-box-de-ma-chambre-etudiant md5
est-ce que je devrais aussi paramétrer la box de ma chambre d'étudiant pour router le port 5432 ?
effectivement, je n'ai pas créé d'utilisateurs et quand je me suis connecté sous windows j'ai utilisé le log postgres
je n'ai pas non plus créé de base spécifique, ya juste une base nommée postgres dont voici le détail :
CREATE DATABASE postgres
WITH OWNER = postgres
ENCODING = 'UTF8'
TABLESPACE = pg_default
LC_COLLATE = 'French, France'
LC_CTYPE = 'French, France'
CONNECTION LIMIT = -1;
COMMENT ON DATABASE postgres
IS 'default administrative connection database';
------------------
voila ce que donne le code que vous m'avez indiqué sur ma VM-Fedora :
[morby@VM-Fedora ~]$ psql -h 192.168.1.11 -U postgres
psql: FATAL: aucune entre dans pg_hba.conf pour l'hte 192.168.1.11 , utilisateur postgres ,
base de donnes postgres , SSL inactif
ou encore :
[morby@VM-Fedora ~]$ psql -h 192.168.1.11 -U postgres postgres
psql: FATAL: aucune entre dans pg_hba.conf pour l'hte 192.168.1.11 , utilisateur postgres ,
base de donnes postgres , SSL inactif
![]()
merci pour cette réponse rapide, adresse IP masquée ![]()
au niveau local, mon Win7 arrive à pinger l'adresse IP virtuelle de la VM en 127.0.0.1
de meme ma VM arrive à pinger l'IP locale de mon win7 en 192.3168.1.11
pour ce qui est de l'ouverture de ports sur mon routeur/firewall pour permettre la connexion extérieure, je suppose que je dois ouvrir en UDP+TCP le port 5432 ?
par contre je ne sais tjrs pas ce que je dois taper sous linux pour tenter d'établir la connexion à la base !
quand je veux me connecter sur le serveur de l'université je tape :
> ssh u0@bambou.xxxxxxxxxxxxxxxx.fr
ensuite on me demande un password et j'ai un prompt de type : u0@db:~$
ensuite je tape :
> psql template1
on me redemande un password, et là je peux commencer à bosser....
quelle adresse dois-je rentrer pour me connecter en locale, ou bien depuis l'extérieur ?
bonjour à tous, je suis étudiant (formation de reconversion), débutant complet en SGBD. D'habitude je travaille sur le serveur de l'université, mais pas mal de fonctions sont verrouillées, et pour les besoins d'un projet j'ai besoin d'avoir mon propre serveur afin de pouvoir créer des utilisateurs, faire des grant, etc...
Chez moi j'ai installé Postgres 9.1 (pgAdmin 1.14.1) sur mon PC fixe Windows 7, je peux m'y connecter avec l'outil SQL Shell, créer une table etc... ça fonctionne. Pour mes cours je travaille sous Linux Fedora (15), lequel tourne sous Virtualbox 4.1.8 sur ce même ordi, mais aussi sur un ordi portable
MON PROBLEME : sur mon PC fixe, pas moyen depuis ma VM-Fedora de me connecter à la base qui, elle, tourne sous le Windows natif.
Quelle adresse dois-je taper en console linux pour me connecter ?
ma config Windows 7 :
IP Internet : xxxxxxxxxx
IP locale 192.168.1.11
masque : 255.255.255.0
ma config pg_hba.conf :
# TYPE DATABASE USER ADDRESS METHOD
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
#host replication postgres 127.0.0.1/32 md5
#host replication postgres ::1/128 md5
sur ce même PC, ma config Fedora 15 qui tourne en parallèle sous virtualbox :
IP : 127.0.0.1
masque : 255.0.0.0
paquet "psql" installé
Autre cas de figure : la semaine je bosse sur un PC portable depuis ma chambre d'étudiant, lui aussi sous Win7 avec une Fedora15 qui tourne sous virtualbox. Quelle adresse devrais-je rentrer pour me connecter à ma base qui tournera chez moi ?
j'ai conscience que ces question peuvent paraitre hautement stupides, mais quand on débute et qu'on est pas anglophone, c'est pas facile de trouver l'info, surtout sur des prbs aussi basiques...