SQL trigger overwrites data in the column - oracle

I have a problem with trigger created to invoke before insert method.
For example, i have 3 columns in my table and 1 of these columns is inserted by trigger.
When i want to insert all data(into all columns) by myself trigger overwrites data in specified column.
The trigger is specified to invoke before insert command so i though that insert command will overwrite data in column specified in trigger.
Do anyone know how to solve this issue?
Is this possible for me to insert all data by myself when i have created a trigger?

Related

How to write trigger in sql

I have condition to insert record in table for that i want to write trigger.
For an instance : when A code is getting inserted in the table at the same time insert B code as well in that table.
Need trigger query

Dynamically read the columns of the :NEW object in an oracle trigger

I have an oracle trigger that needs to copy values from the updated table to another table.
The problem is that the columns aren't known when the trigger is created. Part of this system allows the table schema to be updated by the application. (don't ask).
Essentially what I want to do is pivot the table to another table.
I have a stored procedure that will do the pivot, but I can't call it as part of the trigger because it does a select on the table being updated. Causing a "mutating" error.
What would be ideal would be to create a dynamic scripts that reads all the column names from user_tab_cols for the updated table, and reads the value from the :new object.
But of course...I can't :)
:NEW doesn't exist at the point the dynamic script is executed. So something like the following would fail:
EXECUTE IMMEDIATE `insert into pivotTable values(:NEW.' || variableWithColumnName ||')';
So, I'm stuck.
I can't read from the table that was updated, and I can't read the value that was updated from the :NEW object.
Is there anyway to accomplish this other than rebuilding the trigger each time the schema is changed?
No. You'll need to rebuild the trigger whenever the table changes.
If you want to get really involved, you could write a procedure that dynamically generated the DDL to CREATE OR REPLACE the trigger by reading user_tab_columns. You could then create a DDL trigger that fired when the table was altered, submitted a job via dbms_job that called the procedure to recreate the trigger. That works but it's a rather large number of moving parts which means that it can fail in all sorts of subtle and spectacular ways particularly if the application that is making schema changes on the fly decides to add columns in the middle of the day.

Insert data into a different column when copying from one table to another in Oracle

I am using an AFTER INSERT row trigger in Oracle 11g to copy specific columns from one table to another on insert. I have the trigger and insert working ok. The problem I have is that I need to insert the new data from one column to a different column when copying it.
The trigger info reads:
BEGIN
insert into BALES_STORAGE
(CROP,
CUTTING,
DESTINATION,
BALES_MOVED,
DATE_MOVED,
PASTURE,
TARGET_LB_PER_DAY)
values
(:new.CROP,
:new.CUTTING,
:new.MOVING_LOCATION,
:new.BALES_MOVED,
:new.DATE_MOVED,
:new.PASTURE,
:new.TARGET_LB_PER_DAY);
END;
The first table is called "BALES_HARVESTED" and the 2nd table the trigger inserts the selected columns into is called "BALES_STORAGE". I need to insert the :new.MOVING_LOCATION data into the column called DESTINATION on the second table.
So my question is: when using an after insert row trigger, how to I change the column that the data is inserted into?
Thanks for any help.
Matthew
Your trigger code worked just fine for me. Not sure what the problem is. The 3rd column in your INSERT statement does the column mapping correctly.
http://sqlfiddle.com/#!4/2d2fd5/1/1
Maybe you have different structures or foreign key constraints. Could you elaborate on what error you get? Does it produce an ORA- error? or does it simply not produce the desired result, but no error?

Trigger to update after insert on the same row

I have a function my_func, the input of this function is one of the column in the same row after insertion, how to achieve this.
I have created the table using,
create table sample_trigger_hash ( INDEXID number(19,0) ,
XMLCOLUMN XMLTYPE ,
CHECKFIELD RAW(30)
) XMLTYPE COLUMN XMLCOLUMN STORE AS BINARY XML;
I am thinking of an insertion statement from DBD::Oracle in perl , with just the first two fields.
The following is my trigger,
CREATE OR REPLACE
TRIGGER hash_trigger
AFTER INSERT ON sample_trigger_hash
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
SELECT my_hash(EXTRACT(:OLD.XMLCOLUMN ,''))
INTO :NEW.CHECKFIELD
FROM dual;
END hash_trigger;
Am getting the error,
ORA-04084: cannot change NEW values for this trigger type
04084. 00000 - "cannot change NEW values for this trigger type"
*Cause: New trigger variables can only be changed in before row
insert or update triggers.
*Action: Change the trigger type or remove the variable reference.
But my requirement is to get the XMLType value after insertion, how to achieve this. If I use CLOB storage option for the XMLType, I am getting the same hash value before storing and after storing. But this is not the case when I store it as binary XML. (an XSI section is added to the binary version) More details in this other question.
Your requirement doesn't make sense. You want to include the hashed value in the newly inserted row, so put the function in a before insert trigger.

How to prevent an Insert Trigger from being fired when no row is inserted?

I have a TABLE1. On this table I created a trigger : AFTER INSERT OR UPDATE OR DELETE
Now, if I do an insert which doesn't insert anything, the trigger will still be fired :
insert into TABLE1 select * from TABLE1 where 1=0;
This query will insert NO ROWS but yet the trigger is still fired.
Is there a way to avoid this ? Is this normal behavior?
Yes, it is normal behaviour. It can be avoided, though doing so requires having 3 triggers:
A BEFORE trigger to set a package boolean variable to FALSE
A FOR EACH ROW trigger to set the variable to TRUE when a row is inserted
The AFTER trigger you have, where you can now check the value of the variable before carrying out its action.
Sounds like overkill? Maybe it is: what are to trying to achieve with your trigger?
This is the normal behaviour, Oracle is expecting to insert row so it fires both BEFORE INSERT and AFTER INSERT triggers, even if no row is inserted. One of the purpose of the AFTER triggers is to do some action after a statement succeeds. This statement succeeded :)
You could count the number of rows affected with a package variable:
set the mypackage.table1_nb_ins variable to 0 in a BEFORE INSERT trigger
increment the counter in a AFTER INESRT FOR EACH ROW trigger
and then perform your AFTER INSERT logic if your counter is greater than 0
Row Triggers
A row trigger is fired each time the table is affected by the triggering statement. For example, if an UPDATE statement updates multiple rows of a table, a row trigger is fired once for each row affected by the UPDATE statement. If a triggering statement affects no rows, a row trigger is not run.
https://docs.oracle.com/cd/B19306_01/server.102/b14220/triggers.htm

Resources