How to invoke/call a sequence inside a trigger - sql

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

Related

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

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

Trying to create a trigger that tracks users changes they make on a table but keep getting error ORA-24344: success with compilation error

CREATE OR REPLACE TRIGGER placement_audit_trigger
BEFORE INSERT OR DELETE OR UPDATE ON LDS_PLACEMENT
FOR EACH ROW
ENABLE
DECLARE
v_user varchar(30);
v_date varchar(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 placement_audit (new_name, old_name, user_name, entry_date, operation)
VALUES(:NEW.PLACEMENT_ID, NULL, v_user, v_date, 'Insert');
ELSIF DELETING THEN
INSERT INTO placement_audit (new_name, old_name, user_name, entry_date, operation)
VALUE (NULL,:OLD.PLACEMENT_ID, v_user, v_date, 'Delete');
ELSIF UPDATING THEN
INSERT INTO placement_audit (new_name, old_name, user_name, entry_date, operation)
VALUES(:NEW.PLACEMENT_ID, :OLD.PLACEMENT_ID, v_user, v_date,'Update');
END IF;
END;
Trying to create a trigger, to track changes in table that a user makes but keep ORA-24344: success with compilation error i have researched and tried to resolve the issues could anyone give me an idea where i'm going wrong or point me in the right direction.
You have a typo, it must be
INSERT INTO placement_audit (new_name, old_name, user_name, entry_date, operation)
VALUES (NULL,:OLD.PLACEMENT_ID, v_user, v_date, 'Delete');
instead of
INSERT INTO placement_audit (new_name, old_name, user_name, entry_date, operation)
VALUE (NULL,:OLD.PLACEMENT_ID, v_user, v_date, 'Delete');
VALUES instead of VALUE
As mentioned in comment there is no need for select ... into ... from dual, so just write:
CREATE OR REPLACE TRIGGER placement_audit_trigger
BEFORE INSERT OR DELETE OR UPDATE ON LDS_PLACEMENT
FOR EACH ROW
ENABLE
BEGIN
IF INSERTING THEN
INSERT INTO placement_audit (new_name, old_name, user_name, entry_date, operation)
VALUES (:NEW.PLACEMENT_ID, NULL, USER, SYSDATE, 'Insert');
ELSIF DELETING THEN
INSERT INTO placement_audit (new_name, old_name, user_name, entry_date, operation)
VALUES (NULL,:OLD.PLACEMENT_ID, USER, SYSDATE, 'Delete');
ELSIF UPDATING THEN
INSERT INTO placement_audit (new_name, old_name, user_name, entry_date, operation)
VALUES (:NEW.PLACEMENT_ID, :OLD.PLACEMENT_ID, USER, SYSDATE,'Update');
END IF;
END;

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;
/