Error(20,56): PLS-00049: bad bind variable 'NEW.NEW_NAME' - sql

I am facing this error while creating a trigger.
error - Error(20,56): PLS-00049: bad bind variable 'NEW.NEW_NAME'
if anyone can help it will be appreciated.
Please refer to my code below
Thanks in Advance :)
CREATE OR REPLACE TRIGGER insert_update_delete_employees AFTER
INSERT OR UPDATE OR DELETE ON employees
REFERENCING
OLD AS old
NEW AS new
FOR EACH ROW
ENABLE DECLARE
v_user VARCHAR2(20);
v_count NUMBER;
v_date VARCHAR2(20);
BEGIN
SELECT
user,
to_date(sysdate, 'DD/MON/YYYY HH24:MI:SS')
INTO
v_user,
v_date
FROM
dual;
SELECT
COUNT(1)
INTO v_count
FROM
employees;
IF updating THEN
INSERT INTO audit_table (
table_name,
user_name,
event,
event_date,
table_count,
new_object_name,
old_object_name
) VALUES (
'EMPLOYEES',
v_user,
'UPDATE',
v_date,
v_count,
:new.new_name,
NULL
);
dbms_output.put_line('Table data has been update by user ' || v_user);
SELECT
COUNT(*)
INTO v_count
FROM
employees;
ELSIF inserting THEN
INSERT INTO audit_table (
table_name,
user_name,
event,
event_date,
table_count,
new_object_name,
old_object_name
) VALUES (
'EMPLOYEES',
v_user,
'INSERT',
v_date,
v_count,
:new.new_name,
:old.old_name
);
dbms_output.put_line('Table data has been inserted by user ' || v_user);
SELECT
COUNT(*)
INTO v_count
FROM
employees;
ELSIF deleting THEN
INSERT INTO audit_table (
table_name,
user_name,
event,
event_date,
table_count,
new_object_name,
old_object_name
) VALUES (
'EMPLOYEES',
v_user,
'DELETE',
v_date,
v_count,
NULL,
:old.old_name
);
dbms_output.put_line('Table data has been deleted by user ' || v_user);
SELECT
COUNT(*)
INTO v_count
FROM
employees;`enter code here`
END IF;
END;

As you are using sample database schema, So please use :new.first_name column instead of :new.new_name

Related

How to invoke/call a sequence inside a trigger

I want to auto-increment the table id I have created. This table will save logs about changes made from a certain table in my database. Below is my code and the error I'm getting. Please help me and thank you in advance.
create or replace Trigger PVFC_audit
after insert or delete or update on customer
for each row
declare
v_user varchar2(20);
eventlog_id_go number;
v_date date;
v_time timestamp;
act_done varchar2(20) := case when updating then 'Update' when deleting then 'Delete' else 'Insert' end;
begin
IF eventlog_id IS NULL THEN <--- eventlog_id is the actual column in my eventlogs table
SELECT eventlog_id_seq.NEXTVAL , user, To_Char(sysdate,'DD/MON/YYY'), To_char(CURRENT_TIMESTAMP,'HH12:MI:SS')
INTO eventlog_id_go, v_user, v_date, v_time from dual;
END IF;
if inserting then
insert into eventlogs(eventlog_id, user_name, date_done, time_done, action_done, object_name)
values (eventlog_id_go, v_user, v_date, v_time, act_done , 'customer');
elsif deleting then
insert into eventlogs(eventlog_id, user_name, date_done, time_done, action_done, object_name)
values (eventlog_id_go, v_user, v_date, v_time, act_done,'customer');
elsif updating then
insert into eventlogs(eventlog_id, user_name, date_done, time_done, action_done, object_name)
values (eventlog_id_go, v_user, v_date, v_time, act_done ,'customer');
end if;
end;
-----Below is the sequence I've created-----
CREATE SEQUENCE "SYSTEM"."EVENTLOG_ID_SEQ"
MINVALUE 1
MAXVALUE 9999999999999999999999999999
INCREMENT BY 1
START WITH 1
CACHE 20
NOORDER
NOCYCLE ;
Error(13,4): PLS-00201: identifier 'EVENTLOG_ID' must be declared
eventlog_id is a column from another table named eventlogs
So you can't reference it in a trigger: a trigger only sees the columns of the table which owns it. The solution is just populate the eventlog_id column in the INSERT statement.
Incidentally your trigger has a lot of duplication. You can simplify immensely:
create or replace Trigger PVFC_audit
after insert or delete or update on customer
for each row
declare
act_done varchar2(20) := case when updating then 'Update' when deleting then 'Delete' else 'Insert' end;
begin
if inserting then
act_done := 'INSERT';
elsif deleting then
act_done := 'DELETE';
elsif updating then
act_done := 'UPDATE';
end if;
insert into eventlogs(eventlog_id, user_name, date_done, time_done, action_done, object_name)
values (eventlog_id_seq.NEXTVAL , user, To_Char(sysdate,'DD/MON/YYY'), To_char(CURRENT_TIMESTAMP,'HH12:MI:SS')
, act_done ,'customer');
end;
Not sure why you're populating date_done andtime_done as strings. It would make way more sense to use the correct data types.
insert into eventlogs(eventlog_id, user_name, date_done, time_done, action_done, object_name)
values (eventlog_id_seq.NEXTVAL , user, trunc(sysdate), CURRENT_TIMESTAMP
, act_done ,'customer');
If EVENTLOGS has those columns defined as VARCHAR2 then that is almost definitely a data model bug which will give you grief at some point.
Yo need to reference pseudorecords old/new value
IF :OLD.eventlog_id IS NULL THEN
or
IF :NEW.eventlog_id IS NULL THEN

Cursor for loop error

I am trying to write cursor that would insert into table, but I am receiving error, need help with this. Error that I am receiving is ORA-06550.
DECLARE
CURSOR cur_rating IS
SELECT bc.name, bc.title, bc.checkoutdate, bc.returneddate,
b.categoryname,b.publisher, ba.authorname
FROM bookshelf_checkout bc INNER JOIN bookshelf b
ON bc.title = b.title
INNER JOIN bookshelf_author ba
ON bc.title = ba.title
FOR UPDATE NOWAIT;
lv_totdays_num NUMBER(4) := 0;
lv_rating_txt VARCHAR2(2);
BEGIN
FOR rec_rating IN cur_rating LOOP
lv_totdays_num := rec_rating.returneddate -
rec_rating.checkoutdate;
IF lv_totdays_num <= 10 THEN lv_rating_txt := 'DR';
ELSIF lv_totdays_num <= 25 THEN lv_rating_txt := 'CR';
ELSIF lv_totdays_num <= 35 THEN lv_rating_txt := 'BR';
ELSE lv_rating_txt := 'A';
END IF;
INSERT INTO bookshelf_audit (title, publisher, categoryname,
new_rating, auditdate)
VALUES (rec_rating.title, rec_rating.publisher,
rec_rating.categoryname, lv_rating_txt, sysdate)
WHERE CURRENT OF cur_rating;
END LOOP;
COMMIT;
END;
You need to remove the where clause from your insert ... values statement:
INSERT INTO bookshelf_audit
(title, publisher, categoryname,
new_rating, auditdate)
VALUES
(rec_rating.title, rec_rating.publisher,
rec_rating.categoryname, lv_rating_txt, sysdate)
WHERE CURRENT OF cur_rating;
should be
INSERT INTO bookshelf_audit
(title, publisher, categoryname,
new_rating, auditdate)
VALUES
(rec_rating.title, rec_rating.publisher,
rec_rating.categoryname, lv_rating_txt, sysdate);
The WHERE CURRENT OF clause in an UPDATE or DELETE statement states that the most recent row fetched from the table should be updated or deleted :
UPDATE table_name
SET set_clause
WHERE CURRENT OF cursor_name;
OR
DELETE FROM table_name
WHERE CURRENT OF cursor_name;
but not applicable for an INSERT statement.
So, remove WHERE CURRENT OF cur_rating part only, your code will run. That's make your INSERT statement as :
INSERT INTO bookshelf_audit (title, publisher, categoryname,
new_rating, auditdate)
VALUES (rec_rating.title, rec_rating.publisher,
rec_rating.categoryname, lv_rating_txt, sysdate);

Insert data into staging table in databse trigger on main table

I have below requirement-
I have 2 tables Main Table A ,Staging table B
I have written a before insert trigger on main table A to check some wrong data. If the data is wrong then it will insert into staging table B so that user can view the errors and correct then and then again upload the data.
My issue is -Data is not getting inserted into staging table as I am using raise_form_trigger_failure just after insert statement.Is there any other way to do this?
TRIGGER CODE-
create or replace trigger CCM_TEST
before insert OR UPDATE ON "CCM_MANAGER"
for each row
declare
l_user varchar2(500);
v_user number;
v_cost_centre number;
v_company_code number;
v_show_error varchar2(100);
begin
l_user := NVL(v('APP_USER'), user);
if inserting then
begin
select count(1)
into v_cost_centre
From gl_code_combinations
where segment2=:new.cost_center
and enabled_flag ='Y';
if (v_cost_centre= 0) then
v_show_error:='Cost Centre does not exists!! '||'Cost Centre -'||:new.cost_center;
:new.CHECK_INSERT_FLAG:='Y';
Insert into CCM_MANAGER_STG(COMPANY_CODE,
COST_CENTER,
USER_NAME,
EFFECTIVE_START_DATE,
EFFECTIVE_END_DATE,
CREATED_BY,
CREATION_DATE,
LAST_UPDATED_BY,
LAST_UPDATE_DATE,
LINE_ID,
CHECK_INSERT_FLAG,
SHOW_ERRORS) values
( :new.COMPANY_CODE,
:new.COST_CENTER,
:new.USER_NAME,
:new.EFFECTIVE_START_DATE,
:new.EFFECTIVE_END_DATE,
:new.CREATED_BY,
:new.CREATION_DATE,
:new.LAST_UPDATED_BY,
:new.LAST_UPDATE_DATE,
:new.LINE_ID,
:new.CHECK_INSERT_FLAG,
v_show_error);
end if;
raise_application_error (-20001, 'Cost Centre does not exists!! '||'Cost Centre -'||:new.cost_center||' ');
exception
when others then
--raise_application_error (-20001, sqlerrm);
null;
end;
begin
select count(1)
into v_company_code
From gl_code_combinations
where segment1=:new.company_code
and enabled_flag ='Y';
if (v_company_code= 0) then
v_show_error:='Company Code does not exists!!';
:new.CHECK_INSERT_FLAG:='Y';
Insert into CCM_MANAGER_STG(COMPANY_CODE,
COST_CENTER,
USER_NAME,
EFFECTIVE_START_DATE,
EFFECTIVE_END_DATE,
CREATED_BY,
CREATION_DATE,
LAST_UPDATED_BY,
LAST_UPDATE_DATE,
LINE_ID,
CHECK_INSERT_FLAG,
SHOW_ERRORS) values
( :new.COMPANY_CODE,
:new.COST_CENTER,
:new.USER_NAME,
:new.EFFECTIVE_START_DATE,
:new.EFFECTIVE_END_DATE,
:new.CREATED_BY,
:new.CREATION_DATE,
:new.LAST_UPDATED_BY,
:new.LAST_UPDATE_DATE,
:new.LINE_ID,
:new.CHECK_INSERT_FLAG,
v_show_error);
end if;
raise_application_error (-20001, 'Company Code does not exists!! '||'Company code -'||:new.company_code||' ');
-- Rollback;
exception
when others then
raise_application_error (-20001, sqlerrm);
null;
end;
end if;
end;
First way is autonomous transaction.
Second way is compound trigger.

Getting compilation error in creating trigger in pl/sql

The following code consists of my project on sql. I'm having hard time finding trigger compilation error repeatedly.
Warning: Trigger created with compilation errors.
I'm using oracle SQL.If this code segments is not enough then you can find the whole project in the following link:
https://github.com/Shauqi/PhotoGalleryDatabase.
create table user1
(
user_id number(10) not null,
name varchar(20),
password number(12)
);
create table myaudit
(
new_name varchar2(30),
old_name varchar2(30),
user_name varchar2(30),
entry_date varchar2(30),
operation varchar2(30)
);
set serveroutput on
CREATE OR REPLACE TRIGGER user1audit
BEFORE INSERT OR DELETE OR UPDATE ON user1
FOR EACH ROW
DECLARE
v_user  varchar2 (30); v_date  varchar2(30);
BEGIN
SELECT user, TO_CHAR(sysdate, 'DD/MON/YYYY HH24:MI:SS') INTO v_user, v_date FROM dual;
IF INSERTING THEN
INSERT INTO myaudit (new_name,old_name, user_name, entry_date, operation) VALUES(:NEW.NAME, Null , v_user, v_date, 'Insert');
ELSIF DELETING THEN
INSERT INTO myaudit (new_name,old_name, user_name, entry_date, operation) VALUES(NULL,:OLD.NAME, v_user, v_date, 'Delete');
ELSIF UPDATING THEN
INSERT INTO myaudit (new_name,old_name, user_name, entry_date, operation) VALUES(:NEW.NAME, :OLD.NAME, v_user, v_date,'Update');
END IF;
END;
/
Try this:
CREATE OR REPLACE TRIGGER user1audit
BEFORE INSERT OR DELETE OR UPDATE ON user1
FOR EACH ROW
BEGIN
IF INSERTING THEN
INSERT INTO myaudit (new_name,old_name, user_name, entry_date, operation) VALUES(:NEW.NAME, Null , user, TO_CHAR(sysdate, 'DD/MON/YYYY HH24:MI:SS'), 'Insert');
ELSIF DELETING THEN
INSERT INTO myaudit (new_name,old_name, user_name, entry_date, operation) VALUES(NULL,:OLD.NAME, user, TO_CHAR(sysdate, 'DD/MON/YYYY HH24:MI:SS') , 'Delete');
ELSIF UPDATING THEN
INSERT INTO myaudit (new_name,old_name, user_name, entry_date, operation) VALUES(:NEW.NAME, :OLD.NAME, user, TO_CHAR(sysdate, 'DD/MON/YYYY HH24:MI:SS'),'Update');
END IF;
END;
/

Update Multiple Rows in same table after Update using Trigger

If i update ACK or ReJ column it should update all the other columns with the same GlobalID.
create table t_emp(
empid varchar2(10) not null,
empname varchar2(50),
Dep varchar2(50),
ACk number(5),
REJ number(5),
globalID varchar2(10) default '0'
);
insert into t_emp t values ( 'TM01' , 'Logu','Java',null,null,'01');
insert into t_emp t values ( 'BT01' , 'Logu','Java' ,null,null,'01');
insert into t_emp t values ( 'Oracle01' , 'Logu','DBA' ,null,null,'01');
insert into t_emp t values ( 'Google01' , 'Logu','Design' ,null,null,'0');
insert into t_emp t values ( 'AR02' , 'Uthaya','CRM' ,null,null,'02');
insert into t_emp t values ( 'RIL02' , 'Uthaya','Java' ,null,null,'02');
insert into t_emp t values ( 'EA02' , 'Uthaya','DBA' ,null,null,'02');
insert into t_emp t values ( 'TCS02' , 'Uthaya','Java' ,null,null,null);
insert into t_emp t values ( 'P05' , 'Krish','.Net' ,null,null,'05');
insert into t_emp t values ( 'TCS06' , 'Krish','.Net' ,null,null,'06');
insert into t_emp t values ( 'IBM06' , 'Krish','.Net' ,null,null,'06');
CREATE OR REPLACE TRIGGER t_emp_update
AFTER UPDATE
ON t_emp
FOR EACH ROW
DECLARE
t_Ack varchar2(15);
t_Rej varchar2(15);
t_globalID varchar2(10);
t_empid varchar2(10);
BEGIN
t_globalID := :new.globalID;
t_Ack := :new.ACk;
t_Rej := :new.REJ;
t_empid := :new.empid;
IF t_Ack is not null then
DBMS_OUTPUT.PUT_LINE('t_Ack := ' || t_Ack || ', t_globalID := '|| t_globalID ||', t_empid := '||t_empid);
update t_emp set ACk = t_Ack where globalID = t_globalID and empid != t_empid;
end if;
IF t_Rej is not null then
DBMS_OUTPUT.PUT_LINE('t_REJ := ' || t_Rej || ', t_globalID := '|| t_globalID ||', t_empid := '||t_empid);
update t_emp set Rej = t_Rej where globalID = t_globalID and empid != t_empid;
end if;
END;
update t_emp v set Rej = 1 where empid = 'TCS06';
If I Update empid = 'TCS06' it should Update Internally all rows with same globalID (06).
select * from t_emp order by empname,globalID;
I am getting some errors in this trigger.
ORA-04091: table TEST1.T_EMP is mutating, trigger/function may not see it
ORA-06512: at "TEST1.T_EMP_UPDATE", line 17
ORA-04088: error during execution of trigger 'TEST1.T_EMP_UPDATE'
Kindly Help me ...
This link and this other one should be helpfull to understand the error and how to correct it. Also check sample of an AFTER UPDATE trigger.
Check a similar question here at SO with a detailed answer.
Please refer these links:
INSERT trigger for inserting record in same table(Stackoverflow)
Avoiding Mutating Tables