Oracle SQL Developer: Trigger - plsql

Hello PL/SQL Experts!!
Do you know how can I use the value 'Batman' in
INSERT INTO SUPERHEROES VALUES ('Batman');
so I can have the below output
1 row inserted.
You added Batman
when I run a trigger function? I used the statement below but it does not shows Batman. Thank you in advance! (NOTE: I'm just starting learning sql)
This is a code :
CREATE OR REPLACE TRIGGER TRIG_SUPERHEROES
BEFORE INSERT ON SUPERHEROES
FOR EACH ROW
ENABLE
DECLARE
V_USER VARCHAR(20);
SH_NAME VARCHAR(20);
BEGIN`enter code here`
SELECT USER INTO V_USER FROM DUAL;
DBMS_OUTPUT.PUT_LINE('YOU JUST ADDED NEW RECORD ' ||SH_NAME);
END;

You have to use :new.sh_name.
:old contains the old record state, :new contains the new record state in a for each row trigger.

Related

How do I make a trigger with an increment for the values in a column?

I have two tables TRIP and DRIVER. When a new set of values in inserted into TRIP (to indicate a new trip being made), the values in the column TOTALTRIPMADE (which is currently empty) in the table DRIVER will increase by one. The trigger should recognise which row to update with the select statement I've made.
This is the trigger I've made:
CREATE OR REPLACE TRIGGER updatetotaltripmade
AFTER INSERT ON trip
FOR EACH ROW
ENABLE
BEGIN
UPDATE DRIVER
SET TOTALTRIPMADE := OLD.TOTALTRIPMADE+1
WHERE (SELECT L#
FROM TRIP
INNER JOIN DRIVER
ON TRIP.L# = DRIVER.L#;)
END;
/
However I get this error:
ORA-04098: trigger 'CSCI235.UPDATETOTALTRIPMADE' is invalid and failed re-validation
What should I edit in my code so that my trigger works? Thanks!
One error you made is in trying to reference OLD.TOTALTRIPMADE in your SET clause since no alias OLD exists, and unless the table TRIP contains a TOTALTRIPMADE column then the :OLD record won't contain a TOTALTRIPMADE column either (note that since this is an insert trigger the :OLD record either won't exist or won't contain any meaningful data anyway). Another error is in your WHERE clause where you are selecting L# from TRIP joined to DRIVER, but you aren't linking it back to the DRIVER table that you are attempting to update. Instead just update DRIVER where L# is equal the :NEW value of L# from the trip table. The final error I noticed is your use of , the := assignment operator which is for PLSQL code, however you are using it within SQL so just use = without the colon:
CREATE OR REPLACE TRIGGER updatetotaltripmade
AFTER INSERT ON trip
FOR EACH ROW
ENABLE
BEGIN
UPDATE DRIVER
SET TOTALTRIPMADE = nvl(TOTALTRIPMADE,0)+1
WHERE L# = :NEW.L#;
END;
/
Your code has syntax error due to which the trigger is not compiling,I have modified the trigger and it should get compiled successfully with desired results.Please check and feedback.
Please find below the script to create table and compile the trigger,
drop table trip;
create table trip (trip_id number(10),L# varchar2(10));
drop table driver;
create table driver(driver_id number(10),TOTALTRIPMADE number(10),L# varchar2(10));
drop trigger updatetotaltripmade;
CREATE OR REPLACE TRIGGER updatetotaltripmade
AFTER INSERT ON trip
FOR EACH ROW
ENABLE
DECLARE
BEGIN
UPDATE DRIVER
SET TOTALTRIPMADE = nvl(TOTALTRIPMADE,0) + 1
WHERE DRIVER.L# = :new.L#;
END;
/
select * from ALL_OBJECTS where object_type ='TRIGGER';
Output is below from the tests i did on https://livesql.oracle.com/apex/
There are no issues in the code.The trigger is compiled successfully and is valid.

Statement level trigger

I have a trigger for a table called A_TAB which as only one column A of character type. and I have a another table DUP_A which has same column as TAB_A.Trigger for A_TAB as follows
create or replace trigger A_trig
before insert on A_TAB
for each row
declare
num1 varchar2(50):= null;
pragma autonomous_transaction;
begin
select Wm_Concat(a) into num1 from DUP_A;
if num1 is null
then
num1:=:new.a;
else
num1:=num1||','||:new.a;
end if;
insert into DUP_A values(num1);
delete from DUP_A where rowid<>(select max(rowid) from DUP_A);
commit;
end;
Here I'm concatenating all the values that in newly inserted and inserting it to a single column of DUP_A.
It's working fine but, I need statement level trigger with same functionality
Thank you
You cannot reference data (:new and :old) in a statement level trigger.
Removing "for each row" clause will change row level trigger to statement level trigger .But PL/SQL runtime engine creates and populates
two data structures(:new and :old) that functions much like records only When a row-level trigger is fired

Create a trigger to update time stamp on inserted or updated records?

I am trying to create an Oracle trigger that would update entry_stamp column (type=DATE) on every inserted or updated record for a certain table. Here is my script:
CREATE OR REPLACE TRIGGER mytable_entry_stamp
AFTER INSERT OR UPDATE ON mytable FOR EACH ROW
BEGIN :NEW.entry_stamp := SYSDATE; END;
I am getting this error:
ORA-04084: cannot change NEW values for this trigger type
From Oracle/PLSQL: AFTER UPDATE Trigger:
You can not update the :NEW values.
You can not update the :OLD values.
It appears that Oracle cannot update a record inside AFTER trigger, unlike MSSQL. So it is reserved for logging/audit purposes, i.e. a record can be inserted or updated in another table. After I converted this trigger to BEFORE, it worked flawlessly.

Value of a NEW variable on a trigger not changing, on plsql

I'm loading data through Oracle Apex utilities using a datasheet.
I want to make a trigger that checks for a value on the table from the data loaded, and then changes it depending on what it gets.
The table has 4 columns: id,name,email,type
The data to load is something like this: name,email,type
Now my trigger:
create or replace TRIGGER BI_USER
before insert ON USER
for each row
declare
begin
if :NEW.ID is null then
select USERID_SEQ.nextval into :NEW.ID from dual;
end if;
:NEW.TYPE := 'something else';
end;
The ID works great, it takes a number from the sequence, but :new.type isn't working, it doesn't change.
I also run the SQL insert separately and the same happens.
EDIT:
new.type type is char(1), I wrote it like this just for testing yet it doesn't change...
aah I'm dissapoint of myself, it throws the error just after reading the data and never fires the trigger.
What I was trying to do is that it will have the name of the TYPE column, and put the id from that table into the NEW.type
Is there a way to change the NEW type?
I see what you're trying to do. You want your table to accept an inserted record containing data that will not fit in the width of one of the fields, and you want to use a trigger to "fix" the data so that it will fit.
Unfortunately, this trigger will not help you because the data is validated before your triggers are fired.
An alternative way to get around this may be to use a view with an instead-of trigger. The view would have a column "TYPE" which is based on a string of length 9; the instead-of trigger would convert this to the CHAR(1) for insert into the underlying table.
Try this instead:
select 'something else' into :NEW.TYPE from dual;
If this syntax worked for ID it should also work for TYPE

INSERT inside plsql procedure does not tell how many rows were inserted

i am trying to insert some rows and update some rows inside a pl/sql loop.
however all i get to see is the pl/sql procedure is successfully completed.
i do get to see dbmbs_ouput statements but not the output status of insert and/or update queries.
the serveroutput is set to on.
how do i get to see the status of insert and update rows(namely how many rows were inserted and updated)
In Oracle, the rowcount is not output automatically like it is in SQL Server.
You should do it explicitly:
BEGIN
INSERT
INTO mytable
SELECT …
FROM other_table;
DBMS_OUTPUT.put_line(SQL%ROWCOUNT);
END;

Resources