【问题标题】:Oracle SP2-0552: Bind variable "NEW" is not declaredOracle SP2-0552:未声明绑定变量“NEW”
【发布时间】:2017-10-16 19:54:49
【问题描述】:

我正在尝试创建一个简单的触发器,但出现以下错误。我在互联网上搜索但找不到解决方案。你能帮我解决这个问题吗?

 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; 

错误:

SP2-0552:未声明绑定变量“NEW”。

【问题讨论】:

  • 那么,它是什么? ORA-04071,触发器缺少 BEFORE/AFTER/INSTEAD OF 子句?还是 SP2-0552,未声明绑定变量“NEW”? Oracle 一次抛出一个错误,因此不可能同时出现。
  • 对不起,我的问题标题错了。问题是或 SP2-0552,未声明绑定变量“NEW”
  • 使用您帖子下方的小 edit 链接进行编辑 - 您可以更改标题以匹配您的问题。

标签: oracle plsql database-trigger


【解决方案1】:

如果这是您对“简单触发器”的想法,那么我想知道一个复杂的触发器想要什么?

SP2-0552 错误似乎是因为您正在运行带有恶意换行符的脚本,而没有设置 SQLBLANKLINES

但是,一旦您修复了语法错误,您会发现您的触发器由于变异表错误而无法运行。我们无法从基础表中选择触发器,因为状态是不确定的。所以这是错误的:

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

您需要找到一种不同的方式来实现应该执行的任何业务规则。

【讨论】:

  • 我想我夸张地说这是简单的触发器!我已经更正了 SQLBLANKLINES 设置,但仍然出现同样的错误。我需要另辟蹊径吗?
【解决方案2】:

对这种分配 ID 的功能使用触发器是不安全的。请记住,可能不止一个插入会竞相获得下一个“consecutivo”并获得相同的 ID

此外,还有变异表的问题,您无法在行级触发器中从同一个表中进行选择。

除此之外,您在下面的行中有语法错误,您没有用引号将 T039 括起来!

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

我怀疑您收到的错误是由于对列的引用无效(使用 :new 时)

你可以试试下面的触发器和函数:

  1. 创建一个autonomous_transaction 函数来插入初始的“consecutivo”
  2. 在触发器中,以insert开始(调用函数),如果没有创建记录,则更新

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-29
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    相关资源
    最近更新 更多