Partage
  • Partager sur Facebook
  • Partager sur Twitter

Contrainte inclusion étendue

Sujet résolu
18 décembre 2010 à 17:43:45

Bonjour,
Pour traduire la contrainte inclusion qui est sur le schéma ci-dessous, je dois utiliser un trigger
Image utilisateur


Pour chaque insertion dans la table subir, il faut que je vérifie que l'étudiant est inscrit dans l'uv concerné par le contrôle
Mais je ne voie pas comment faire.
Merci de votre aide
Yann
  • Partager sur Facebook
  • Partager sur Twitter
18 décembre 2010 à 18:10:54

Fais un SELECT FOR UPDATE dans ton trigger ON INSERT sur la table subir et puis regarde ce que ça renvoie...

  • Partager sur Facebook
  • Partager sur Twitter
19 décembre 2010 à 16:05:28

Comme cela ?

create trigger subir_insert
before insert on subir
for each row
begin

 select for update

end
  • Partager sur Facebook
  • Partager sur Twitter
19 décembre 2010 à 18:26:24

Bonjour,

Tu dois faire un trigger sur insert (et pour bien faire, sur update) on subir et faire un trigger sur delete (et pour bien faire, sur update) on inscrit

Du genre (version postgresql)

Je considère que tu insères (code_c, code_e)

*************************************************************************
create function verif_inscription() returns trigger as
'
DECLARE
     inscrit integer;
BEGIN
     select into inscrit count(*) from controle inner join inscrit on (controle.code_u = inscrit.code_u) where code_c= NEW.code_c and code_e=NEW.code_e;
if inscrit = 0 then
     raise exception ''Cet étdiant n'est pas inscrit à l'UV.'';
end if;
return NEW;
END;
' language 'plpgsql';

*************************************************************************
create trigger verifier_inscription before insert on subir
for each row execute procedure verif_inscription();


Voilà, voilà ...


:)
  • Partager sur Facebook
  • Partager sur Twitter
19 décembre 2010 à 19:33:40

Pas mal, mais tu as oublié le lock (FOR SHARE convient) et il n'y a pas besoin de déclarer de variable ;)

ROLLBACK;
BEGIN;

CREATE TABLE etudiants ( etudiant_id SERIAL PRIMARY KEY );
INSERT INTO etudiants (etudiant_id) VALUES (1),(2);

CREATE TABLE uvs ( uv_id SERIAL PRIMARY KEY );
INSERT INTO uvs (uv_id) VALUES (1),(2);

CREATE TABLE uvs_etudiants ( 
	uv_id INTEGER NOT NULL REFERENCES uvs( uv_id ),
	etudiant_id INTEGER NOT NULL REFERENCES etudiants( etudiant_id ),
	PRIMARY KEY (uv_id, etudiant_id)
);

INSERT INTO uvs_etudiants VALUES (1,1), (2,2);

CREATE TABLE controles ( 
	controle_id SERIAL PRIMARY KEY,
	uv_id INTEGER NOT NULL REFERENCES uvs( uv_id )
);

INSERT INTO controles (controle_id,uv_id) VALUES (1,1),(2,2);

SELECT * FROM etudiants NATURAL JOIN uvs_etudiants NATURAL JOIN uvs NATURAL JOIN controles;

CREATE TABLE etudiants_controles (
	etudiant_id INTEGER NOT NULL REFERENCES etudiants( etudiant_id ),
	controle_id INTEGER NOT NULL REFERENCES controles( controle_id ),
	PRIMARY KEY (etudiant_id, controle_id)
);

SELECT controle_id FROM controles
JOIN    uvs_etudiants USING (uv_id)
WHERE   controle_id=1 AND etudiant_id=1 FOR SHARE;

CREATE OR REPLACE FUNCTION verif_inscription_f() RETURNS TRIGGER AS
$$
BEGIN
    PERFORM 1
        FROM controles
        JOIN    uvs_etudiants USING (uv_id)
        WHERE   controle_id=NEW.controle_id AND etudiant_id=NEW.etudiant_id
        FOR SHARE;

    IF NOT FOUND THEN 	
	RAISE EXCEPTION 'Cet étudiant n''est pas inscrit à l''UV.';
    END IF;
RETURN NEW;
END;
$$ LANGUAGE 'plpgsql';

CREATE TRIGGER verif_inscription BEFORE INSERT ON etudiants_controles
FOR EACH ROW EXECUTE PROCEDURE verif_inscription_f();

INSERT INTO etudiants_controles (etudiant_id, controle_id) VALUES (1,1);
INSERT INTO etudiants_controles (etudiant_id, controle_id) VALUES (1,2);

SELECT * FROM etudiants_controles;

ROLLBACK;


(Le 2è INSERT échoue comme attendu)
  • Partager sur Facebook
  • Partager sur Twitter