I created a trigger, and this is the code below, for which I got the above error. I am doing this on Oracle Live SQL. I think it is a Live SQL specific error because the same code doesn't have much problems on a local database. Here is the code below:
create or replace trigger t1
after update or insert or delete
on emp_43
declare
o char(1);
begin
if inserting then
o := 'i';
elsif updating then
o := 'u';
else
o := 'd';
end if;
insert into emp_trail values(o,sysdate);
end;
please help this noob out.
this is the snapshot of the code and error on live sql
correct syntax is
create or replace trigger t1
after update or insert or delete
on emp_43
declare o char(1);
begin
if (inserting) then
o := 'i';
elsif (updating) then
o := 'u';
else
o := 'd';
end if;
insert into emp_trail values(o,sysdate);
end;
Related
I am a beginner using PL/SQL in oracle database, I just want to develop the coding that has been exist before. I want to put new condition and statement IF THEN ELSE NESTED after this code ELSIF updating THEN H_TYP := 'U';
But I am stuck with the my code, I have not yet find the way to fixing my code.
Here is my code;
create or replace TRIGGER TMCI_SUB_ITEM_MASTER_TR_R
AFTER DELETE OR INSERT OR UPDATE ON TMCI_SUB_ITEM_MASTER
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
BEGIN
DECLARE
H_ID TMCI_SUB_ITEM_MASTER_R.HST_ID%TYPE;
H_TYP TMCI_SUB_ITEM_MASTER_R.TSK%TYPE;
rdate DATE;
t_max_rev TMCI_SUB_ITEM_MASTER_R.REV%TYPE;
H_INS_USR_ID TMCI_SUB_ITEM_MASTER_R.INS_USR_ID%TYPE;
BEGIN
rdate := SYSDATE;
IF INSERTING THEN H_TYP := 'I';
...
ELSIF updating THEN H_TYP := 'U';
IF H_INS_USR_ID = 'SL01' THEN
SELECT NVL(MAX(Rev), 0) INTO t_max_rev FROM TMCI_SUB_ITEM_MASTER_R WHERE ITM_CD = :old.ITM_CD;
INSERT INTO TMCI_SUB_ITEM_MASTER_R
VALUES( H_ID,
H_TYP,
:old.ITM_CD,
CASE WHEN :old.ITM_NM <> :new.ITM_NM THEN CONCAT(:new.ITM_NM,'')
ELSE :new.ITM_NM
END);
ELSE
SELECT NVL(MAX(Rev), 0) INTO t_max_rev FROM TMCI_SUB_ITEM_MASTER_R WHERE ITM_CD = :old.ITM_CD;
INSERT INTO TMCI_SUB_ITEM_MASTER_R
VALUES( H_ID,
H_TYP,
:old.ITM_CD,
CASE WHEN :old.ITM_NM <> :new.ITM_NM THEN CONCAT(:new.ITM_NM,'*')
ELSE :new.ITM_NM
END);
END IF;
ELSIF deleting THEN H_TYP := 'D';
...
END IF;
END;
END;
If I login by SL01 result will always read in the last statement (ELSE ...). It should be execute the first statement.
I need a help for fixing this problem.
It looks like you are never setting H_INS_USR_ID to any value. I assume it is meant to the user for the incoming row? If that is the case, then
H_INS_USR_ID TMCI_SUB_ITEM_MASTER_R.INS_USR_ID%TYPE;
becomes
H_INS_USR_ID TMCI_SUB_ITEM_MASTER_R.INS_USR_ID%TYPE := :new.INS_USR_ID;
I'm unable to find what is the issue with this trigger. I'm getting this issue while complicating.
Compilation failed, line 6 (17:42:44) The line numbers associated with compilation errors are relative to the first BEGIN statement. This only affects the compilation of database triggers.
PLS-00103: Encountered the symbol "IF" when expecting one of the following: ;
BEFORE insert or update on "JANC"
for each row
begin
if inserting and :new.id is null then
:new.created_by := nvl(v('APP_USER'), USER);
:new.created := localtimestamp;
end if;
end if;
if updating then
:new.updated_by := nvl(v('APP_USER'), USER);
:new.updated := localtimestamp;
end if;
END;```
I got this error (PLS-00642) when trying to compile a compound trigger. I just learned about types and collections so it is still very confusing.
CREATE OR REPLACE TRIGGER trigger_trecho_teste
FOR DELETE OR UPDATE OF shape ON tr_eixo_lt_ope
COMPOUND TRIGGER
-- Declarative Section (optional)
-- Variables declared here have firing-statement duration.
TYPE num_list IS TABLE OF NUMBER;
trechos num_list;
--Trechos :
TYPE trechos_update IS VARRAY(2) OF sde.st_geometry; -- This will contain old/new or old/null of trechos
TYPE trecho_dict IS TABLE OF trechos_update INDEX BY PLS_INTEGER; -- This is a dictionary of the above, with keys as the cod
trechos_dict trecho_dict;
--Lts :
TYPE trechos_in_lt_to_update IS TABLE OF trechos_update; -- List of trechos above in specific LT
TYPE lt_dict IS TABLE OF trechos_in_lt_to_update INDEX BY PLS_INTEGER; -- Dictionary of the above
lts_dict lt_dict;
-- Auxiliar de iteração :
elem trechos_in_lt_to_update;
--Executed before each row change- :NEW, :OLD are available
BEFORE EACH ROW IS
BEGIN
trechos.extend;
IF UPDATING THEN
trechos(trechos.COUNT) := :NEW.PK_CD_TR_LT_OPE;
trechos_dict(:NEW.PK_CD_TR_LT_OPE) := trechos_update(:OLD.SHAPE, :NEW.SHAPE);
ELSE
trechos(trechos.COUNT) := :OLD.PK_CD_TR_LT_OPE;
trechos_dict(:NEW.PK_CD_TR_LT_OPE) := trechos_update(:OLD.SHAPE, NULL);
END IF;
END BEFORE EACH ROW;
--Executed aftereach row change- :NEW, :OLD are available
AFTER EACH ROW IS
BEGIN
NULL;
END AFTER EACH ROW;
--Executed after DML statement
AFTER STATEMENT IS
BEGIN
-- Construindo o dicionário com as lts e os seus trechos modificados
FOR resultado IN (SELECT FK_CD_LT_OPE cod_lt,FK_CD_TR_LT_OPE cod_trecho FROM EIXO_LT_OPE_COM_TR_EIXO_LT_OPE WHERE FK_CD_TR_LT_OPE MEMBER OF trechos)
LOOP
IF lts_dict.EXISTS(resultado.cod_lt) THEN
lts_dict(resultado.cod_lt).extend;
lts_dict(resultado.cod_lt)(lts_dict(resultado.cod_lt).COUNT) := trechos_dict(cod_trecho);
ELSE
lts_dict(resultado.cod_lt) := trechos_in_lt_to_update(trechos_dict(cod_trecho));
END IF;
END LOOP;
-- Iterando o dicionário construído acima
elem := lts_dict.FIRST;
WHILE elem IS NOT NULL LOOP
elem := lts_dict.next(elem);
cogeo_utils.rebuild_line('tr_eixo_lt_ope', elem, lts_dict(elem));
END LOOP;
END AFTER STATEMENT;
END trigger_trecho_teste;
The error occurs in the lines:
FOR resultado IN (SELECT FK_CD_LT_OPE cod_lt,FK_CD_TR_LT_OPE cod_trecho FROM EIXO_LT_OPE_COM_TR_EIXO_LT_OPE WHERE FK_CD_TR_LT_OPE MEMBER OF trechos)
LOOP
IF lts_dict.EXISTS(resultado.cod_lt) THEN
lts_dict(resultado.cod_lt).extend;
lts_dict(resultado.cod_lt)(lts_dict(resultado.cod_lt).COUNT) := trechos_dict(cod_trecho);
ELSE
lts_dict(resultado.cod_lt) := trechos_in_lt_to_update(trechos_dict(cod_trecho));
END IF;
END LOOP;
Is it because I'm accessing the collections inside the select loop? Is there a simple workaround this?
In Oracle 11g you cannot use collection types declared in PL/SQL in the SQL scope. You need to create them in the SQL scope.
CREATE OR REPLACE TYPE num_list IS TABLE OF NUMBER;
and remove the type declaration from the trigger.
What am I missing here? It's tagging line 5 column 19....that semi-colon has to stay.
CREATE OR REPLACE TRIGGER Patient_Audit_Trigger
BEFORE DELETE OR UPDATE ON Patient
FOR EACH ROW
DECLARE
Operation VARCHAR(6);
BEGIN
IF DELETING THEN
Operation := 'D';
END IF;
IF UPDATING THEN
Operation := 'U';
END IF;
INSERT INTO Patient_Audit (patNo, patName, patAddr, patDOB, changeTime, changeBy, ActionType)
VALUES (:old.patNo, :old.patName, :old.patAddr, :old.patDOB, CURRENT_TIMESTAMP WITH TIME ZONE, USER, Operation);
END;
/
I tried to compile your trigger ( first of all I created Patient and Patient_Audit tables) and the only reason why it was unable to compile is that there is
CURRENT_TIMESTAMP WITH TIME ZONE
which should be
CURRENT_TIMESTAMP
CURRENT_TIME stamp has already time zone , unlike LOCALTIMESTAMP
This compiles
CREATE OR REPLACE TRIGGER Patient_Audit_Trigger
BEFORE DELETE OR UPDATE ON Patient
FOR EACH ROW
DECLARE
Operation VARCHAR(6);
BEGIN
IF DELETING THEN
Operation := 'D';
END IF;
IF UPDATING THEN
Operation := 'U';
END IF;
INSERT INTO Patient_Audit (patNo, patName, patAddr, patDOB, changeTime, changeBy, ActionType)
VALUES (:old.patNo, :old.patName, :old.patAddr, :old.patDOB, current_timestamp, USER, Operation);
END;
/
(Off topic: Note that use of VARCHAR is not encouraged, you should use VARCHAR2)
I have trigger for auditing, which stored the action performed on any row of EMP table.
This trigger works fine, except in some cases (which occurs very rarely, and I cannot identify exact condition) it gives me
Oracle Error: ORA-01400: cannot insert NULL into ("MY_SCHEMA"."HIST_EMP"."ACTION")
CREATE OR REPLACE TRIGGER HIST_EMP_AIUD
AFTER UPDATE OR INSERT OR DELETE
ON EMP
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
v_action VARCHAR2(1) := 'D';
BEGIN
IF INSERTING THEN
v_action := 'A';
ELSIF UPDATING THEN
v_action := 'U';
END IF;
IF DELETING THEN
INSERT INTO hist_emp (source_rowid, source_date, action)
VALUES (:old.rowid, SYSDATE, v_action);
ELSIF INSERTING OR UPDATING THEN
INSERT INTO hist_emp (source_rowid, source_date, action)
VALUES (:new.rowid, SYSDATE, v_action);
END IF;
EXCEPTION
WHEN OTHERS THEN
--Code to Log
-- <some exception handling should be placed here >
END;
This generally happens when I am deleting the row, but I am not sure.
Any thought on why this will be happening? The code looks ok to me...
Something weird is going on with variable v_action initialization, I guess. Try handling all 3 possibilities:
v_action:= null;
IF INSERTING THEN
v_action := 'A';
ELSIF UPDATING THEN
v_action := 'U';
ELSIF DELETING THEN
v_action := 'D';
END IF;