Ошибка в названии вашего вопроса является второй из двух; Запустив переформатированный код в вашем вопросе, я вижу:
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 ;
...