SQL Trigger Compilation Error - sql

I am new to SQL Triggers.
The below trigger gives me a error saying that
Error: PL/SQL: ORA-00942: table or view does not exist
Error: PL/SQL: SQL Statement ignored
create or replace trigger HIST
after update of DATE ON EPISODE
for each row
begin
INSERT INTO HIST SELECT * FROM INSERTED;
end HIST;
Any help would be appreciated.

You can't use INSERTED table on Oracle DB.
You should use new values insetad as below
INSERT INTO HIST (col1,col2)
VALUES (:new.col1,:new.col2)
Here you can find more information about triggers.

Related

Oracle PL/SQL - BEFORE INSERT 'table does not exist' error?

I'm taking my first steps in Pl/SQL and am struggling with triggers. I've tried creating the trigger below but am receiving this error:
Error at line 2: PL/SQL: SQL Statement ignored
PL/SQL: ORA-00942: table or view does not exist
To clarify: I have checked the name of the table over and over, and it does exist. It is also in the same schema as the trigger I'm trying to create. The 'customer_seq.NEXTVAL' refers to a sequence created previously that runs without errors.
The code is as follows:
CREATE TRIGGER new_customer
BEFORE INSERT ON customer
FOR EACH ROW
BEGIN
INSERT INTO customer_id VALUES ('c-', customer_seq.NEXTVAL);
END;
Thanks in advance for any help.
You probably intend something like this:
CREATE TRIGGER new_customer
BEFORE INSERT ON customer
FOR EACH ROW
BEGIN
SELECT customer_seq.NEXTVAL INTO :NEW.customer_id
FROM dual;
END;
It is unclear what the purpose of 'C_' is. If it is part of the customer id, I would advise you to stick to numbers.
Also note that more recent versions of Oracle support generated always as identity -- which is much preferred over defining a sequence and trigger.

Audit Table Trigger

Trying to create a trigger for populating an audit table with old data before changes are made to the base table BOOKS
CREATE OR REPLACE TRIGGER populate_audit_table
BEFORE INSERT OR UPDATE OF cost, retail OR DELETE
ON books
REFERENCING NEW as new OLD as old
FOR EACH ROW
DECLARE
dml_operation varchar2(1) :=
CASE WHEN UPDATING THEN 'U'
WHEN DELETING THEN 'D'
ELSE 'I'
END;
BEGIN
INSERT INTO cost_retail_history
(isbn
,title
,pubid
,pubdate
,cost
,retail
,discount
,category
,dml_operation)
SELECT
(old.isbn
,old.title
,old.pubid
,old.pubdate
,old.cost
,old.retail
,old.discount
,old.category
,new.dml_operation)
FROM BOOKS;
end;
I get the following errors:
Errors: TRIGGER POPULATE_AUDIT_TABLE
Line/Col: 8/7 PL/SQL: SQL Statement ignored
Line/Col: 20/13 PL/SQL: ORA-00907: missing right parenthesis
I also tried using VALUES on the INSERT INTO and not designating a source table ("FROM BOOKS")
....VALUES
(old.isbn
,old.title
,old.pubid
,old.pubdate
,old.cost
,old.retail
,old.discount
,old.category
,new.dml_operation);
end;
And I get the following errors:
Line/Col: 8/7 PL/SQL: SQL Statement ignored
Line/Col: 27/18 PL/SQL: ORA-00984: column not allowed here
I've read and re-read https://docs.oracle.com/cd/A64702_01/doc/server.805/a58225/ch4a.htm#1997457 so I feel like I'm missing something simple and just need a point in the right direction.
Thanks,
EDIT:
I dropped the dml_operation as this wasn't required and followed the advice below, but I am still getting errors:
Current version:
CREATE OR REPLACE TRIGGER cost_retail_history
BEFORE INSERT
OR UPDATE OF cost, retail
OR DELETE
ON books
REFERENCING NEW as new OLD as old
FOR EACH ROW
BEGIN
CASE
WHEN INSERTING THEN
INSERT INTO cost_retail_history
(isbn
,title
,pubid
,pubdate
,cost
,retail
,discount
,category)
VALUES
(:new.isbn
,:new.title
,:new.pubid
,:new.pubdate
,:new.cost
,:new.retail
,:new.discount
,:new.category)
WHEN UPDATING cost, retail OR DELETING THEN
INSERT INTO cost_retail_history
(isbn
,title
,pubid
,pubdate
,cost
,retail
,discount
,category)
VALUES
(:old.isbn
,:old.title
,:old.pubid
,:old.pubdate
,:old.cost
,:old.retail
,:old.discount
,:old.category);
END CASE;
END;
I'm getting the errors:
Errors: TRIGGER COST_RETAIL_HISTORY
Line/Col: 4/9 PL/SQL: SQL Statement ignored
Line/Col: 22/5 PL/SQL: ORA-00933: SQL command not properly ended
I can't tell exactly what line the error is on as this would indicate it's with:
...OR DELETE
and
... ,:new.title
which does not make sense to me.
If you were doing insert ... select ... then you should not have the parentheses around the column list; i.e.:
INSERT INTO cost_retail_history
(isbn
...
,dml_operation)
SELECT
old.isbn
...
,new.dml_operation
FROM BOOKS;
but you should not be selecting from the table the trigger is against - partly because you'll get a mutating table error, and you are attempting to insert an audit row for every row in the base table; but mostly because you already have all of the information you need.
With the values clase you need to prefix the old/new values with a colon:
....VALUES
(:old.isbn
,:old.title
,:old.pubid
,:old.pubdate
,:old.cost
,:old.retail
,:old.discount
,:old.category
,:new.dml_operation);
end;
Read more in the documentation.
Oracle has built-in audit tools but presumably this is an exercise.
I can't tell exactly what line the error is on as this would indicate...
This can be slightly confusing with triggers as they are a mix of SQL and PL/SQL. Because you are getting PL/SQL errors the line numbering starts from the beginning of the PL/SQL part, so here BEGIN is line 1, INSERT is line 4; WHEN UPDATING... is line 22.
Those new errors are just because you don't have a semicolon at the end of the first INSERT statement:
,:new.discount
,:new.category);
-----------------------^
WHEN UPDATING cost, retail OR DELETING THEN
INSERT INTO cost_retail_history
The error is reported against line 22 because that WHEN is where it's expecting to see the semicolon, and the first point it can see the previous SQL command hasn't been completed. The error against line 4 is saying where that not-ended command started; so you're getting two messages for one actual problem.

Oracle SQL trigger - DBMS_OUTPUT.PUT_LINE

I'm creating a trigger within my database, I came across two error that I am not able to fix, I'm pretty sure that those two are relating to my use of DBMS_OUTPUT.PUT_LINE, the rest of the statement does not cause any errors, although it had before.
Errors:
Error(5,3): PL/SQL: SQL Statement ignored
Error(5,15): PL/SQL: ORA-00903: invalid table name
Code:
CREATE TRIGGER INVOICES
BEFORE INSERT OR UPDATE ON BRUINVOICE
FOR EACH ROW
BEGIN
IF :new.BRU_DATE < :new.BRU_PAID_DATE THEN
DBMS_OUTPUT.PUT_LINE('You cannot do that');
ELSE
INSERT INTO table BRUINVOICE
values
from inserted;
END IF;
END;
Check constraints are a better choice (performance-wise) than triggers when it comes to record level validation:
ALTER TABLE bruinvoice
ADD CONSTRAINT validate_bru_date CHECK (BRU_DATE < BRU_PAID_DATE);
Inserting invalid data will raise an error message like the following:
scott#ORCL> insert into bruinvoice values ('21-DEC-14','20-DEC-14');
insert into bruinvoice values ('21-DEC-14','20-DEC-14')
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.VALIDATE_BRU_DATE) violated
I fully agree with cstotzer, a check constraint is much better in your situation at should be the preferred way of doing it. However, just for information this would be the trigger syntax:
CREATE TRIGGER INVOICES
BEFORE INSERT OR UPDATE ON BRUINVOICE
FOR EACH ROW
BEGIN
IF :new.BRU_DATE < :new.BRU_PAID_DATE THEN
RAISE_APPLICATION_ERROR(-20001, 'You cannot do that');
END IF;
END;
You don't need any ELSE, your INSERT or UPDATE will be simply executed in this case.

How to Insert a stored procedure into sql developer

I'm trying to create an INSERT stored procedure in my database using Oracle SQL Developer but I can't seem to figure out what's the problem with this code;
create or replace procedure insert_order
as
BEGIN
INSERT INTO ORDERS (ORDER_NUM, ORDER_DATE, CONDITION, STATUS, CUSTOMER_CUSTOMER_NUM, CUSTOMER_EMPLOYEE_NUM)
VALUES(1, '30/OCT/2007', 'BRANDNEW', 'ORDERD', 103, 1);
end insert_order;
Can you help please?
The error message PL/SQL: SQL Statement ignored, and Error(5,23): PL/SQL: ORA-00984: column not allowed here indicates that the error is with the value '30/OCT/2007' (line 5, column 23), since you are not using the standard format for dates.
You can try TO_DATE('30/OCT/2007') or '2007-10-30'.

Creating a INSERT TRIGGER in different table

I need help on creating a trigger on my table1
that will insert specific columns into table2 from table1.
How can i do that? I am using Oracle 11G XE .
Here is my code:
create trigger AllowanceTrigger
on ex_bulacan
after insert
as
insert into allowance VALUES (PLANT_ORIGIN,SO_NO, SO_STATUS,SO_REMARKS,DRIVER_NAME)
select plant_origin, sales_order_no, status,remarks, driver_name
from ex_bulacan;
go ;
When I run that command I get this error
ORA-04071: missing BEFORE, AFTER or INSTEAD OF keyword
The explanation is:
ORA-04071. 00000 - "missing BEFORE, AFTER or INSTEAD OF keyword"
*Cause: The trigger statement is missing the BEFORE/AFTER/INSTEAD OF clause.
*Action: Specify either BEFORE, AFTER or INSTEAD OF.
There is no "go" statement in PL/SQL, and you have not followed the correct syntax for a trigger definition (it is well documented)
Try this:
create trigger AllowanceTrigger
after insert on ex_bulacan
begin
insert into allowance (PLANT_ORIGIN,SO_NO, SO_STATUS,SO_REMARKS,DRIVER_NAME)
select plant_origin, sales_order_no, status,remarks, driver_name
from ex_bulacan;
end;
I'm not sure whether it does what you intended. It fires once per insert statement, not for each row, and it inserts all rows from ex_bulacan into allowance, not just the ones you just inserted. Maybe what you want is actually:
create trigger AllowanceTrigger
after insert on ex_bulacan
for each row
begin
insert into allowance (PLANT_ORIGIN,SO_NO, SO_STATUS,SO_REMARKS,DRIVER_NAME)
values (:new.plant_origin, :new.sales_order_no, :new.status, :new.remarks,
:new.driver_name);
end;
There is a syntax error in your code. You must specify the trigger in this order:
CREATE TRIGGER AllowanceTrigger
AFTER INSERT
ON ex_bulacan