[postgres] Contrainte d'intégrité sur nombre de tuples
7 réponses
Christophe CLEMENT
Bonjour,
Imaginons qu'on ait la table :
CREATE TABLE bidon(
ref INTEGER,
a INTEGER
);
Comment faire - en postgreSQL - pour ajouter une contrainte qui vérifie
qu'il y a au plus 3 tuples (lignes) dans la table qui ont la même
valeur de ref ?
J'ai essayé avec une assertion mais ça n'est pas encore implémenté :-(
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Jean-Paul Argudo
Christophe CLEMENT wrote:
Bonjour,
Bonjour!
Imaginons qu'on ait la table :
CREATE TABLE bidon( ref INTEGER, a INTEGER );
Comment faire - en postgreSQL - pour ajouter une contrainte qui vérifie qu'il y a au plus 3 tuples (lignes) dans la table qui ont la même valeur de ref ?
Je pense qu'en PostgreSQL comme dans d'autres SGBDR qui se respectent, vous pouvez faire cela avec un trigger.
Voilà comment je ferais pour ma part (v.8.x.x à cause des $ dans le plpgsql):
CREATE TABLE test ( ref integer, b integer );
CREATE FUNCTION test_tripl() RETURNS trigger AS $test_stamp$ DECLARE compte integer; BEGIN
select count(*) into compte from test where ref = NEW.ref;
-- vous êtes en trigger BEFORE soit =3 ou plus... if compte>=3 then RAISE EXCEPTION 'pas plus de 3 tuples avec ref= %', NEW.ref; END IF;
RETURN NEW; END; $test_stamp$ LANGUAGE plpgsql;
CREATE TRIGGER test_stamp BEFORE INSERT OR UPDATE ON test FOR EACH ROW EXECUTE PROCEDURE test_tripl();
tests=# insert into test values (1,1); INSERT 2665136 1 tests=# insert into test values (1,2); INSERT 2665137 1 tests=# insert into test values (1,3); INSERT 2665138 1 tests=# insert into test values (1,4); ERROR: pas plus de 3 tuples avec ref= 1
Voilà... :-)
NB: ne me remerciez pas trop, mais plutôt les gens qui se cassent la tête à écrire de docs, et à ceux qui font pareil pour les traduire
Comment faire - en postgreSQL - pour ajouter une contrainte qui vérifie
qu'il y a au plus 3 tuples (lignes) dans la table qui ont la même
valeur de ref ?
Je pense qu'en PostgreSQL comme dans d'autres SGBDR qui se respectent, vous
pouvez faire cela avec un trigger.
Voilà comment je ferais pour ma part (v.8.x.x à cause des $ dans le
plpgsql):
CREATE TABLE test (
ref integer,
b integer
);
CREATE FUNCTION test_tripl() RETURNS trigger AS $test_stamp$
DECLARE
compte integer;
BEGIN
select count(*) into compte
from test
where ref = NEW.ref;
-- vous êtes en trigger BEFORE soit =3 ou plus...
if compte>=3 then
RAISE EXCEPTION 'pas plus de 3 tuples avec ref= %', NEW.ref;
END IF;
RETURN NEW;
END;
$test_stamp$ LANGUAGE plpgsql;
CREATE TRIGGER test_stamp BEFORE INSERT OR UPDATE ON test
FOR EACH ROW EXECUTE PROCEDURE test_tripl();
tests=# insert into test values (1,1);
INSERT 2665136 1
tests=# insert into test values (1,2);
INSERT 2665137 1
tests=# insert into test values (1,3);
INSERT 2665138 1
tests=# insert into test values (1,4);
ERROR: pas plus de 3 tuples avec ref= 1
Voilà... :-)
NB: ne me remerciez pas trop, mais plutôt les gens qui se cassent la tête à
écrire de docs, et à ceux qui font pareil pour les traduire
Comment faire - en postgreSQL - pour ajouter une contrainte qui vérifie qu'il y a au plus 3 tuples (lignes) dans la table qui ont la même valeur de ref ?
Je pense qu'en PostgreSQL comme dans d'autres SGBDR qui se respectent, vous pouvez faire cela avec un trigger.
Voilà comment je ferais pour ma part (v.8.x.x à cause des $ dans le plpgsql):
CREATE TABLE test ( ref integer, b integer );
CREATE FUNCTION test_tripl() RETURNS trigger AS $test_stamp$ DECLARE compte integer; BEGIN
select count(*) into compte from test where ref = NEW.ref;
-- vous êtes en trigger BEFORE soit =3 ou plus... if compte>=3 then RAISE EXCEPTION 'pas plus de 3 tuples avec ref= %', NEW.ref; END IF;
RETURN NEW; END; $test_stamp$ LANGUAGE plpgsql;
CREATE TRIGGER test_stamp BEFORE INSERT OR UPDATE ON test FOR EACH ROW EXECUTE PROCEDURE test_tripl();
tests=# insert into test values (1,1); INSERT 2665136 1 tests=# insert into test values (1,2); INSERT 2665137 1 tests=# insert into test values (1,3); INSERT 2665138 1 tests=# insert into test values (1,4); ERROR: pas plus de 3 tuples avec ref= 1
Voilà... :-)
NB: ne me remerciez pas trop, mais plutôt les gens qui se cassent la tête à écrire de docs, et à ceux qui font pareil pour les traduire
Le Fri, 06 May 2005 08:46:02 +0000, Christophe CLEMENT a écrit :
Le 05/05/2005 vers 21h34, Jean-Paul Argudo a écrit :
> Comment faire - en postgreSQL - pour ajouter une contrainte qui vérifie
$test_stamp$ LANGUAGE plpgsql;
Merci, mais là tu utilises du pl/pgsql et je veux faire ça qu'avec du postgres standart.
Tu veux dire en SQL seul, non ? parce que plpgsql fais parti par défaut de PostgreSQL. Donc la proposition de JP était bonne.
Je ne vois pas comment faire ça sans procédure stockée.
-- Sébastien
Christophe CLEMENT
Le 06/05/2005 vers 17h24, Sébastien_Lardière a écrit :
Tu veux dire en SQL seul, non ? parce que plpgsql fais parti par défaut de PostgreSQL. Donc la proposition de JP était bonne.
Admettons, mais quand je lance la fonction de JP dans mon terminal, j'ai l'erreur : ERROR: language "plpgsql" does not exist HINT: You need to use "createlang" to load the language into the database.
Donc même si dans la distribution standard du logiciel il y a ce module, il n'est pas chargé par défaut, et comme je doit faire la base de donnée en question dans le cadre d'un projet pour mes études il faut que ça puisse tourner sur les machines de la FAC sans avoir à faire trop de manipulation préalable...
Je ne vois pas comment faire ça sans procédure stockée.
Moi non plus :o) Sinon j'ai toujours la possibilité d'implémenter celà dans mon programme qui interragit avec la base de données (php), donc au pire je fais ça...
Christophe -- Pour me répondre, mon email en rot13 : hfrarg [ng] 75018 [qbg] bet
Le 06/05/2005 vers 17h24, Sébastien_Lardière <binfalse@altern.org> a
écrit :
Tu veux dire en SQL seul, non ? parce que plpgsql fais parti par défaut
de PostgreSQL. Donc la proposition de JP était bonne.
Admettons, mais quand je lance la fonction de JP dans mon terminal,
j'ai l'erreur :
ERROR: language "plpgsql" does not exist
HINT: You need to use "createlang" to load the language into the
database.
Donc même si dans la distribution standard du logiciel il y a ce
module, il n'est pas chargé par défaut, et comme je doit faire la base
de donnée en question dans le cadre d'un projet pour mes études il faut
que ça puisse tourner sur les machines de la FAC sans avoir à faire
trop de manipulation préalable...
Je ne vois pas comment faire ça sans procédure stockée.
Moi non plus :o) Sinon j'ai toujours la possibilité d'implémenter celà
dans mon programme qui interragit avec la base de données (php), donc
au pire je fais ça...
Christophe
--
Pour me répondre, mon email en rot13 : hfrarg [ng] 75018 [qbg] bet
Le 06/05/2005 vers 17h24, Sébastien_Lardière a écrit :
Tu veux dire en SQL seul, non ? parce que plpgsql fais parti par défaut de PostgreSQL. Donc la proposition de JP était bonne.
Admettons, mais quand je lance la fonction de JP dans mon terminal, j'ai l'erreur : ERROR: language "plpgsql" does not exist HINT: You need to use "createlang" to load the language into the database.
Donc même si dans la distribution standard du logiciel il y a ce module, il n'est pas chargé par défaut, et comme je doit faire la base de donnée en question dans le cadre d'un projet pour mes études il faut que ça puisse tourner sur les machines de la FAC sans avoir à faire trop de manipulation préalable...
Je ne vois pas comment faire ça sans procédure stockée.
Moi non plus :o) Sinon j'ai toujours la possibilité d'implémenter celà dans mon programme qui interragit avec la base de données (php), donc au pire je fais ça...
Christophe -- Pour me répondre, mon email en rot13 : hfrarg [ng] 75018 [qbg] bet
Sébastien Lardière
Le Fri, 06 May 2005 15:58:57 +0000, Christophe CLEMENT a écrit :
Le 06/05/2005 vers 17h24, Sébastien_Lardière a écrit :
Tu veux dire en SQL seul, non ? parce que plpgsql fais parti par défaut de PostgreSQL. Donc la proposition de JP était bonne.
Admettons, mais quand je lance la fonction de JP dans mon terminal, j'ai l'erreur : ERROR: language "plpgsql" does not exist HINT: You need to use "createlang" to load the language into the database.
Donc même si dans la distribution standard du logiciel il y a ce module, il n'est pas chargé par défaut, et comme je doit faire la base de donnée en question dans le cadre d'un projet pour mes études il faut que ça puisse tourner sur les machines de la FAC sans avoir à faire trop de manipulation préalable...
Tu n'auras probablement pas les droits nécessaire, demande à un DBA de ta FAC.
-- Sébastien
Le Fri, 06 May 2005 15:58:57 +0000, Christophe CLEMENT a écrit :
Le 06/05/2005 vers 17h24, Sébastien_Lardière <binfalse@altern.org> a
écrit :
Tu veux dire en SQL seul, non ? parce que plpgsql fais parti par défaut
de PostgreSQL. Donc la proposition de JP était bonne.
Admettons, mais quand je lance la fonction de JP dans mon terminal,
j'ai l'erreur :
ERROR: language "plpgsql" does not exist
HINT: You need to use "createlang" to load the language into the
database.
Donc même si dans la distribution standard du logiciel il y a ce
module, il n'est pas chargé par défaut, et comme je doit faire la base
de donnée en question dans le cadre d'un projet pour mes études il faut
que ça puisse tourner sur les machines de la FAC sans avoir à faire
trop de manipulation préalable...
Le Fri, 06 May 2005 15:58:57 +0000, Christophe CLEMENT a écrit :
Le 06/05/2005 vers 17h24, Sébastien_Lardière a écrit :
Tu veux dire en SQL seul, non ? parce que plpgsql fais parti par défaut de PostgreSQL. Donc la proposition de JP était bonne.
Admettons, mais quand je lance la fonction de JP dans mon terminal, j'ai l'erreur : ERROR: language "plpgsql" does not exist HINT: You need to use "createlang" to load the language into the database.
Donc même si dans la distribution standard du logiciel il y a ce module, il n'est pas chargé par défaut, et comme je doit faire la base de donnée en question dans le cadre d'un projet pour mes études il faut que ça puisse tourner sur les machines de la FAC sans avoir à faire trop de manipulation préalable...
Tu n'auras probablement pas les droits nécessaire, demande à un DBA de ta FAC.
Ça m'a étonné mais il était déjà activé sur le serveur de la Fac ! Donc je l'ai activé aussi sur ma machine ce matin, je vais utiliser cette solution finalement. Si j'ai des soucis pour recoder la fonction ou le trigger je reviens vous voir ;-)
Merci pour tout.
Christophe -- Pour me répondre, mon email en rot13 : hfrarg [ng] 75018 [qbg] bet
Le 07/05/2005 vers 11h49, Sébastien_Lardière <binfalse@altern.org> a
écrit :
Tu n'auras probablement pas les droits nécessaire, demande à un DBA de
ta FAC.
Ça m'a étonné mais il était déjà activé sur le serveur de la Fac ! Donc
je l'ai activé aussi sur ma machine ce matin, je vais utiliser cette
solution finalement. Si j'ai des soucis pour recoder la fonction ou le
trigger je reviens vous voir ;-)
Merci pour tout.
Christophe
--
Pour me répondre, mon email en rot13 : hfrarg [ng] 75018 [qbg] bet
Tu n'auras probablement pas les droits nécessaire, demande à un DBA de ta FAC.
Ça m'a étonné mais il était déjà activé sur le serveur de la Fac ! Donc je l'ai activé aussi sur ma machine ce matin, je vais utiliser cette solution finalement. Si j'ai des soucis pour recoder la fonction ou le trigger je reviens vous voir ;-)
Merci pour tout.
Christophe -- Pour me répondre, mon email en rot13 : hfrarg [ng] 75018 [qbg] bet
J.Pierre Pourrez
Le Mon, 09 May 2005 06:37:03 +0000, Christophe CLEMENT a écrit :
Le 07/05/2005 vers 11h49, Sébastien_Lardière a écrit :
Tu n'auras probablement pas les droits nécessaire, demande à un DBA de ta FAC.
Ça m'a étonné mais il était déjà activé sur le serveur de la Fac ! Donc je l'ai activé aussi sur ma machine ce matin, je vais utiliser cette solution finalement. Si j'ai des soucis pour recoder la fonction ou le trigger je reviens vous voir ;-)
Tu peux faire la requête suivante dans ta base de données pour voir de quels sont les langages procéduraux disponibles: select * from pg_language;
Si plpgsql n'est pas disponible, essaie dans un xterm sur le serveur: createlang plpgsql ton_sgbdr
En principe, être propriétaire de son sgbdr devrait suffire.
Cordialement Jean-Pierre
Le Mon, 09 May 2005 06:37:03 +0000, Christophe CLEMENT a écrit :
Le 07/05/2005 vers 11h49, Sébastien_Lardière <binfalse@altern.org> a
écrit :
Tu n'auras probablement pas les droits nécessaire, demande à un DBA de
ta FAC.
Ça m'a étonné mais il était déjà activé sur le serveur de la Fac !
Donc je l'ai activé aussi sur ma machine ce matin, je vais utiliser cette
solution finalement. Si j'ai des soucis pour recoder la fonction ou le
trigger je reviens vous voir ;-)
Tu peux faire la requête suivante dans ta base de données pour voir de
quels sont les langages procéduraux disponibles:
select * from pg_language;
Si plpgsql n'est pas disponible, essaie dans un xterm sur le serveur:
createlang plpgsql ton_sgbdr
En principe, être propriétaire de son sgbdr devrait suffire.
Tu n'auras probablement pas les droits nécessaire, demande à un DBA de ta FAC.
Ça m'a étonné mais il était déjà activé sur le serveur de la Fac ! Donc je l'ai activé aussi sur ma machine ce matin, je vais utiliser cette solution finalement. Si j'ai des soucis pour recoder la fonction ou le trigger je reviens vous voir ;-)
Tu peux faire la requête suivante dans ta base de données pour voir de quels sont les langages procéduraux disponibles: select * from pg_language;
Si plpgsql n'est pas disponible, essaie dans un xterm sur le serveur: createlang plpgsql ton_sgbdr
En principe, être propriétaire de son sgbdr devrait suffire.