RESERVATION
NUM_RESERVATION
NUM_BATEAU
CODE_VEHICULE
NOMBRE_VEHICULES POIDS_TOTAL_VEHICULES
PRIX_TOTAL
BATEAU
NUM_BATEAU
CHARGE_MAXIMALE
PRIX_BATEAU
CHARGE_ACTUELLE
CATEGORIE_VEHICULE
CODE_VEHICULE (PK)
POIDS
PRIX_VEHICULE
Le but de mon trigger serait qu'il calcule le prix_total et le poids_total
et qu'il fasse ensuite un update de la table reservation
Une premiere version du trigger donne ca
create or replace trigger Prix
after insert on reservation
FOR EACH ROW
declare
c integer;
d integer;
begin
select prix_bateau into c from bateau where num_bateau = :new.num_bateau;
select prix_vehicule into d from categorie_vehicule where code_vehicule =
:new.code_vehicule;
end;
/
Mon probleme est que je n'arrive pas a recuperer cette foutue variable
nombre_vehicules
le prix_total = (prix_vehicule * nombre_vehicules) + prix_bateau
et par la suite faire un update de la reservation fraichement cree
Je ne comprends pas comment il faut faire ca doit etre une erreur de syntaxe
Pitie de l'aide
Merci d'avance :)
si j'ai bien compris (ce qui n'est pas certain ) :
:new.prix_total := (d * :new.nombre_vehicules) + c;
Simon Jeremy
le trigger doit être exécuté avant l'insertion, pas après
ça m'avait echappé
Simon Jeremy
create or replace trigger Prix
before insert on reservation
FOR EACH ROW
declare
c integer;
d integer;
begin
select prix_bateau into c from bateau where num_bateau = :new.num_bateau;
select prix_vehicule into d from categorie_vehicule where code_vehicule =
:new.code_vehicule;
update reservation set :new.prix_total := (d * :new.nombre_vehicules) + c;
end;
/
Votre aide serait bienvenue :D
il faut supprimer le UPDATE :
create or replace trigger Prix
before insert on reservation
FOR EACH ROW
declare
c integer;
d integer;
begin
select prix_bateau
into c
from bateau
where num_bateau = :new.num_bateau;
select prix_vehicule
into d
from categorie_vehicule
where code_vehicule =:new.code_vehicule;
:new.prix_total := (d * :new.nombre_vehicules) + c;
end;
/
Simon Jeremy
create or replace trigger Prix
before insert on reservation
FOR EACH ROW
declare
bat integer;
pla integer;
p_vehicule integer;
p_bateau integer;
codeb integer;
begin
select type_bateau
from bateau
where
num_bateau = :new.num_bateau;
if codeb = 1
then
select prix_bateau
into bat
from bateau
where num_bateau = :new.num_bateau;
select prix_place
into pla
from categorie_place
where code_place =:new.code_place;
:new.prix_total := (pla * :new.nombre_personnes) + bat;
elsif codeb = 0
then
select prix_bateau
into p_bateau
from bateau
where num_bateau = :new.num_bateau;
select prix_vehicule
into p_vehicule
from categorie_vehicule
where code_vehicule =:new.code_vehicule;
:new.prix_total := (p_vehicule * :new.nombre_vehicules) + p_bateau;
endif;
end;
/
> begin
>
> select type_bateau
> from bateau
into codeb ?
> where
> num_bateau = :new.num_bateau;
>
Simon Jeremy
create or replace trigger Prix
before insert on reservation
FOR EACH ROW
declare
bat integer;
pla integer;
p_vehicule integer;
p_bateau integer;
codeb integer;
begin
select type_bateau into codeb from bateau
where num_bateau = :new.num_bateau;
endif;
end;
/
Peut etre que l'erreur vient du bloc if then elseif endif
que donne la commande
show errors;
Simon Jeremy
espacement entre le END et le IF
END IF;
Simon Jeremy
declare
nbpersact integer;
codeb integer;
chargeact integer;
begin
select type_bateau into codeb from bateau
where num_bateau = :old.num_bateau;
if codeb = 1
then
select nb_pact into nbpersact from bateau where num_bateau =
:old.num_bateau;
update bateau set nb_pact = (nbpersact + :old.nb_p) where num_bateau =
:old.num_bateau;
elsif codeb = 0
then
select charge_act into chargeact from bateau where num_bateau =
:old.num_bateau;
update bateau set charge_act = :old.poids_total_vehicules + chargeact where
num_bateau = :old.num_bateau;
end if;
end;
/
J'avoue ne pas trop savoir comment faire vu que pour mettre a jour les
bateaux j'ai besoin des donnees obtenues precedement avec le trigger prix si
tu pouvais m'aider ca serait encore une fois tres sympatjique de ta part :)
tu ne peux pas utiliser :old
puisque old correspond à l'ancienne valeur présente dans la table
insert => :new
update => :new et :old
delete => :old
tu ne peux pas non plus agir sur :new si tu fais un after insert,
puisque la valeur est déjà dans la table
Simon Jeremy
il faut mettre les :
c'est la syntaxe
a priori, ça permet au moteur PL/SQL de savoir que tu agis sur les
données de ta requête et non pas sur une variable de package :
:new.prix_total
new.prix_total
Simon Jeremy
CREATE OR REPLACE TRIGGER mab
AFTER INSERT ON reservation
FOR EACH ROW
DECLARE
nbpersact INTEGER;
codeb INTEGER;
chargeact INTEGER;
BEGIN
SELECT type_bateau
INTO codeb
FROM bateau
WHERE num_bateau = :new.num_bateau;
IF codeb = 1
THEN
SELECT nb_pact
INTO nbpersact
FROM bateau
WHERE num_bateau = :new.num_bateau;
UPDATE bateau
SET nb_pact = (nbpersact + :new.nb_p)
WHERE num_bateau = :new.num_bateau;
ELSIF codeb = 0
THEN
SELECT charge_act
INTO chargeact
FROM bateau
WHERE num_bateau = :new.num_bateau;
UPDATE bateau
SET charge_act = :new.poids_total_vehicules + chargeact
WHERE num_bateau = :new.num_bateau;
END IF;
END;
/
tu peux mettre tous tes traitements dans le meme
trigger (before insert) pour eviter la dispersion
et la duplication du code
Simon Jeremy
au debut de ton trigger before insert (Prix)
tu mets tes tests
s'ils sont negatifs, tu déclenches une exception utilisateur
Simon Jeremy
CREATE OR REPLACE TRIGGER mab
AFTER INSERT ON reservation
FOR EACH ROW
DECLARE
nbpersact INTEGER;
codeb INTEGER;
chargeact INTEGER;
BEGIN
SELECT type_bateau
INTO codeb
FROM bateau
WHERE num_bateau = :new.num_bateau;
IF codeb = 1
THEN
SELECT nb_pact
INTO nbpersact
FROM bateau
WHERE num_bateau = :new.num_bateau;
UPDATE bateau
SET nb_pact = nbpersact + :new.nb_p
WHERE num_bateau = :new.num_bateau;
ELSIF codeb = 0
THEN
SELECT charge_act
INTO chargeact
FROM bateau
WHERE num_bateau = :new.num_bateau;
UPDATE bateau
SET charge_act = :new.poids_total_vehicules + chargeact
WHERE num_bateau = :new.num_bateau;
END IF;
END;
/
create or replace trigger PrixBF
before insert on reservation
FOR EACH ROW
declare
bat integer;
pla integer;
p_vehicule integer;
p_bateau integer;
codeb integer;
poidsv integer;
chargeact integer;
chargemax integer;
nbpact integer;
nbpmax integer;
begin
select type_bateau into codeb from bateau
where num_bateau = :new.num_bateau;
if codeb = 1
then
select nb_pact,nb_pmax into nbpact,nbpmax
from bateau
where num_bateau = :new.num_bateau;
if (nbpact < nbpmax) and ((nbpact+ :new.nb_p) < nbpmax)
then
select prix_bateau
into bat
from bateau
where num_bateau = :new.num_bateau;
select prix_p
into pla
from categorie_place
where code_place =:new.code_place;
:new.prix_total := (pla * :new.nb_p) + bat;
else
raise_application_error(-20502,'Bateau plein! Plus de places voyageurs');
end if;
elsif codeb = 0
then
select charge_max,charge_act into chargemax,chargeact from bateau
where num_bateau = :new.num_bateau;
select poids_v into poidsv from categorie_vehicule where
code_vehicule = :new.code_vehicule;
if (chargeact < chargemax) and ((poidsv * :new.nb_v) < chargemax)
then
select poids_v into poidsv from categorie_vehicule where
code_vehicule = :new.code_vehicule;
select prix_bateau
into p_bateau
from bateau
where num_bateau = :new.num_bateau;
select prix_v
into p_vehicule
from categorie_vehicule
where code_vehicule =:new.code_vehicule;
:new.prix_total := (p_vehicule * :new.nb_v) + p_bateau;
:new.poids_total_vehicules := (poidsv * :new.nb_v);
else
raise_application_error(-20502,'Bateau plein! Plus de places vehicules');
end if;
end if;
end;
/
Encore merci :)
n'hésite pas améliorer l'indentation et les sauts de lignes
pour rendre ton prog plus facile et agréable à lire
en général, je mets les mots-clés du langage en majuscules (en PL/SQL)
je ne nomme jamais une variable p_xxx
ca laisse penser que c'est un paramètre (fonction, procédure)
je l'appele plutôt v_xxx
j'évite d'appeler des variables pla ou bat
place et bateau (ou prix_place et prix_bateau) c'est pas beaucoup plus
long et bien plus explicite
Simon Jeremy
développeur Web / BDD
mais le newsgroup n'est pas le lieu le plus approprié
pour les discussions de salon :)
Simon Jeremy
j'ai jamais esssayé
il faut plutôt voir ca sur le newsgroup consacré au php
(et sur les archives)
il faut tester la connexion, l'exécution de la requête
et le fetch du résultat, et essayer de récupérer un
message d'erreur
est-ce que ta requête ramène bien des lignes ?
il vaut mieux commencer par une requête simple du style
SELECT sysdate FROM dual;
ou SELECT user FROM dual;
Simon Jeremy