Précédent   Forum des professionnels en informatique > Bases de données > Oracle > Outils > Forms
Forms Forum d'entraide sur Oracle Forms
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 22/11/2006, 08h48   #1
Membre actif
 
Avatar de Jean_Benoit
 
Inscription : juin 2004
Messages : 495
Détails du profil
Informations personnelles :
Âge : 58

Informations forums :
Inscription : juin 2004
Messages : 495
Points : 182
Points : 182
Par défaut TRIGGER sur INSERT

Bonjour,

Soit la table ventes: prodno, quantite, montant_ligne

Supposons que pour le moment je souhaite renseigner "montant_ligne"
avec "quantite * 2"
Le plan A serait que le trigger récupère les infos ("prodno" et "quantite") déjà passées par l'ordre insert pour calculer "montant_ligne".
Je tente:
Code :
1
2
3
4
5
6
7
8
CREATE OR REPLACE TRIGGER calcule_vente
before INSERT ON ventes
FOR each row
begin
	IF inserting then
		montant_ligne := :new.quantite * 2;
	end IF;
end;
Bien sûr ça ne marche pas:
Citation:
SQL>SHOW ERROR
PLS--063 Expression .. ne peut être utilisée come cible d'affectation
Normalement sous forms ça irait tout seul avec un petit post-field, mais là j'interface avec ACCESS (2002 SP3) && ODBC, j'ai pas trop envie de me lancer dans VB, et je n'arrive pas à renseigner le champ "valeur par défaut" de la requête, car la table est liée.

Donc j'en appelle à votre aide pour le plan B
Jean_Benoit est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2006, 09h24   #2
Expert Confirmé
 
Inscription : février 2006
Messages : 3 433
Détails du profil
Informations forums :
Inscription : février 2006
Messages : 3 433
Points : 3 462
Points : 3 462
Essayer:

Code :
:new.montant_ligne := :new.quantite * 2;
__________________
P. Forstmann

AskTom Forums OTN doc 8, 9, 10 et 11
pifor est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2006, 11h17   #3
Membre actif
 
Avatar de Jean_Benoit
 
Inscription : juin 2004
Messages : 495
Détails du profil
Informations personnelles :
Âge : 58

Informations forums :
Inscription : juin 2004
Messages : 495
Points : 182
Points : 182
ça marche!!!

Merci beaucoup
Jean_Benoit est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2006, 11h56   #4
Membre actif
 
Avatar de Jean_Benoit
 
Inscription : juin 2004
Messages : 495
Détails du profil
Informations personnelles :
Âge : 58

Informations forums :
Inscription : juin 2004
Messages : 495
Points : 182
Points : 182
Je cite le trigger qui marche pour le moment, je ne sais pas si on peut optimiser:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
CREATE OR REPLACE TRIGGER compute_sales
before INSERT ON sales
FOR each row
declare
var_product_id number(6);
var_normal_value number(10,2);
 
cursor C1 IS
SELECT product_id, normal_value
FROM products;
 
begin
open c1;
	IF inserting then
		loop
		fetch c1 INTO var_product_id, var_normal_value;
		IF var_product_id = :new.product_id then
			:new.sale_value := var_normal_value * :new.quantity;
		end IF;
		exit when c1%notfound;
		end loop;
	end IF;	
close c1;
end;
/
Je n'ai pas réussi à compiler :new.product_id dans le prédicat du curseur en section declare.

Merci encore
Jean_Benoit est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2006, 12h08   #5
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 450
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 450
Points : 4 209
Points : 4 209
Tu peux passer un paramètre à un curseur (PS : C'est mieux d'utiliser FOR LOOP que les FETCH pour des boucles comme ceci).

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CREATE OR REPLACE TRIGGER compute_sales
BEFORE INSERT ON sales
FOR EACH ROW
DECLARE
 
CURSOR C1 (p_id IN NUMBER) IS
SELECT normal_value
FROM products
WHERE product_id = p_id;
 
BEGIN
	IF INSERTING 
	THEN
		FOR r IN c1 (:NEW.product_id)
		LOOP
			:NEW.sale_value := r.normal_value * :NEW.quantity;
		END LOOP;
	END IF;	
END;
Sinon, à quoi ça sert de faire un curseur ? Tu peux avoir plusieurs lignes ?
Sinon, faut faire un SELECT INTO avec gestion d'erreur (on ne fait rien si on trouve pas dans PRODUCTS.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
CREATE OR REPLACE TRIGGER compute_sales
BEFORE INSERT ON sales
FOR EACH ROW
DECLARE
 v_value NUMBER;
BEGIN
	IF INSERTING 
	THEN
		BEGIN
			SELECT normal_value
			INTO v_value
			FROM PRODUCTS
			WHERE product_id =:NEW.product_id;
 
			:NEW.sale_value := v_value * :NEW.quantity;
 
		EXCEPTION WHEN OTHERS THEN NULL;
		END;
	END IF;	
END;
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2006, 12h30   #6
Membre actif
 
Avatar de Jean_Benoit
 
Inscription : juin 2004
Messages : 495
Détails du profil
Informations personnelles :
Âge : 58

Informations forums :
Inscription : juin 2004
Messages : 495
Points : 182
Points : 182
Effectivement, c'est trop excellent!

(Pour la solution 1 je ne vois pas comment passer un paramètre au trigger depuis la fenêtre "Table" de Access;
Pour la gestion des erreurs dans la solution 2 je tenterai (( quand j'aurai trouvé où télécharger Forms 6i Win32)) une liste déroulante dynamique sur product_id ou product_description, de façon que l'utilisateur n'entre en "Sales" que des produits déjà renseignés en base.)
Jean_Benoit est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2006, 12h52   #7
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 450
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 450
Points : 4 209
Points : 4 209
Heu, j'ai pas dit paramètre au trigger, mais paramètre au curseur

Code :
1
2
3
CURSOR C1 (p_id IN NUMBER)
..
FOR r IN c1 (:NEW.product_id)
T'as rien à faire sous access.
Le comportement est identique à ton trigger qui marche, c'est juste optimisé.
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2006, 13h03   #8
Membre actif
 
Avatar de Jean_Benoit
 
Inscription : juin 2004
Messages : 495
Détails du profil
Informations personnelles :
Âge : 58

Informations forums :
Inscription : juin 2004
Messages : 495
Points : 182
Points : 182
Ah! les paramètres au curseur! que de souvenirs! j'avais complètement oublié...
Bon donc en gros ça signifie qu'il faut y retourner immédiatement..

Merci encore
Jean_Benoit est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 23h25.


 
 
 
 
Partenaires

Hébergement Web