Ошибка (6,87): PLS-00103: обнаружен символ «JOIN» при ожидании одного из следующих / составных триггеров - PullRequest
0 голосов
/ 12 июня 2019

Когда я пытаюсь скомпилировать ниже составного триггера, я получаю сообщение об ошибке.Пожалуйста, предложите, что можно сделать, чтобы устранить эту ошибку.

Я пытался использовать обычный триггер, но он выдает ORA-04091 ОШИБКА.

create or replace TRIGGER "WS5108"."AL_PROJECT_ORACLE_CODE_TRG" FOR
    INSERT 
  ON ITIB_REQUESTS 
  COMPOUND TRIGGER
DECLARE  
  V_CODE varchar (200);
  BEGIN
    IF :NEW."J_PROJECT_ORACLE_CODE" IS NULL THEN 
      SELECT distinct (PROJECT_ORACLE_CODE) INTO V_CODE
        FROM ITIB_PROJECT_ORACLE_CODE POC 
        JOIN ITIB_VPDOMAIN VP ON (POC.VP_DOMAIN = VP.VP_DOMAIN) 
       WHERE POC.VP_DOMAIN = (SELECT VP_DOMAIN
                                FROM ITIB_VPDOMAIN
                               WHERE ID = :NEW."VP_DOMAIN")
         AND CAPEX_CATEGORY = :NEW."C_CAPEX_CATEGORY" 
         AND :NEW."C_TOTAL_EURO" <= 250 ;
  END IF;

:NEW.J_PROJECT_ORACLE_CODE := V_CODE;

EXCEPTION

  when no_data_found then

  V_CODE := null ;

    END AL_PROJECT_ORACLE_CODE_TRG;

Я пытаюсь добавить значение для одного столбца в таблице после новой строки, вставленной в эту таблицу, если этот столбецпустой.Это значение столбца я беру из этого условия выбора и новых значений, которые вставляются в таблицу.

1 Ответ

0 голосов
/ 12 июня 2019

Ошибка в названии вашего вопроса является второй из двух; Запустив переформатированный код в вашем вопросе, я вижу:

LINE/COL  ERROR
--------- -------------------------------------------------------------
2/1       PLS-00103: Encountered the symbol "DECLARE" when expecting one of the following:     function pragma procedure subtype type <an identifier>    <a double-quoted delimited-identifier> current cursor delete    exists prior before after instead 
8/9       PLS-00103: Encountered the symbol "JOIN" when expecting one of the following:     , ; for group having intersect minus order start union where    connect 

(с другим номером строки из-за переформатирования). В общем, вы должны исправить первую ошибку, о которой сообщают первыми, поскольку последующие ошибки часто бесполезны и вызваны побочными эффектами более ранних. Это тот случай, здесь. Если вы исправите синтаксис составного триггера, чтобы устранить ошибку, сообщенную для DECLARE, то JOIN больше не будет проблемой:

create or replace TRIGGER "WS5108"."AL_PROJECT_ORACLE_CODE_TRG"
  FOR INSERT 
  ON ITIB_REQUESTS 
  COMPOUND TRIGGER

  BEFORE EACH ROW IS
    V_CODE varchar (200);
  BEGIN
    IF :NEW."J_PROJECT_ORACLE_CODE" IS NULL THEN 
      SELECT distinct PROJECT_ORACLE_CODE INTO V_CODE
...
    END IF;

    :NEW.J_PROJECT_ORACLE_CODE := V_CODE;
  EXCEPTION
    when no_data_found then
      V_CODE := null ;
  END BEFORE EACH ROW;
END AL_PROJECT_ORACLE_CODE_TRG;
/

По сути, основной код тела триггера, который вам нужен был в блоке BEFORE EACH ROW, так как это составной триггер.

Кстати, вы, вероятно, хотите, чтобы V_CODE был объявлен как varchar2, а не varchar или как ITIB_PROJECT_ORACLE_CODE.PROJECT_ORACLE_CODE%TYPE. Если вам нужна эта переменная вообще; присваивание назад полю :NEW, вероятно, хочет быть внутри блока IF (как если бы это было , а не изначально нулевым, вы устанавливаете его на v_code, что равно затем ноль!), но вы также можете выбрать прямо в переменную :NEW. Поэтому я думаю, что вы действительно хотите что-то похожее на:

create or replace TRIGGER WS5108.AL_PROJECT_ORACLE_CODE_TRG
  FOR INSERT 
  ON ITIB_REQUESTS 
  COMPOUND TRIGGER

  BEFORE EACH ROW IS
  BEGIN
    IF :NEW.J_PROJECT_ORACLE_CODE IS NULL THEN 
      SELECT PROJECT_ORACLE_CODE
        INTO :NEW.J_PROJECT_ORACLE_CODE
        FROM ITIB_PROJECT_ORACLE_CODE POC 
        JOIN ITIB_VPDOMAIN VP ON (POC.VP_DOMAIN = VP.VP_DOMAIN) 
       WHERE POC.VP_DOMAIN = (SELECT VP_DOMAIN
                                FROM ITIB_VPDOMAIN
                               WHERE ID = :NEW."VP_DOMAIN")
         AND CAPEX_CATEGORY = :NEW.C_CAPEX_CATEGORY
         AND :NEW.C_TOTAL_EURO <= 250 ;
    END IF;

  EXCEPTION
    when no_data_found then
      null ; -- do nothing; :NEW.J_PROJECT_ORACLE_CODE is already null
  END BEFORE EACH ROW;
END AL_PROJECT_ORACLE_CODE_TRG;
/

Я действительно не понимаю, почему это должен быть составной триггер, хотя вы не обращаетесь к таблице, против которой выступает триггер (как вы это делали в предыдущем вопросе), и у вас есть только один сценарий - только before insert; поэтому здесь будет работать простой триггер:

create or replace WS5108.TRIGGER AL_PROJECT_ORACLE_CODE_TRG
  BEFORE INSERT 
  ON ITIB_REQUESTS
  FOR EACH ROW

BEGIN
  IF :NEW.J_PROJECT_ORACLE_CODE IS NULL THEN 
    SELECT PROJECT_ORACLE_CODE
      INTO :NEW.J_PROJECT_ORACLE_CODE
      FROM ITIB_PROJECT_ORACLE_CODE POC 
      JOIN ITIB_VPDOMAIN VP ON (POC.VP_DOMAIN = VP.VP_DOMAIN) 
     WHERE POC.VP_DOMAIN = (SELECT VP_DOMAIN
                              FROM ITIB_VPDOMAIN
                             WHERE ID = :NEW.VP_DOMAIN)
       AND CAPEX_CATEGORY = :NEW.C_CAPEX_CATEGORY
       AND :NEW.C_TOTAL_EURO <= 250 ;
  END IF;
EXCEPTION
  when no_data_found then
    null ; -- do nothing; :NEW.J_PROJECT_ORACLE_CODE is already null
END AL_PROJECT_ORACLE_CODE_TRG;
/

И даже запрос внутри этого выглядит запутанным; вам не нужен подзапрос:

...
      SELECT PROJECT_ORACLE_CODE
        INTO :NEW.J_PROJECT_ORACLE_CODE
        FROM ITIB_PROJECT_ORACLE_CODE POC 
        JOIN ITIB_VPDOMAIN VP ON (POC.VP_DOMAIN = VP.VP_DOMAIN) 
       WHERE VP.ID = :NEW.VP_DOMAIN
         AND CAPEX_CATEGORY = :NEW.C_CAPEX_CATEGORY
         AND :NEW.C_TOTAL_EURO <= 250 ;
...
...