Oracle 11g cannot run trigger and insert records - oracle

While running this code I am getting Error message.
CREATE TABLE superheoes
(
sh_name VARCHAR2(20)
);
CREATE OR REPLACE TRIGGER superheroes_audit
BEFORE INSERT OR DELETE OR UPDATE ON superheoes
FOR EACH ROW
ENABLE
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 sh_audit (new_name, old_name, user_name, entry_date, operation)
VALUES (:NEW.sh_name, NULL, v_user, v_date, 'Insert');
ELSIF DELETING THEN
INSERT INTO sh_audit (new_name, old_name, user_name, entry_date, operation)
VALUES (NULL, :OLD.sh_name, v_user, v_date, 'Delete');
ELSIF UPDATING THEN
INSERT INTO sh_audit (new_name, old_name, user_name, entry_date, operation)
VALUES ( :NEW.sh_name, :OLD.sh_name, v_user, v_date, 'Update');
END IF;
END;
/
Then upon inserting the values:
INSERT INTO superheoes(sh_name) VALUES ('Supe');
======================================================================
I am getting the following Error message:
Error starting at line : 76 in command -
INSERT INTO superheoes(sh_name) VALUES ('Supe')
Error at Command Line : 76 Column : 13
Error report -
SQL Error: ORA-04098: trigger 'HR.SUPERHEROES_AUDIT' is invalid and failed re-
validation
04098. 00000 - "trigger '%s.%s' is invalid and failed re-validation"
*Cause:
A trigger was attempted to be retrieved for execution and was
found to be invalid. This also means that compilation/authorization
failed for the trigger.
*Action: Options are to resolve the compilation/authorization errors,
disable the trigger, or drop the trigger.

If I create the tables according to the trigger, the trigger works as you wrote it:
CREATE TABLE superheoes (sh_name VARCHAR2(20));
CREATE TABLE sh_audit
(
new_name VARCHAR2(20),
old_name VARCHAR2(20),
user_name VARCHAR2(20),
entry_date VARCHAR2(20),
operation VARCHAR2(20)
);
CREATE OR REPLACE TRIGGER superheroes_audit
BEFORE INSERT OR DELETE OR UPDATE
ON superheoes
FOR EACH ROW
ENABLE
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 sh_audit(
new_name,
old_name,
user_name,
entry_date,
operation
)
VALUES (
:NEW.sh_name,
NULL,
v_user,
v_date,
'Insert'
);
ELSIF DELETING
THEN
INSERT INTO sh_audit(
new_name,
old_name,
user_name,
entry_date,
operation
)
VALUES (
NULL,
:OLD.sh_name,
v_user,
v_date,
'Delete'
);
ELSIF UPDATING
THEN
INSERT INTO sh_audit(
new_name,
old_name,
user_name,
entry_date,
operation
)
VALUES (
:NEW.sh_name,
:OLD.sh_name,
v_user,
v_date,
'Update'
);
END IF;
END;
/
The trigger is compiled and works:
SQL> INSERT INTO superheoes(sh_name) VALUES ('Supe');
1 row created.
SQL> select * from sh_audit;
NEW_NAME OLD_NAME USER_NAME ENTRY_DATE OPERATION
-------------------- -------------------- -------------------- -------------------- --------------------
Supe ALEK 21/DIC/2016 15:25:37 Insert
I would check the table structure, schema, privileges, ...

Try this: Its working. Also check if you have execute privilege.
SQL> SELECT * FROM DBA_SYS_PRIVS where grantee = 'SYSUSR' and privilege = 'EXECUTE ANY PROCEDURE' ;
GRANTEE PRIVILEGE ADM
------------------------------ ---------------------------------------- ---
SYSUSR EXECUTE ANY PROCEDURE NO
Trigger:
CREATE OR REPLACE TRIGGER superheroes_audit
BEFORE INSERT OR DELETE OR UPDATE
ON superheoes
FOR EACH ROW
BEGIN
-- SELECT USER, TO_CHAR (SYSDATE, 'DD/MON/YYYY HH24:MI:SS')
-- INTO v_user, v_date
-- FROM DUAL;
IF INSERTING
THEN
INSERT INTO sh_audit (new_name,
old_name,
user_name,
entry_date,
operation)
VALUES (:NEW.sh_name,
NULL,
USER,
TO_CHAR (SYSDATE, 'DD/MON/YYYY HH24:MI:SS'),
'Insert');
ELSIF DELETING
THEN
INSERT INTO sh_audit (new_name,
old_name,
user_name,
entry_date,
operation)
VALUES (NULL,
:OLD.sh_name,
User,
TO_CHAR (SYSDATE, 'DD/MON/YYYY HH24:MI:SS'),
'Delete');
ELSIF UPDATING
THEN
INSERT INTO sh_audit (new_name,
old_name,
user_name,
entry_date,
operation)
VALUES (:NEW.sh_name,
:OLD.sh_name,
User,
TO_CHAR (SYSDATE, 'DD/MON/YYYY HH24:MI:SS'),
'Update');
END IF;
END;
/
See Demo for Trigger functionality:
Tables:
CREATE TABLE superheoes (sh_name VARCHAR2 (20));
CREATE TABLE sh_audit (new_name varchar2(20),
old_name varchar2(20),
user_name varchar2(30),
entry_date varchar2(30),
operation varchar2(20));
Execution:
SQL> select * from superheoes;
no rows selected
SQL> select * from sh_audit;
no rows selected
SQL> insert into superheoes values('XING');
1 row created.
SQL> commit;
SQL> select * from sh_audit;
NEW_NAME OLD_NAME USER_NAME
-------------------- -------------------- ------------------------------
ENTRY_DATE OPERATION
------------------------------ --------------------
XING SYSUSR
21/DEC/2016 15:19:41 Insert
SQL> delete from superheoes;
1 row deleted.
SQL> commit;
Commit complete.
SQL> select * from sh_audit;
NEW_NAME OLD_NAME USER_NAME
-------------------- -------------------- ------------------------------
ENTRY_DATE OPERATION
------------------------------ --------------------
XING SYSUSR
21/DEC/2016 15:19:41 Insert
XING SYSUSR
21/DEC/2016 15:20:30 Delete

Related

PLS-00049: bad bind variable 'NEW.NEW_SKILL_DESC'

When I run the trigger the PLS-00049: bad bind variable 'NEW.NEW_SKILL_DESC' problems occur. The problem occurs in the: New section. This is the first time I am auditing a database query.
CREATE OR REPLACE TRIGGER lds_skill_trig
BEFORE INSERT OR DELETE OR UPDATE ON LDS_SKILL
FOR EACH ROW
ENABLE
DECLARE
v_user VARCHAR2(30);
v_date VARCHAR2(30);
BEGIN
SELECT user, TO_CHAR(sysdate, 'DD/M0N/YYYY HH24:MI:SS')
INTO v_user, v_date FROM dual;
IF INSERTING THEN
INSERT INTO db_lds_skill(new_skill_desc, old_skill_desc,user_name,
entry_date, operation)
VALUES(:NEW.new_skill_desc, NULL, v_user, v_date, 'Insert');
ELSIF DELETING THEN
INSERT INTO db_lds_skill(new_skill_desc, old_skill_desc, user_name,
entry_date, operation)
VALUES(NULL, :OLD.new_skill_desc, v_user, v_date, 'Delete');
ELSIF UPDATING THEN
INSERT INTO db_lds_skill(new_skill_desc, old_skill_desc, user_name,
entry_date, operation)
VALUES(:NEW.new_skill_desc, :OLD.new_skill_desc, v_user, v_date,'update');
END IF;
END;
This is the table for db_lds_skill where the audit record i want to save.
CREATE TABLE DB_LDS_SKILL
(NEW_SKILL_DESC VARCHAR2(30),
OLD_SKILL_DESC VARCHAR2(30),
USER_NAME VARCHAR2(30),
ENTRY_DATE VARCHAR2(30),
OPERATION VARCHAR2(30)
);
It seems you are adding wrong column name in the :NEW.new_skill_desc, in The :new. you have to specific the column for the table LDS_SKILL table, not db_lds_skill
The below I created locally and it was working fine, Note that I replaced to_date with to_char and replaced M0N with MON
drop table db_lds_skill
/
create table db_lds_skill
(new_skill_desc varchar2(100) null,
old_skill_desc varchar2(100) null,
user_name varchar2(100) null,
entry_date varchar2(100),
operation varchar2(100) null
)
/
drop table LDS_SKILL
/
create table LDS_SKILL
(new_skill_desc varchar2(100) null,
old_skill_desc varchar2(100) null,
user_name varchar2(100) null,
entry_date varchar2(100) nulll,
operation varchar2(100) null
)
/
CREATE OR REPLACE TRIGGER lds_skill_trig
BEFORE INSERT OR DELETE OR UPDATE ON LDS_SKILL
FOR EACH ROW
ENABLE
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 db_lds_skill(new_skill_desc, old_skill_desc,user_name,
entry_date, operation)
VALUES(:NEW.new_skill_desc, NULL, v_user, v_date, 'Insert');
ELSIF DELETING THEN
INSERT INTO db_lds_skill(new_skill_desc, old_skill_desc, user_name,
entry_date, operation)
VALUES(NULL, :OLD.new_skill_desc, v_user, v_date, 'Delete');
ELSIF UPDATING THEN
INSERT INTO db_lds_skill(new_skill_desc, old_skill_desc, user_name,
entry_date, operation)
VALUES(:NEW.new_skill_desc, :OLD.new_skill_desc, v_user, v_date,'update');
END IF;
END;
/
insert into LDS_SKILL (new_skill_desc) values('pp')
/
commit
/

compiler error while creating trigger in sql developer; [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I have two tables:
create table superheroes('sh_name varchar2(30));
create table sh_audit(new_name varchar2(30), old_name varchar2(30), username varchar2(30), entry_date varchar2(30), operation);
trigger:
create or replace trigger SUPERHEROES_AUDIT
before insert or update or delete on superheroes
for each row
enable
declare
v_user varchar2(30);
v_date varchar2(30);
begin
select user, TO_CHAR(SYSDATE,' DD/MM/YYYY HH24:MI:SS') INTO v_user, v_date from dual;
if inserting then
insert into sh_audit(new_name, old_name, username, entry_date, operation)
values(:NEW.sh_name, null, v_user, v_date,'insert');
elsif deleting then
insert into sh_audit(new_name, old_name, username, entry_date, operation)
values(null, :OLD.sh_name, v_user, v_date,'delete');
elsif updateing then
insert into sh_audit(new_name, old_name, username, entry_date, operation)
values(:NEW.sh_name, :OLD.sh_name, v_user, v_date,'update');
end if;
end;
/
error: Trigger SUPERHEROES_AUDIT compiled Errors: check compiler log
Error(5,5): PL/SQL: Statement ignored Error(11,11): PLS-00201:
identifier 'UPDATEING' must be declared.
try separating the trigger like this:
CREATE OR REPLACE TRIGGER TRG_BI_SUPERHEROES_AUDIT
BEFORE INSERT
ON SUPERHEROES
FOR EACH ROW
ENABLE
BEGIN
INSERT INTO SH_AUDIT (NEW_NAME, OLD_NAME, USERNAME, ENTRY_DATE, OPERATION)
VALUES (
:NEW.SH_NAME,
NULL,
USER,
TO_CHAR (SYSDATE, ' DD/MM/YYYY HH24:MI:SS'),
'insert');
END;
CREATE OR REPLACE TRIGGER TRG_BU_SUPERHEROES_AUDIT
BEFORE UPDATE
ON SUPERHEROES
FOR EACH ROW
ENABLE
BEGIN
INSERT INTO SH_AUDIT (NEW_NAME, OLD_NAME, USERNAME, ENTRY_DATE, OPERATION)
VALUES (
:NEW.SH_NAME,
:OLD.SH_NAME,
USER,
TO_CHAR (SYSDATE, ' DD/MM/YYYY HH24:MI:SS'),
'update');
END;
CREATE OR REPLACE TRIGGER TRG_BD_SUPERHEROES_AUDIT
BEFORE DELETE
ON SUPERHEROES
FOR EACH ROW
ENABLE
BEGIN
INSERT INTO SH_AUDIT (NEW_NAME, OLD_NAME, USERNAME, ENTRY_DATE, OPERATION)
VALUES (
NULL,
:OLD.SH_NAME,
USER,
TO_CHAR (SYSDATE, ' DD/MM/YYYY HH24:MI:SS'),
'insert');
END;

How to display time only

Can anyone help me how can I change the output of Time_done to a time only (example: 5:00AM)? If I add TO_CHAR(SYSDATE, 'HH24:MI:SS') on SYSDATE, I got an error message
ORA-01843: not a valid month.
Below are my codes and screen capture of EVENTLOGS table
CREATE TABLE EVENTLOGS(
Eventlog_id Number(3,0) NOT NULL,
User_name Varchar2(20),
Date_done Date,
Time_done Timestamp,
Action_done Varchar2(50),
CONSTRAINT PK_EVENTLOGS PRIMARY KEY (Eventlog_id));
/* TRIGGER CREATION */
CREATE OR REPLACE TRIGGER SUPERHEROES_AUDIT
AFTER INSERT OR DELETE OR UPDATE ON SUPERHEROES
FOR EACH ROW
ENABLE
DECLARE
V_LOGID NUMBER;
V_USER VARCHAR(30);
V_DATE DATE;
BEGIN
SELECT EVENTLOG_ID_SEQ.NEXTVAL, USER INTO V_LOGID, V_USER FROM DUAL;
IF INSERTING THEN
INSERT INTO EVENTLOGS(Eventlog_id, User_name, Date_done, Time_done, Action_done)
VALUES (V_LOGID, V_USER, SYSDATE, SYSDATE, 'INSERT');
ELSIF DELETING THEN
INSERT INTO EVENTLOGS(Eventlog_id, User_name, Date_done, Action_done)
VALUES (V_LOGID, V_USER, V_DATE, SYSDATE, SYSDATE, 'DELETE');
ELSIF UPDATING THEN
INSERT INTO EVENTLOGS(Eventlog_id, User_name, Date_done, Action_done)
VALUES (V_LOGID, V_USER, V_DATE, SYSDATE, SYSDATE, 'UPDATE');
END IF;
END;
/
[![INSERT INTO
EMPLOYEE_T (EmployeeID, EmployeeName, EmployeeAddress, EmployeeCity, EmployeeState, EmployeeZip, EmployeeBirthDate, EmployeeDateHired, EmployeeSupervisor)
VALUES (2, 'JACKIE', 'AFRICA', 'kenya', 'NO', 11285, TO_DATE('13-OCT-1950', 'DD-MM-YYYY'), TO_DATE('27-JUN-2014', 'DD-MM-YYYY'), 455789);][1]][1]
You have posted an incomplete TRIGGER code with too many errors.
If you are inserting data into a TIMESTAMP column, you need to insert a compatible record. Inserting only time portion is not useful as you cannot do direct date arithmetic / comparison operations which may be required on the column. I have used SYSTIMESTAMP function here to insert current system TIMESTAMP
CREATE OR REPLACE TRIGGER SUPERHEROES_AUDIT
AFTER INSERT OR DELETE OR UPDATE ON SUPERHEROES
FOR EACH ROW
ENABLE
DECLARE
V_LOGID NUMBER;
V_USER VARCHAR(30);
V_DATE DATE;
BEGIN
SELECT EVENTLOG_ID_SEQ.NEXTVAL, USER, SYSDATE INTO V_LOGID, V_USER, V_DATE FROM DUAL;
IF INSERTING THEN
INSERT INTO EVENTLOGS(Eventlog_id, User_name, Date_done, Time_done,Action_done)
VALUES (V_LOGID, V_USER, V_DATE, SYSTIMESTAMP, 'INSERT');
ELSIF DELETING THEN
INSERT INTO EVENTLOGS(Eventlog_id, User_name, Date_done,Time_done, Action_done)
VALUES (V_LOGID, V_USER, V_DATE, SYSTIMESTAMP, 'DELETE');
ELSIF UPDATING THEN
INSERT INTO EVENTLOGS(Eventlog_id, User_name, Date_done,Time_done, Action_done)
VALUES (V_LOGID, V_USER, V_DATE, SYSTIMESTAMP, 'UPDATE');
END IF;
END;
/
Here is the sample data
select * FROM EVENTLOGS;
EVENTLOG_ID USER_NAME DATE_DONE TIME_DONE ACTION_DONE
----------- -------------- --------- ------------------------------- ------------
1 SLDDEVELOPER 13-OCT-17 13-OCT-17 04.58.07.237343000 AM INSERT
If you need only time portion and not the DATE portion in your time_done column, then it should be a VARCHAR2 column and you can use TO_CHAR while inserting in this case as you were attempting to do.
INSERT INTO EVENTLOGS(Eventlog_id, User_name, Date_done, Time_done,Action_done)
VALUES (V_LOGID, V_USER, V_DATE, TO_CHAR(SYSDATE,'HH24:MI:SS'), 'INSERT');

SQL Error: ORA-01843: not a valid month

I am receiving ORA-01843 when I run the Insert command below. Is there something wrong with my code? And got the below error messages:
SQL Error:
ORA-01843: not a valid month
ORA-06512: at "MDSYS.SUPERHEROES_AUDIT", line 8
ORA-04088: error during execution of trigger 'MDSYS.SUPERHEROES_AUDIT'
01843. 00000 - "not a valid month"
What seems to be wrong with my declaration? Thank you.
/* TABLE CREATED */
CREATE TABLE EVENTLOGS(
Eventlog_id Number(3,0) NOT NULL,
User_name Varchar2(20),
Date_done Date,
Action_done Varchar2(50),
CONSTRAINT PK_EVENTLOGS PRIMARY KEY (Eventlog_id));
/* SEQUENCE CREATED */
CREATE SEQUENCE EVENTLOG_ID_SEQ
MINVALUE 1
START WITH 1
INCREMENT BY 1
NOCYCLE
CACHE 10;
/* TRIGGER CREATED */
CREATE OR REPLACE TRIGGER SUPERHEROES_AUDIT
AFTER INSERT OR DELETE OR UPDATE ON SUPERHEROES
FOR EACH ROW
ENABLE
DECLARE
V_LOGID NUMBER;
V_USER VARCHAR(30);
V_DATE VARCHAR(30);
BEGIN
SELECT EVENTLOG_ID_SEQ.NEXTVAL, USER, TO_CHAR(SYSDATE, 'DD/MM/YYYY HH24:MI:SS') INTO V_LOGID, V_USER, V_DATE FROM DUAL;
IF INSERTING THEN
INSERT INTO EVENTLOGS(Eventlog_id, User_name, Date_done, Action_done)
VALUES (V_LOGID, V_USER, V_DATE, 'INSERT');
END IF;
END;
/
INSERT INTO SUPERHEROES VALUES ('TEST');
Your column in the table is defined as
Date_done Date,
You are storing the date into a VARCHAR2 variable
V_DATE VARCHAR(30);
....
SELECT EVENTLOG_ID_SEQ.NEXTVAL, USER,
TO_CHAR(SYSDATE, 'DD/MM/YYYY HH24:MI:SS') INTO V_LOGID, V_USER, V_DATE
...
And you are inserting this variable into the DATE column.
...
VALUES (V_LOGID, V_USER, V_DATE, 'INSERT');
Keep datatype consistent to avoid confusion.

Is possible use a not updated column in trigger body?

I'm coding a DML Trigger for insert update rows in a new table. Trigger will fired only when one single column be updated but... Is possible use into trigger body other column outside UPDATE OF one_single_column clause?
AUDIT TABLE:
CREATE TABLE employees_salary_history(
user_name VARCHAR2(45) NOT NULL,
time_stamp date DEFAULT (sysdate),
employee_id NUMBER(6),
old_salary NUMBER(8, 2),
new_salary NUMBER(8, 2),
percente_raise_salary NUMBER(8, 2));
DML TRIGGER:
CREATE OR REPLACE TRIGGER update_salary_trg
AFTER
UPDATE
OF salary
ON employees23
FOR EACH ROW
DECLARE
v_user VARCHAR2(25);
BEGIN
SELECT user
INTO v_user
FROM dual;
INSERT INTO employees_salary_history
VALUES(
v_user,
sysdate,
employee_id, -- I would like add employee_id about employee that was updated,
:OLD.salary,
:NEW.salary,
TRUNC((:NEW.salary - :OLD.salary) / :OLD.salary * 100, 3)
);
END update_salary_trg;
Trigger works right when I omite "employee_id" column but I would like add employee_id as a reference about the salary updated. When I add employee_id column I receive the following error:
Errors: check compiler log
Errores para TRIGGER HR.UPDATE_SALARY_TRG:
LINE/COL ERROR
-------- ----------------------------------
8/3 PL/SQL: SQL Statement ignored
8/15 PL/SQL: ORA-00913: too many values
This is because the trigger cant reference the employee_id field. In your case New and OLD will be same . So just replace employee_id with either :OLD.employee_id or :NEW. employee_id as shown below. Hope it helps.
CREATE OR REPLACE TRIGGER update_salary_trg
AFTER
UPDATE
OF salary
ON employees23
FOR EACH ROW
DECLARE
v_user VARCHAR2(25);
BEGIN
SELECT user
INTO v_user
FROM dual;
INSERT INTO employees_salary_history --employees_salary_history
VALUES(
v_user,
sysdate,
:NEW.employee_id, -- I would like add employee_id about employee that was updated,
:OLD.salary,
:NEW.salary,
TRUNC((:NEW.salary - :OLD.salary) / :OLD.salary * 100, 3)
);
END update_salary_trg;
Yes it is possible to use any column of employees23-table in the trigger.
If the column was not changed then the values of :old and :new pseudorecords are the same.
So in your case just use :new.employee_id.
Next I recommend you to RTFM: PL/SQL Triggers. It also explains in the details when the pseudorecords are available and what values they hold.

Resources