2017-10-16 2 views
1

J'essaie de créer un déclencheur simple mais j'ai obtenu une erreur en dessous. J'ai cherché sur internet mais je n'ai pas trouvé la solution. Pourriez-vous m'aider sur cette question?Oracle SP2-0552: La variable de liaison "NEW" n'est pas déclarée

create trigger ProcessTigger before insert on T039 
for each row 
declare consecutivo int; idconsecutivo int; maxconsecutivo int; 
begin 
    select t326c004 into consecutivo from T326 where t326c003 = 'T039' and t326c002 = :new.t039c004; 

if consecutivo is not null 
then 
consecutivo :=consecutivo+1; 
select t326c001 into idconsecutivo from T326 where t326c002 = :new.t039c004 and t326c003=T039; 
update T326 set t326c004 = consecutivo where t326c001=idconsecutivo and t326c003=T039; 
else 
select max(t039c003) into maxconsecutivo from T039 where t071c002=:new.t039c004; 

if maxconsecutivo is not null 
then consecutivo := maxconsecutivo+1; 
else consecutivo:=1; 
end if; 

insert into T326 
(t326c002,t326c003,t326c004)values(:new.t039c004,'T039',consecutivo); 

end if; 
end; 

ERREUR:

SP2-0552: bind variable "NEW" est pas déclarée.

+1

Alors, c'est quoi? ORA-04071, le déclencheur manque la clause BEFORE/AFTER/INSTEAD OF? Ou SP2-0552, La variable "NEW" n'est pas déclarée? Oracle jette une erreur à la fois, donc ** ne peut pas ** être les deux. – mathguy

+0

désolé je me suis trompé dans le titre de la question. La question était Or SP2-0552, La variable "NEW" n'est pas déclarée –

+0

Utilisez le petit lien 'edit' situé en dessous de votre message pour l'éditer - vous pouvez changer le titre pour qu'il corresponde à votre problème. – mathguy

Répondre

1

Si c'est votre idée d'un "déclencheur simple" alors je me demande ce que l'on voudrait compliqué?

Il semble probable que l'erreur SP2-0552 est due au fait que vous exécutez un script avec des retours à la ligne aléatoires sans définir SQLBLANKLINES. Mais une fois que vous avez corrigé les erreurs de syntaxe, vous verrez que votre déclencheur ne fonctionnera pas en raison d'une erreur de table en mutation. Nous ne pouvons pas sélectionner dans un déclencheur de la table sous-jacente car l'état est indéterminé. Donc, cela est faux:

select max(t039c003) into maxconsecutivo 
from T039 
where t071c002=:new.t039c004; 

Vous devez trouver une façon différente de la mise en œuvre de règles métier tout qui est censé faire.

+0

Je pense que j'exagère en disant que c'était un simple déclencheur! J'ai déjà corrigé les paramètres SQLBLANKLINES mais j'ai toujours la même erreur. Je dois trouver une manière différente? –

0

L'utilisation de déclencheurs pour une telle fonction de distribution d'ID n'est pas sûre. Rappelez-vous qu'il pourrait y avoir plus d'un insert qui courra pour obtenir le prochain «consecutivo» et obtenir le même ID

En outre, le problème de la table de mutation, où vous ne pouvez pas sélectionner dans la même table dans un déclencheur de niveau ligne. En plus de cela, vous avez une erreur de syntaxe dans les lignes comme celle ci-dessous où vous n'incluez pas T039 entre guillemets!

select t326c001 into idconsecutivo from T326 where t326c002 = :new.t039c004 
and t326c003=T039; 
update T326 set t326c004 = consecutivo where t326c001=idconsecutivo and 
t326c003=T039; 

je soupçonne l'erreur que vous obtenez est due à une référence non valide à une colonne (lorsque vous utilisez: nouveau)

Vous pouvez essayer le déclencheur et la fonction suivante:

  1. Créer un autonomous_transaction fonction pour insérer le "consecutivo" initial
  2. Dans le déclencheur, commencez par insérer (appel de la fonction), et si vous ne créez pas d'enregistrement, mettez à jour

    create or replace 
        trigger processtrigger 
        before insert on t039 
        for each row 
        declare 
        v_id number; 
        begin 
        -- start with insert calling the function 
        if f_create_new_con(:new.t039c004) = 0 then 
         update t326 set t326c004 = t326c004 + 1 -- this is safe since it will take the last committed t326c004 and increase it 
         where t326c003 = 'T039' 
         and t326c002 = :new.t039c004; 
        end if; 
        end; 
    /
    
        create or replace 
        function f_create_new_con(p_value in number) return number 
        is 
        pragma autonomous_transaction; 
        begin 
        insert into t326 (t326c002, t326c003, t326c004) 
        select p_value, 'T039', (select nvl(max(t039c003), 0) + 1 from t039 where t071c002 = p_value) 
        from dual 
        where not exists (select 1 from t326 where t326c002 = p_value and t326c003 = 'T039'); 
    
        -- if no insert then return 0 to update 
        if (sql%rowcount = 0) then 
         return 0; 
        else 
         return 1; 
        end if; 
        end; 
    /