Trigger oracle

0 views
Skip to first unread message

HPL

unread,
Jun 11, 2002, 8:43:20 AM6/11/02
to
Bonjour tout le monde j'ai un petit probleme avec un trigger oracle
je vous expose le probleme
D abord les tables

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 :)


Simon Jeremy

unread,
Jun 11, 2002, 11:33:25 AM6/11/02
to

si j'ai bien compris (ce qui n'est pas certain ) :

:new.prix_total := (d * :new.nombre_vehicules) + c;

Simon Jeremy

HPL

unread,
Jun 11, 2002, 12:23:47 PM6/11/02
to
Oui c bien ca mais ca ne marche pas
Tu aurais la solution le probleme ici c qu'il faut se servir de variable qui
sont en cours d'insertion after insert
puis les melanger avec des variables qui existent deja
Je recapitule pour que tu comprennes bien
En inserant dans la table reservation je choisis un bateau et un nombre de
vehicules
Mon but par la suite est d'obrtenir le prix_total qui est ici une valeur
calculee donc
Pour cela je dois faire une jointure sur le numero du bateau donne par la
reservation en cours, ce qui me donnera le prix de celui ci
Puis je dois faire une jointure sur le code_vehicule (en gors cela identifie
le type de vehicule choisi) qui est donne par la reservation en cours, ce
qui me donnera le prix de celui ci
Puis finalement pour calcuer le prx_total que j'inserrais par la suite dans
la reservation
il faut que je fasse
prix_total = prix_bateau +(prix_vehicule * nombre_vehicules)
Et j'avoue que je m'embrouille dans la syntaxe
Si tu le souhaites ton aide serait bienvenue
ARgh je crois que j'ai ecrit ce message en double desole ^_^'


Simon Jeremy

unread,
Jun 12, 2002, 5:27:49 AM6/12/02
to

CREATE OR REPLACE TRIGGER prix
BEFORE INSERT ON reservation
...


le trigger doit être exécuté avant l'insertion, pas après
ça m'avait echappé


Simon Jeremy


HPL

unread,
Jun 12, 2002, 7:00:40 AM6/12/02
to
Voila a quoi pourrait plus ou moins ressembler le trigger mais
malheuresement il me sort des errreurs de compilation...

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


Simon Jeremy

unread,
Jun 12, 2002, 7:17:38 AM6/12/02
to

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

HPL

unread,
Jun 12, 2002, 7:25:12 AM6/12/02
to
Merci bcp ca compile maintenant :)
Je v tester et te dire ce qu'il en est
Si tu as besoin de quoi que ce soit en application jeux films ou autres
n'hesite pas a me contacter ici
h...@postmaster.co.uk


HPL

unread,
Jun 12, 2002, 8:02:18 AM6/12/02
to
Arf en ajoutant un test maintenant ca foire
dans la table bateau il existe un champ type_bateau
a 0 ou a 1
0 etant un bateau de fret
1 un bateau pour voyageurs
donc selon le resultat de ceci je met la table a jour mais ca me sort une
erruer et je vois pas trop quoi est ce
je te donne le trigger :

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;
/


Simon Jeremy

unread,
Jun 12, 2002, 8:27:55 AM6/12/02
to
HPL wrote:

> begin
>
> select type_bateau
> from bateau

into codeb ?

> where
> num_bateau = :new.num_bateau;
>

Simon Jeremy

HPL

unread,
Jun 12, 2002, 8:57:21 AM6/12/02
to
Voila j'ai modifie bete erreur d'etourderie :)
Mais cela ne marche pas quand meme

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

Simon Jeremy

unread,
Jun 12, 2002, 9:17:45 AM6/12/02
to
HPL wrote:
> Voila j'ai modifie bete erreur d'etourderie :)
> Mais cela ne marche pas quand meme
>

que donne la commande
show errors;

Simon Jeremy

HPL

unread,
Jun 12, 2002, 9:33:22 AM6/12/02
to
Elle me sort ca
LINE/COL ERROR
-------- -----------------------------------------------------------------
41/4 PLS-00103: Symbole ";" rencontré à la place d'un des symboles
suivants :
if


Simon Jeremy

unread,
Jun 12, 2002, 9:33:42 AM6/12/02
to

espacement entre le END et le IF
END IF;


Simon Jeremy

HPL

unread,
Jun 12, 2002, 9:42:03 AM6/12/02
to
merci bcp ca marche faut dire que j avais plus trop l ahbitude d oracle
aapres php/mysql
Vraiment un ters grand merci a toi
N hesite pas a me recontacter si tu veux kkchose :D
h...@postmaster.co.uk

HPL

unread,
Jun 12, 2002, 2:04:31 PM6/12/02
to
Bon le trigger precedement ecrit fonctionne j'en ai ecrit un autre qui met a
jour l'occupation des bateaux
Il compile egalement
mais je me pose des questions
quand doit on
utiliser
new ou :new
quand doit on mettre les :
j'ai reussi a faire l autre en tatonnant mais je ne sais pas pk ca marche et
c un peu embetant si tu pouvais m'expliqer cela eclaircisseraitgrandement
les choses
Merci d'avance


HPL

unread,
Jun 12, 2002, 4:56:35 PM6/12/02
to
Mhh j'ai teste et ca ne fonctionne pas
ERREUR à la ligne 2 :
ORA-01403: Aucune donnée trouvée
ORA-06512: à "SYSTEM.MAB", ligne 9
ORA-04088: erreur lors d'exécution du déclencheur 'SYSTEM.MAB'
Ci dessus l erreur sortie
et voici le trigger
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 = :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 :)


Simon Jeremy

unread,
Jun 13, 2002, 3:01:47 AM6/13/02
to
HPL wrote:
> Mhh j'ai teste et ca ne fonctionne pas
> ERREUR à la ligne 2 :
> ORA-01403: Aucune donnée trouvée
> ORA-06512: à "SYSTEM.MAB", ligne 9
> ORA-04088: erreur lors d'exécution du déclencheur 'SYSTEM.MAB'
> Ci dessus l erreur sortie
> et voici le trigger
> 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 = :old.num_bateau;
>
...


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

Simon Jeremy

unread,
Jun 13, 2002, 3:10:24 AM6/13/02
to

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

HPL

unread,
Jun 13, 2002, 4:14:53 AM6/13/02
to
Ok je cerne un peu mieux tout ca mais tu me conseillerais de gerer comment
la mise a jour des bateaux
Car la j'avoue ne pas trop voir comment
A moins bien sur que pour retrouverle numero de reservation j'utilise le
s_reservation.currentval qui me donnera le numero de sequence courant et
donc me permettra de retrouver la reservation que je viens juste d'effectuer


HPL

unread,
Jun 13, 2002, 4:23:08 AM6/13/02
to
Non je viens de tester ca ne marche pas
Donc comment retrouver mon numero de reservation
Pour mettre a jour ma table bateau si apparement je ne peux pas me servir de
trigger


Simon Jeremy

unread,
Jun 13, 2002, 7:48:29 AM6/13/02
to


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

HPL

unread,
Jun 13, 2002, 8:29:27 AM6/13/02
to
Oki ca marche :)
Mais maintenant car rien n'est decidement evident
Je vourrais verifier qu'il reste de la palce dans le bateau
c a dire que la charge actuelle <= charge_max
et que le nb_pact <= nb_pmax
Ou dois je mettre ces tests ?


Simon Jeremy

unread,
Jun 13, 2002, 8:39:52 AM6/13/02
to

au debut de ton trigger before insert (Prix)
tu mets tes tests

s'ils sont negatifs, tu déclenches une exception utilisateur


Simon Jeremy

HPL

unread,
Jun 13, 2002, 9:31:12 AM6/13/02
to
Voila tout fonctionne merci :)
Je v pouvoir ecrire mon rapport :)
Je suis en maitrise et mon projet consitait a comparer deux implementations
pour la meme bd
une php/mysql et l autre oracle/php
vu que certains fonctions oci ne daignent pas fonctionner ca sera du oracle
pur :)
En bref un grand merci a toi :)
Je te donne les triggers au cas ou tu verrais une connerie ou quelque chose
a ameliorer dedans

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 :)


Simon Jeremy

unread,
Jun 13, 2002, 10:57:38 AM6/13/02
to
HPL wrote:
> Voila tout fonctionne merci :)
> Je v pouvoir ecrire mon rapport :)
> Je suis en maitrise et mon projet consitait a comparer deux implementations
> pour la meme bd
> une php/mysql et l autre oracle/php
> vu que certains fonctions oci ne daignent pas fonctionner ca sera du oracle
> pur :)
> En bref un grand merci a toi :)
> Je te donne les triggers au cas ou tu verrais une connerie ou quelque chose
> a ameliorer dedans
>


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

HPL

unread,
Jun 13, 2002, 11:28:39 AM6/13/02
to
Ok je tiendrai compte de tes judicieux conseils
Mais toi tu fais koi tu bosses dans les bd ou tu es etudiant ?


Simon Jeremy

unread,
Jun 13, 2002, 11:52:38 AM6/13/02
to
HPL wrote:
> Ok je tiendrai compte de tes judicieux conseils
> Mais toi tu fais koi tu bosses dans les bd ou tu es etudiant ?
>
>

développeur Web / BDD
mais le newsgroup n'est pas le lieu le plus approprié
pour les discussions de salon :)


Simon Jeremy

HPL

unread,
Jun 13, 2002, 1:28:34 PM6/13/02
to
il est vrai mais je voulais en savoir un peu plus sur la personne qui m'a
aide :)
Sinon tu as deja reussi a interfacer du oracle avec du php ?
Moi la dll oci se charge
mais malheuresemetn je n'arrive pas a afficher les resultats d une de mes
requetes


Simon Jeremy

unread,
Jun 14, 2002, 2:44:57 AM6/14/02
to

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

Reply all
Reply to author
Forward
0 new messages