编写触发器时的另一个PLS-00103

时间:2015-03-18 08:03:58

标签: oracle plsql triggers

所以我正在使用sql开发人员为DB编写触发器,但我不能解决这个问题:

这是我的触发器(更短的版本,但我尝试使其工作)

create or replace trigger trig_ognisko
        before insert or UPDATE ON podsumowanie
        FOR EACH ROW
  DECLARE
  z1 varchar2;
  z2 varchar2;
  z3 varchar2;
  BEGIN
  IF :NEW.ognisko=(select o.id 
   from ognisko o join grupy_ognisk g on g.id=o.grupa and g.placowka=o.placowka and g.prowadzace!=o.id
   where o.placowka=:NEW.placowka and o.id=:NEW.ognisko)THEN            
    if updating('dzialania_korygujacje_opis') then
      select p.dzialania_korygujacje_opis into z1
      from ognisko o
      join grupy_ognisk g on g.id=o.grupa and g.placowka=o.placowka and g.prowadzace=o.id
      join podsumowanie p on p.ognisko = o.id and p.placowka=o.placowka
      where o.placowka=:NEW.placowka and o.id=:NEW.ognisko;
         IF INSTR(z1,:OLD.dzialania_korygujacje_opis)!=-1 then
           REPLACE(z1,:OLD.dzialania_korygujacje_opis,:NEW.dzialania_korygujacje_opis);
            update podsumowanie pod set pod.dzialania_korygujacje_opis=z1 where
            pod.ID=(
            select p.ID
            from ognisko o
            join grupy_ognisk g on g.id=o.grupa and g.placowka=o.placowka and g.prowadzace=o.id
            join podsumowanie p on p.ognisko = o.id and p.placowka=o.placowka
            where o.placowka=:NEW.placowka and o.id=:NEW.ognisko);
         END IF;
    end if;
  END IF;
END;

尝试创建后,我收到一个错误: 错误(8,23):PLS-00103:当遇到以下情况之一时遇到符号“JOIN”:),组具有交叉减去开始联合连接

Oracle版本11.2.0.1.0 不知道,问题是什么。我一直在寻找很长一段时间!也许你有更好的谷歌搜索结果? DB:

GRUPY_OGNISK:

ID  NUMBER(38,0)    No      1   
PLACOWKA    NUMBER(38,0)    No      2   
USUNIETE    NUMBER(1,0) No      5   
REF_ID  NUMBER(38,0)    Yes     9   
REF_PLACOWKA    NUMBER(38,0)    Yes     10  
REF_TYP NUMBER(38,0)    No      11  
PROWADZACE  NUMBER(38,0)    Yes     13  
PROWADZACE_PLACOWKA NUMBER(38,0)    Yes     14  
PROWADZACE_IDENTYFIKATOR    VARCHAR2(50 CHAR)   Yes     15  

OGNISKO:

ID  NUMBER(38,0)    No      1   
PLACOWKA    NUMBER(38,0)    No      2   
REF_ID  NUMBER(38,0)    Yes     9   
REF_PLACOWKA    NUMBER(38,0)    Yes     10  
REF_TYP NUMBER(38,0)    No      11  
GRUPA   NUMBER(38,0)    Yes     38  

PODSUMOWANIE:

ID  NUMBER(38,0)    No      1   
PLACOWKA    NUMBER(38,0)    No      2   
USUNIETE    NUMBER(1,0) No      5   
REF_ID  NUMBER(38,0)    Yes     9   
REF_PLACOWKA    NUMBER(38,0)    Yes     10  
REF_TYP NUMBER(38,0)    No      11  
DZIALANIA_KORYGUJACJE_OPIS  VARCHAR2(255 CHAR)  Yes     16  
OGNISKO NUMBER(38,0)    No      26  
OGNISKO_PLACOWKA    NUMBER(38,0)    No      27  

只有一些列,因为它们有很多,它们在这里并不重要

2 个答案:

答案 0 :(得分:1)

错误在本节中:

IF :NEW.ognisko=(select o.id 
   from ognisko o join grupy_ognisk g on g.id=o.grupa and g.placowka=o.placowka and g.prowadzace!=o.id
   where o.placowka=:NEW.placowka and o.id=:NEW.ognisko)THEN

您无法在PL / SQL条件中使用(子)查询,您需要将值选择到局部变量中并进行比较。您正在做的简化版本是:

begin
  if 'X' = (select d.dummy from dual d join dual x on x.dummy = d.dummy) then
    null;
  end if;
end;
/

ORA-06550: line 2, column 40:
PLS-00103: Encountered the symbol "JOIN" when expecting one of the following: ...

它抱怨加入,因为这就是解析器首先发现问题无法解决的问题;没有加入它仍然是错误,有更有意义的消息:

begin
  if 'X' = (select d.dummy from dual d) then
    null;
  end if;
end;
/

ORA-06550: line 2, column 12:
PLS-00405: subquery not allowed in this context

您需要使用局部变量,例如:

declare
  l_dummy dual.dummy%type;
begin
  select dummy into l_dummy from dual;
  if 'X' = l_dummy then
    null;
  end if;
end;
/

或者在您的情况下,定义了合适的变量:

  select o.id into l_id
   from ognisko o join grupy_ognisk g on g.id=o.grupa and g.placowka=o.placowka and g.prowadzace!=o.id
   where o.placowka=:NEW.placowka and o.id=:NEW.ognisko;
  IF :NEW.ognisko=l_id THEN  

但是由于select where条件正在执行o.id=:NEW.ognisko,所以条件必须为true,除非没有匹配的记录,在这种情况下你会得到一个no -data-found错误。如果您正在测试是否存在,请进行计数,然后检查,或许:

  select count(*) into l_count
   from ognisko o join grupy_ognisk g on g.id=o.grupa and g.placowka=o.placowka and g.prowadzace!=o.id
   where o.placowka=:NEW.placowka and o.id=:NEW.ognisko;
  IF l_count > 0 THEN  

答案 1 :(得分:0)

Alex Poole - 谢谢! 如果有人对最终触发器主体感兴趣,没有错误,我在这里发布,作为下一代的例子:)

            create or replace trigger trig_ognisko
            before insert or UPDATE ON podsumowanie
            FOR EACH ROW
  DECLARE
  z1 varchar2(1000);
  z2 varchar2(1000);
  z3 varchar2(1000);
  tempID NUMBER;
BEGIN
select o.id into tempID
   from ognisko o join grupy_ognisk g on g.id=o.grupa and g.placowka=o.placowka and g.prowadzace!=o.id
   where o.placowka=:NEW.placowka and o.id=:NEW.ognisko;
  IF :NEW.ognisko=tempID THEN            
    if updating('dzialania_korygujacje_opis') then
      SELECT p.dzialania_korygujacje_opis INTO z1
      FROM ognisko o1
      JOIN grupy_ognisk g1 ON g1.id=o1.grupa AND g1.placowka=o1.placowka AND g1.prowadzace=o1.id
      JOIN podsumowanie p ON p.ognisko = o1.id AND p.placowka=o1.placowka
      WHERE o1.placowka=:NEW.placowka AND o1.id=:NEW.ognisko;
         IF INSTR(z1,:OLD.dzialania_korygujacje_opis)!=-1 then
           z1:=REPLACE(z1, :OLD.dzialania_korygujacje_opis, :OLD.dzialania_korygujacje_opis);
            update podsumowanie pod set pod.dzialania_korygujacje_opis=z1 where
            pod.ID=(
            select p.ID
            from ognisko o
            join grupy_ognisk g on g.id=o.grupa and g.placowka=o.placowka and g.prowadzace=o.id
            join podsumowanie p on p.ognisko = o.id and p.placowka=o.placowka
            where o.placowka=:NEW.placowka and o.id=:NEW.ognisko);
         END IF;
    end if;     
   if updating('likwidacja_zrodla_opis') then
      select p.likwidacja_zrodla_opis into z2
      from ognisko o join grupy_ognisk g on g.id=o.grupa and g.placowka=o.placowka and g.prowadzace=o.id
      join podsumowanie p on p.ognisko = o.id and p.placowka=o.placowka
      where o.placowka=:NEW.placowka and o.id=:NEW.ognisko;
        IF INSTR(z2,:OLD.likwidacja_zrodla_opis)!=-1 then
           z2:=REPLACE(z2, :OLD.likwidacja_zrodla_opis, :OLD.likwidacja_zrodla_opis);
            update podsumowanie pod set pod.likwidacja_zrodla_opis=z2 where
            pod.ID=(
            select p.ID
            from ognisko o
            join grupy_ognisk g on g.id=o.grupa and g.placowka=o.placowka and g.prowadzace=o.id
            join podsumowanie p on p.ognisko = o.id and p.placowka=o.placowka
            where o.placowka=:NEW.placowka and o.id=:NEW.ognisko);
         END IF;
    end if;
     if updating('inne_opis') then
      select p.inne_opis into z3
      from ognisko o join grupy_ognisk g on g.id=o.grupa and g.placowka=o.placowka and g.prowadzace=o.id
      join podsumowanie p on p.ognisko = o.id and p.placowka=o.placowka
      where o.placowka=:NEW.placowka and o.id=:NEW.ognisko;
        IF INSTR(z2,:OLD.inne_opis)!=-1 then
           z3:=REPLACE(z2, :OLD.inne_opis, :OLD.inne_opis);
            update podsumowanie pod set pod.inne_opis=z3 where
            pod.ID=(
            select p.ID
            from ognisko o
            join grupy_ognisk g on g.id=o.grupa and g.placowka=o.placowka and g.prowadzace=o.id
            join podsumowanie p on p.ognisko = o.id and p.placowka=o.placowka
            where o.placowka=:NEW.placowka and o.id=:NEW.ognisko);
         END IF;
    end if;
  END IF;
END;

  drop trigger trig_ognisko;
  select* from V$VERSION;