Oracle SQL - Running scripts - oracle

I'm trying to create an Oracle SQL script that defines the field and triggers for multiple tables as part of my initialization for the implementation of a new project. A sample of what I'm trying to do is shown here;
ALTER TABLE TBL_SAP_VENDORS
DROP COLUMN UPT_TS;
ALTER TABLE TBL_SAP_VENDORS
ADD (
UPT_TS TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- The automatic update of fields has to be performed using a trigger
-- First we drop the trigger incase it already exists
drop trigger vendors_updt_mark;
-- Then add the trigger deffinition
CREATE TRIGGER vendors_updt_mark
before insert or update
on TBL_SAP_VENDORS
FOR EACH ROW
BEGIN
:new.UPT_TS := SYSTIMESTAMP;
END;
-- INVENTORY
ALTER TABLE TBL_SAP_INVENTORY
DROP COLUMN UPT_TS;
ALTER TABLE TBL_SAP_INVENTORY
ADD (
UPT_TS TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- The automatic update of fields has to be performed using a trigger
-- First we drop the trigger incase it already exists
drop trigger inventory_updt_mark;
-- Then add the trigger deffinition
CREATE TRIGGER inventory_updt_mark
before insert or update
on TBL_SAP_INVENTORY
FOR EACH ROW
BEGIN
:new.UPT_TS := SYSTIMESTAMP;
END;
When I try executing this in the Oracle SQL Developer I get the message :
Table TBL_SAP_VENDORS altered.
Table TBL_SAP_VENDORS altered.
Trigger VENDORS_UPDT_MARK dropped.
Trigger VENDORS_UPDT_MARK compiled
LINE/COL ERROR
--------- -------------------------------------------------------------
6/1 PLS-00103: Encountered the symbol "ALTER"
Errors: check compiler log
When I open up the compile log I see:
Error(5,1): PLS-00103: Encountered the symbol "ALTER"
How do I run these commands, of which I have about 20 to run in a single script?
thanks

You have to end the creation of a trigger (or any PL/SQL object, for that matter), with a slash on its own line.
...
CREATE TRIGGER vendors_updt_mark
before insert or update
on TBL_SAP_VENDORS
FOR EACH ROW
BEGIN
:new.UPT_TS := SYSTIMESTAMP;
END;
/
....

Related

How do I create a trigger with the below problem statement?

I am trying to create a trigger named transaction_type_af_insert that is triggered whenever a new record is inserted into ransaction_type table. This trigger will insert the new type and action into the table transaction_type_log_history after the insertion of transaction type details. The action name in the affected log table transaction_type_log_history is 'After_Insert_transaction_type'.
But facing below error:
Warning: Trigger created with compilation errors.
insert into transaction_type(id,type)values(22,'Credit Card')
*
ERROR at line 1:
ORA-04098: trigger 'P12097.TRANSACTION_TYPE_AF_INSERT' is invalid and failed
re-validation
Please help me resolve the issue
CREATE TRIGGER transaction_type_af_insert
AFTER INSERT
ON transaction_type FOR EACH ROW
DECLARE
type varchar(30)
action varchar(30)
BEGIN
UPDATE transaction_type_log_history
SET action = 'After_Insert_transaction_type'
WHERE transaction_type.id = transaction_type_log_history.id;
END;
You can query the user_errors view to see what is actually wrong; some clients let you show errors as a shortcut after you create the object (SQL Developer, SQLcl, SQL*Plus..) and see the 'Warning: Trigger created with compilation errors' message. With your current code that will say something like:
PLS-00103: Encountered the symbol "(" when expecting one of the following:
; is default authid as force under accessible
type is a reserved word so you can't use that for a local variable name - it's expecting you to be declaring a record type. Changing the name of that variable reveals the next error:
PLS-00103: Encountered the symbol "ACTION" when expecting one of the following:
:= ; not null default character
which is because you don't have semicolons after your declarations.
Fixing that still gets 'ORA-00904: "TRANSACTION_TYPE"."ID": invalid identifier' because your update statement doesn't include the transaction_type table. You can use correlation names to refer to data in the original table row statement the trigger fired against, using :new by default; so this now compiles:
CREATE OR REPLACE TRIGGER transaction_type_af_insert
AFTER INSERT ON transaction_type
FOR EACH ROW
DECLARE
l_type varchar2(30);
l_action varchar2(30);
BEGIN
UPDATE transaction_type_log_history
SET action = 'After_Insert_transaction_type'
WHERE transaction_type_log_history.id = :new.id;
END;
/
db<>fiddle
You aren't actually using either of the the two locally declared variables so you can remove those and the declare keyword.
You also seem to be trying to update the history table instead of inserting a new row there, which the problem statement seems to suggest you should be doing.

Oracle_Trigger: Auto Update Of a Column Based Upon INSERT/UPDATE

This might appear a simple query for most of you, but I am a beginner in Oracle DB.
A table has been created with below script-
CREATE TABLE PLAN_TABLE
(
PL_ID DECIMAL(10,0) PRIMARY KEY NOT NULL
,PL_NAME VARCHAR2(300) DEFAULT NULL
,UPDATED_TS TIMESTAMP DEFAULT SYSDATE NOT NULL
,DELETE_FLAG DECIMAL(10,0) DEFAULT 0 NOT NULL
);
The requirement is to have SYSDATE for UPDATED_TS for any new record inserted into the table and also in case when the DELETE_FLAG is updated to 1. Can it be done by trigger?
The below trigger was created-
CREATE OR REPLACE TRIGGER PT_BEFORE_INSERT_TR
BEFORE INSERT ON PLAN_TABLE
FOR EACH ROW
BEGIN
SELECT SYSDATE INTO :new.UPDATED_TS FROM DUAL;
dbms_output.put_line('Inserted');
END;
/
Below error was encountered while inserting record into the table-
error: ORA-04091: table I60_SCH04.PLAN_TABLE is mutating, trigger/function may not see it
Can you please help in letting me know that where am I committing the mistake? Is there any better way to achieve the requirement based upon INSERT/UPDATE?
The actual error you get is due to the fact that you try to select from a table that you actually are changing. To prevent the issue there are a couple of methods, but in you case things are really simple.
SYSDATE is a function, that you could call directly inside PL/SQL block (which a trigger actually is) and use the value returned to update the set the column value
CREATE OR REPLACE TRIGGER PT_BEFORE_INSERT_TR
BEFORE INSERT ON PLAN_TABLE
FOR EACH ROW
BEGIN
:new.UPDATED_TS := sysdate;
dbms_output.put_line('Inserted');
END;
/
OK, this covers the insert part.
For updating - once again, many options. One could be - change your trigger to BEFORE INSERT OR UPDATE ON PLAN_TABLE.
In this case whenever you issue update or insert - this trigger is fired for each row and updates the date column accordingly.
And of course you could use particular checks available in triggers, something like
IF INSERTING OR UPDATING('DELETE_FLAG') THEN
...
END IF;
and code in the logic you need.

Oracle Trigger inserting row into custom table

I have a Post-Insert Oracle trigger that is simply going to be used to insert a row into a table when the triggered table has a record added to it. My code is a simple insert:
BEGIN
INSERT INTO R5CHECKLISTMAP(CLM_CHKLINECODE, CLM_SYSTEMCODE)
VALUES(10, 'TEST');
END;
However, I get the error:
ORA 01006 - Bind Variable does not exist POST-INSERT 10 Before Binding
I know this has to be something simple, but I cannot figure out what the problem could be.

Store the data of deleted record using trigger

I want to write a trigger which fires on deletion of a record from a table, and inserts a record in another table and uses the details of the record deleted.
Database : Oracle 10g
My trigger looked like this
CREATE or REPLACE TRIGGER myTrigger
AFTER DELETE
ON myTable
REFERENCING NEW AS old_tab
FOR EACH ROW
BEGIN
INSERT INTO ACTIVITYLOG values ('ADMIN',:old_tab.tabletID,'MIGRATION','ERROR','TEST','T','NIL',sysdate)
END;
here :old_tab.tabletID the tabletID is the column of the table myTable in which deletion is done.
I want to save the I and a log that it was deleted.
But when I try deleting a record I get the following error
Error code 4098, SQL state 42000: ORA-04098: trigger 'DB.MYTRIGGER' is
invalid and failed re-validation
P.S. Ran the trigger creation in NetBeans SQL Editor.
Here is the,
EDIT
STRUCTURE OF myTable (Table deletion occurs)
tabletID varchar2(15) PRIMARY KEY
tabletName varchar2(100)
STRUCTURE OF ACTIVITYLOG
username varchar2(15)
tabletKey varchar2(15)
page_ref varchar2(100)
errors varchar2(100)
remarks varchar2(100)
operationcode char(2)
lastupdateip varchar2(20)
lastupdatedate date
Sorry don't have access to SQL PLUS EDITOR.
You should use the :OLD values rather than the :NEW values. The :NEW values in a DELETE trigger (whether BEFORE or AFTER) are blank. This makes sense, because if you think about it the record has logically ceased to exist at this point.
However that is not a source of compilation errors.
"still the same error shows up on deletion. "
I suppose we could spend all day guessing what's wrong so let's stop now. You can discover the compilation errors with this simple query:
select * from user_errors
where name = 'MYTRIGGER'
and type = 'TRIGGER'
"I changed the :NEW to :OLD, and added a semicolan and ran it on SQL
PLUS, and that did the trick"
For the benefit of future here is a version of the trigger which will compile and which will correctly write the required values:
CREATE or REPLACE TRIGGER myTrigger
AFTER DELETE
ON myTable
REFERENCING OLD AS old_tab
FOR EACH ROW
BEGIN
INSERT INTO ACTIVITYLOG values ('ADMIN',:old_tab.tabletID,'MIGRATION','ERROR','TEST','T','NIL',sysdate);
END;
/
The problem is this:
REFERENCING NEW AS old_tab
You've redefined the NEW values with the label "old_tab". This is somewhat like adding #define FALSE TRUE to the top of a program.
Add a semicolon after the insert statement
Because you're using an AFTER DELETE trigger, you only need to access the :OLD values, e.g.:
CREATE or REPLACE TRIGGER myTrigger
AFTER DELETE
ON myTable
FOR EACH ROW
BEGIN
INSERT INTO ACTIVITYLOG values ('ADMIN',:OLD.tabletID,'MIGRATION','ERROR','TEST','T','NIL',sysdate);
END;

Why would a database trigger be invalid in an oracle DB?

I've created a trigger manually (By pasting the SQL from another oracle db into the management console) which auto increments the primary key of a table and when I look at the trigger in the object browser The trigger is listed as invalid.
Why would this be the case?
Here is the SQL that recreates the trigger:
CREATE OR REPLACE TRIGGER "BI_AGENTEVENTDATA"
before insert on "AGENTEVENTDATA"
for each row
begin
select "AGENTEVENTDATA_SEQ".nextval into :NEW.ID from dual;
end; ;
/
ALTER TRIGGER "BI_AGENTEVENTDATA" ENABLE
/
are you sure that the sequence exists and can be used by the trigger?
Try this:
select sequence_name from user_sequences;
Try the trigger without the " . In other words:
CREATE OR REPLACE TRIGGER "BI_AGENTEVENTDATA"
before insert on "AGENTEVENTDATA"
for each row
begin
select AGENTEVENTDATA_SEQ.nextval into :NEW.ID from dual;
end; ;
/
ALTER TRIGGER "BI_AGENTEVENTDATA" ENABLE
/

Resources