[SGBD/SQL] Oracle : PL/SQL, problème tout con

Oracle : PL/SQL, problème tout con [SGBD/SQL] - SQL/NoSQL - Programmation

Marsh Posté le 28-03-2006 à 16:04:37    

Oracle, c'est de la merde et c'est pas nouveau.
 
Le "to_number" se localise comme un con à partir de la locale du client, et du coup j'ai un trigger mal codé qui plante.
 
J'ai pas envie de le foutre en l'air, donc je veux juste faire la modif bidon qui va me permettre de le squizer.
 
Dans ma requête, dans mon cas précis, j'ai "SIGDEP" qui est vide ( :new.sigdep = ' ' ).
Hors, applicativement, c'est impossible, donc je suis certain que seul "moi" pourrai faire cette requête (un peu compliqué à expliquer, mais c'est ce qu'il y a de plus propre à faire, mise à part corriger le trigger, mais j'ai pas envie de me plonger dedans)
 
Du coup, je voudrais simplement faire un test sur le trigger : si sigdep != ' ', alors je fais tout le bordel, sinon je zappe.
Sauf que la syntaxe PL/SQL est un gros mystère pour moi, et je m'en sors pas. Je suis sur le serveur de production, et du coup à chaque test, je vous tous les utilisateurs dans les choux. Ca me lourde.
 
Est-ce que qq1 peut me dire quoi rajouter ?
 

Code :
  1. CREATE OR REPLACE TRIGGER "SOC1"."MAJ_PRO" AFTER INSERT OR UPDATE OF "CODPRO", "CODSOC", "CODZN2", "SIGFOU", "VOLUME" ON "SOC1"."PRO" FOR EACH ROW WHEN (nvl(old.codzn2,0)<>new.codzn2 or old.volume<>new.volume and new.codsoc<>3)
  2. declare
  3. cursor frn is
  4.   select coddev,decode(codzn1,' ','0',codzn1) codzn1,
  5.          replace(decode(codzn2,' ','0',codzn2),',','.') codzn2
  6.     from tie
  7.    where sigtie=:new.sigfou and typtie='FOU' and codsoc=:new.codsoc;
  8. codev     varchar2(6);
  9. dadev     varchar2(30);
  10. txdev     number(18,6);
  11. cdzn      varchar2(12);
  12. pxach     number;
  13. frapp     number;
  14. pxrev     number;
  15. coefmg    number:=2.2;
  16. pxvenc    number;
  17. pxven     number;
  18. mrgval    number;
  19. mrgpct    number;
  20. dev_abs   varchar2(2):='NK';
  21. begin
  22. --- MON TEST ICI
  23.   for f in frn loop
  24.   begin
  25.     select cours into txdev from dem
  26.      where codsoc=:new.codsoc and coddev=f.coddev and natdev='PRE' and
  27.              (datdeb,datfin) = (select max(datdeb), datfin from dem
  28.                                  where codsoc=:new.codsoc and coddev=f.coddev and
  29.                                        natdev='PRE' and datdeb<=to_char(sysdate,'yyyymmdd') and
  30.                                        nvl(datfin,'29991231')<=to_char(sysdate,'yyyymmdd')
  31.                                  group by datfin
  32.                                  having max(datdeb)<=to_char(sysdate,'yyyymmdd'));
  33.   exception
  34.     when no_data_found then txdev:=1;
  35.   end;
  36.    if :new.codzn2=' ' /* px achat obligatoire */
  37.     then cdzn:='1';
  38.     else cdzn:=:new.codzn2;
  39.    end if;
  40.     pxach:=to_number(replace(cdzn,',','.'))*to_number(txdev);
  41.       if (f.codzn1=0 and f.codzn2=0)
  42.        then frapp:=0;
  43.        else if f.codzn2=0    /* val au m3 par defaut sinon %VM */
  44.              then frapp:=to_number(f.codzn1)*pxach/100;
  45.              else frapp:=to_number(f.codzn2)*:new.volume;
  46.             end if;
  47.        end if;
  48.     pxrev:=pxach+frapp;
  49.     pxvenc:=pxrev*coefmg; /* que pour insertion */
  50.     mrgval:=pxvenc-pxrev;
  51.     if pxvenc<>0
  52.      then mrgpct:=mrgval/pxvenc; /*/100;*/
  53.      else mrgpct:=mrgval;
  54.     end if;
  55.     begin
  56.       select px_vent into pxven
  57.         from wt_prdwr_art
  58.        where co_art=:new.codpro and co_soc=:new.codsoc and co_dev=f.coddev;
  59. /*      mrgval:=pxvenc-pxrev;
  60.       if pxvenc<>0
  61.        then mrgpct:=mrgval/pxvenc;  
  62.        else mrgpct:=mrgval;
  63.       end if;
  64.       if pxrev<>0
  65.        then coefmg:=pxvenc/pxrev;
  66.        else coefmg:=pxvenc;
  67.       end if;
  68.       coef_mrg=coefmg, */
  69.       update wt_prdwr_art set px_acht=pxach, fr_apprt=frapp, px_revt=pxrev,
  70.                               mrg_valt=mrgval, mrg_prctgt=mrgpct,
  71.                               da_modif=sysdate, tx_dev=txdev, px_vent=pxvenc
  72.        where co_art=:new.codpro and co_soc=:new.codsoc and co_dev=f.coddev;
  73.     exception
  74.       when no_data_found then
  75.         insert into wt_prdwr_art
  76.          values (:new.codsoc, :new.codpro, f.coddev, txdev,  pxach, frapp, pxrev, coefmg,
  77.                  pxvenc, mrgval, mrgpct, sysdate,sysdate);
  78.     end;
  79.   end loop;
  80. exception
  81.   when no_data_found then null;
  82. end;


 
Merci :sweat:

Message cité 2 fois
Message édité par Arjuna le 28-03-2006 à 16:05:54
Reply

Marsh Posté le 28-03-2006 à 16:04:37   

Reply

Marsh Posté le 28-03-2006 à 16:49:11    

Arjuna a écrit :

Oracle, c'est de la merde et c'est pas nouveau.


 
Je dois me tapper un gros projet sous Oracle sous peu, tu lui reproches quoi exactement à cet environnement ?
 

Arjuna a écrit :


Dans ma requête, dans mon cas précis, j'ai "SIGDEP" qui est vide ( :new.sigdep = ' ' ).
Hors, applicativement, c'est impossible, donc je suis certain que seul "moi" pourrai faire cette requête (un peu compliqué à expliquer, mais c'est ce qu'il y a de plus propre à faire, mise à part corriger le trigger, mais j'ai pas envie de me plonger dedans)
 
Du coup, je voudrais simplement faire un test sur le trigger : si sigdep != ' ', alors je fais tout le bordel, sinon je zappe.
Sauf que la syntaxe PL/SQL est un gros mystère pour moi, et je m'en sors pas. Je suis sur le serveur de production, et du coup à chaque test, je vous tous les utilisateurs dans les choux. Ca me lourde.
 
Est-ce que qq1 peut me dire quoi rajouter ?


 
Je trouve pas de trace de sigdep dans ton code, tu le récupères comment dans ces conditions :??:

Reply

Marsh Posté le 28-03-2006 à 16:52:17    

Arjuna a écrit :

Oracle, c'est de la merde et c'est pas nouveau.


 
 :lol: belle manière de cacher son ignorance ;)
 
Essaye :
 

Code :
  1. IF :new.sigdep IS NULL THEN
  2. <ton code>
  3. END IF;


 
Par ailleurs tu as MERGE qui remplace avantageusement ton update ou insert selon l'exception ;)
 
Au pire :

Code :
  1. update wt_prdwr_art set px_acht=pxach, fr_apprt=frapp, px_revt=pxrev,
  2.                              mrg_valt=mrgval, mrg_prctgt=mrgpct,
  3.                              da_modif=sysdate, tx_dev=txdev, px_vent=px_vent
  4.       where co_art=:new.codpro and co_soc=:new.codsoc and co_dev=f.coddev;
  5.    IF SQL%ROWCOUNT=0 THEN
  6.        insert into wt_prdwr_art
  7.         values (:new.codsoc, :new.codpro, f.coddev, txdev,  pxach, frapp, pxrev, coefmg,
  8.                 pxvenc, mrgval, mrgpct, sysdate,sysdate);
  9.    END IF;


 
le SELECT est alors inutile :)

Reply

Marsh Posté le 28-03-2006 à 16:54:20    

Reply

Marsh Posté le 28-03-2006 à 17:52:26    

orafrance a écrit :

:lol: belle manière de cacher son ignorance ;)


Je cache pas mon ignorance. Un SGBD qui utilise la locale du client dans un trigger, je trouve ça plus que douteux (et y'a pas que ça que je reproche à Oracle, ça encore ça peut avoir certains avantages).

Message cité 1 fois
Message édité par Arjuna le 28-03-2006 à 18:00:05
Reply

Marsh Posté le 28-03-2006 à 17:58:56    

Bon, sinon, j'ai à la fois trouvé où ça plantait (même pas dans le corps du trigger) et un moyen plus efficace pour squizzer le trigger (truc pas mal d'ailleurs, comme quoi Oracle c'est pas que de la merde).
 
J'ai débuggé le "when" (première ligne) de déclenchement tu trigger.
 
En fait, le filtre "codzn <> 3" correspond à mon cas (encore plus que le coup du new.sigdep = ' ', sauf qu'avec un OR avant et des parenthèses mal équilibrée, ça ne risquait pas de marcher.
Ensuite, ce qui plantait, c'est le :
 
nvl(old.codzn2, 0) <> new.codzn2
 
le crétin qui a pondu ça a juste oublié que ce champ est un varchar, et que si new.codzn2 = ' ' (mon cas) ben comparer 0 avec ' ' se traduit pas une erreur de type.
 
le when corrigé :
 

Code :
  1. WHEN ((nvl(old.codzn2,'0')<>new.codzn2 or old.volume<>new.volume) and new.codsoc<>3)


 
voilà.
 
Merci d'avoir pris la peine de regarder mon problème en tout cas :jap:
 
Sinon, pour le IF, j'avais bêtement mis un "end;" tout court, c'était ça mon problème, je hais le PL/SQL, et du coup j'évite autant que possible d'en faire - ça tombe bien foutre des trigger sur la base d'un ERP, y'a rien de mieux pour le planter, donc on me demande as d'en faire - :spamafote:
 
Pour le MERGE, je me trompe peut-être, mais là je suis sur 8i, et je ne crois pas que ce soit supporté, si ? En tout cas, si ça l'est, je garde sous le coude, c'est vrai que c'est moins chiant.

Message cité 1 fois
Message édité par Arjuna le 28-03-2006 à 18:03:35
Reply

Marsh Posté le 29-03-2006 à 11:36:20    

Arjuna a écrit :

Je cache pas mon ignorance. Un SGBD qui utilise la locale du client dans un trigger, je trouve ça plus que douteux (et y'a pas que ça que je reproche à Oracle, ça encore ça peut avoir certains avantages).


 
Et si tu veux que le trigger régisse différemment selon le contexte ??? Genre remplir un champ LAST_UPDATED_BY :)

Reply

Marsh Posté le 29-03-2006 à 11:38:44    

Arjuna a écrit :


Pour le MERGE, je me trompe peut-être, mais là je suis sur 8i, et je ne crois pas que ce soit supporté, si ? En tout cas, si ça l'est, je garde sous le coude, c'est vrai que c'est moins chiant.


 
je crois bien que tu as raison :)
 

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed