Creating Update Trigger
Hello,
I am pretty sure the problem here is ignorance. I am trying to create a trigger that will put the sysdate in a column called MODIFIED anytime the row is updated.
create or replace trigger "INSP_ER_KEY_MOD"
AFTER
update on "INSP_ER_KEY"
begin
update INSP_ER_KEY set MODIFIED = sysdate;
end;Thank you,
Adam
Hello
What is missing from the code Tony posted is the 'co-relation' name for the column to be updated. By default this is ':new' for the new value of the column.
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_triggers.htm#sthref1228
CREATE OR REPLACE TRIGGER INSP_ER_KEY_MOD
BEFORE UPDATE
ON INSP_ER_KEY
FOR EACH ROW
BEGIN
-- Update updated_date field to current system date
:new.Modified := sysdate; --- changed
END;varad
Similar Messages
-
Help on creating update trigger(urgent)
Hii all,
I have a situation like this
I have 10 different tables like a,b,c,d,e,f
But i have same columns in all tables
like
updated_by,
updated_date
I need to create a procedure and call that procedure in update triggers for all tables
Can anybody help
In creating Procedure and trigger
ThanksThere is nothing wrong with the trigger, but the procedure is another story. You cannot do DML on the table that is firing the trigger inside the trigger, that is the mutating table error.
I am not really sure why you are doing the DML anyway. you have defined a BEFORE UPDATE trigger on k_constituent, and the procedure checks for the existence of a row in the same table where the currt_user_id field is the same as the id of the user making the update. Without knowing anything about the application, this implies one of two things to me. Either you are trying to make sure the row to be updated does exist, or, this is some kind of security check.
If it is the first, then it is unneccessary, since the before update trigger will only fire if the row to be updated exists viz.
SQL> CREATE OR REPLACE TRIGGER jt_bu
2 BEFORE UPDATE ON JTEST
3 FOR EACH ROW
4
5 BEGIN
6 :new.updby := USER;
7 :new.updon := SYSDATE;
8 DBMS_OUTPUT.Put_Line('Trigger fired ok');
9 END;
10 /
Trigger created.
SQL> SELECT * FROM jtest;
ID DESCR UPDBY UPDON
1 YES OPS$ORACLE 24-APR-03
2 NEWDES OPS$ORACLE 23-APR-03
3 ORACLE OPS$ORACLE 23-APR-03
SQL> UPDATE jtest SET descr = 'NO' WHERE id = 1;
Trigger fired ok
1 row updated.
SQL> UPDATE jtest SET descr = 'NO' WHERE id = 5;
0 rows updated.If you are doing this for security, then you are way too late. The user should not be in the database doing updates if they are not a valid user (whatever valid user means to you).
As a side note, you do realize that if there is more than one record in k_constituent with currt_user_id = updating user, then the procedure will not set update_date and update_by?
TTFN
John -
ADF BC: Creating updatable VO based upon DB View with "instead of" trigger
Hello all,
I have got an interesting issue. I have an Oracle DB view that is used to hide some complexity in the underlying DB design (it does some unions). This view is updatable because we have created an "instead of" update trigger to update the correct table when a row is updated. This is working fine in SQL.
Next, we have created an ADF Entity object based upon the view, specifying an appropriate PK for the DB View. Then, we have created an updatable VO based upon the EO. All well and good so far. The issue we have is in trying to commit changes to the DB - because the ADF BC framework is trying to lock the row to update (using SELECT ... FOR UPDATE), it's not working because of ORA-02014 - cannot select FOR UPDATE from view with DISTINCT, GROUP BY, etc.
This leads me to thinking about overridding doSelect() on the EO as hinted here http://radio.weblogs.com/0118231/stories/2005/07/28/differenceBetweenViewObjectSelectAndEntityDoselectMethod.html
As a temporary test, we have over-ridden the EO's doSelect to call super.doSelect(false) and it does work, although we will have lost update issues as detailed in Steve's article.
My questions:
1). Is overriding doSelect() the correct thing here? Perhaps there is a better way of handling this problem? I do have a base EO class from which all of the EO's extend, so adding this behavior should be straightforward.
2). Does anyone have example doSelect implementation? I am thinking of overriding doSelect for my EO and calling super.doSelect (lock=false), but then I need to deal with some possible exceptions, no?
Kind regards,
JohnHi John,
I have exactly the same issue as you experienced back in January. I have a complex data modelling requirement which requires the need to pivot rows into columns using ROW_NUMBER() and PARTITION clauses. To hide the complexity from the middle tier, I have created a database view and appropriate INSTEAD OF triggers and mapped my EO to the view. I have overriden the lock() method on the EO implementation class (to avoid ORA-02014) and would like to try the same solution you used with the pl/sql call to lock the record.
My question is, how did you manage the release of the lock if the transaction was not rolled back or committed by your application i.e. if the user closed the browser for instance.
In my naivity, I would like to think that the BC4J framework would release any locks for the database session when it found the servlet session to be terminated however my concern is that the lock would persist and cause complications.
Any assistance greatly appreciated (if you would be willing to supply your lock() method and pl/sql procedure logic I would be even more grateful!).
Many thanks,
Dave
London -
Help me in creating a Trigger for Insert and Update Options
Hi
Please help me in creating a Trigger .
My requirement is that after insert or update on a Table , i want to fire an event .
I have started this way ,but doesn't know how to fully implement this .
say i have a dept table
CREATE TRIGGER DepartmentTrigger
AFTER INSERT ON Dept
BEGIN
INSERT INTO mytable VALUES("123","Kiran");
END DepartmentTrigger;
Please tell me how can i put the Update option also .
Thanks in advance .Please tell me how can i put the Update option also .Add "Or Update". ;-)
Here are a few suggestions, but you definitely need to refer to the manual page that the previous poster suggested.
CREATE OR REPLACE TRIGGER DepartmentTrigger
AFTER INSERT Or Update ON Dept
BEGIN
INSERT INTO mytable VALUES(:new.Dept,'DEPT ADDED OR CHANGED');
END DepartmentTrigger;
The "Or Replace" means you can replace the trigger while you're developing without having to type in a drop statement every time. Just change and rerun your script, over and over until you get it right.
Adding "Or Update" or "Or Delete" makes the trigger fire for those events too. Note, you may want seperate triggers in different scripts and with different names for each event. You have to decide if your design really does the same thing whether it's an insert or an update.
:new.Dept is how you would refer to the changed vale of the Dept column (:old.Dept is the prior value). I changed the double quotes on the string in the VALUES clause to single quotes.
Andy -
How can you create a simple insert or update trigger
I am trying to create a simple insert or update trigger to timestamp an xml document when I load it into my XML DB repository but I always get an error trying to compile the trigger.
"ORA-25003: cannot change NEW values for this column type in trigger"
Here is my PL/SQL:
CREATE OR REPLACE TRIGGER "PLCSYSADM"."PLCSYSLOG_TIMESTAMP"
BEFORE
INSERT
OR UPDATE ON "PLCSYSADM"."PLCSYSLOG"
FOR EACH ROW BEGIN
:new.sys_nc_rowinfo$ := xmltype('<datestamp>' || SYSDATE || '</datestamp>');
END;
Does anyone have an example that works ?
Thanks in advance
Niels Montananahttp://developer.apple.com/referencelibrary/HardwareDrivers/idxUSB-date.html
-
I have a table that consists of the following: product_id number, location number, qty number. product_id and location are primary keys.
I want to create a trigger before an update and if the record doesn't exist that is trying to be updated, then I have to create the record.
For example, if I want to do an update of the following:
update inventory set qty = 80 where product_id=13 and location=45;
Let's say that the record doesn't exist, how do I do this with a trigger.Hi,
First of all i would like to clear one thing:
IF you are trying to update any record and that record does not exist in table then trigger will not be called.
"afiedt.buf" 10 lines, 236 characters
1 CREATE OR REPLACE TRIGGER t_trig
2 BEFORE UPDATE ON t
3 FOR EACH ROW
4 BEGIN
5 DBMS_OUTPUT.PUT_LINE('Trigger has been called!!!');
6 EXCEPTION
7 WHEN OTHERS THEN
8 DBMS_OUTPUT.PUT_LINE('IN EXCEPTION:'||SQLERRM);
9* END;
SQL>/
Trigger created.
SQL>DESC t;
Name Null? Type
NAME VARCHAR2(20)
SQL>SELECT * FROM t;
NAME
BBB
1 row selected.
SQL>SET SERVEROUTPUT ON
SQL>
SQL>UPDATE t SET NAME='XXX' WHERE name='AAA';
0 rows updated.
SQL>UPDATE t SET NAME='XXX' WHERE name='BBB';
Trigger has been called!!! <-- Trigger called here
1 row updated.So to achieve your result you have to do it outside the trigger.
If you are updating trougha a procedure, after update statement you can use SQL%ROWCOUNT to get how many rows have been updated. If it zero you can insert the record.
Regards -
How to create conditional update trigger in sql server
How to create conditional update trigger in sql server
You cant create a conditional update trigger. Once you create an update trigger it will get called for every update action. However you could write logic inside it to make it do your activity based on your condition using IF condition statement
Say for example if you've table with 6 columns and you want some logic to be implemented on update trigger only if col3 and col5 are participating in update operation you can write trigger like this
CREATE TRIGGER Trg_TableName_Upd
ON TableName
FOR UPDATE
AS
BEGIN
IF UPDATE(Col3) OR UPDATE (Col5)
BEGIN
....your actual logic here
END
END
UPDATE() function will check if column was involved in update operation and returns a boolean result
Please Mark This As Answer if it helps to solve the issue Visakh ---------------------------- http://visakhm.blogspot.com/ https://www.facebook.com/VmBlogs -
i am creating a trigger i am getting an error
create or replace TRIGGER INS_Discharge
AFTER INSERT
ON Discharge
FOR EACH ROW
AS
declare
vr_DischargeType INT ;
vr_Visit_ID INT ;
vr_Discharge_Date DATE;
vr_VisitDate DATE;
vr_AdmTime varchar(5) ;
vr_TransferID INT ;
vr_BedID AS INT ;
BEGIN
select :NEW.DischargeType into vr_DischargeType
from dual;
select :NEW.Discharge_Date into vr_Discharge_Date
from dual;
select :NEW.VisitDate into vr_VisitDate
from dual;
SELECT VisitDate into vr_VisitDate FROM Visit WHERE Visit_ID = vr_Visit_ID ;
UPDATE Visit SET DischargeType = vr_DischargeType, DischargeDate = vr_Discharge_Date
WHERE Visit_ID = vr_Visit_ID ;
SELECT MAX(Transfer_ID)into vr_TransferID FROM BedSchedule WHERE VisitID = vr_Visit_ID ;
IF vr_DischargeType = 2 then
SELECT Bed_ID into vr_BedID FROM BedSchedule WHERE Transfer_ID = vr_TransferID ;
UPDATE Bed_Mst SET Bed_Status_ID = 1 WHERE Bed_ID = vr_BedID ;
:NEW.Bed_ID :=vr_BedID;
end if;
END ;
Error report:
ORA-04079: invalid trigger specification
04079. 00000 - "invalid trigger specification"
*Cause: The create TRIGGER statement is invalid.
*Action: Check the statement for correct syntax.i have done you said .... i have oracle version 10g
create or replace TRIGGER trUPD_Discharge
AFTER UPDATE
ON Discharge
for each row
AS
declare
vr_DischargeType INT ;
vr_Discharge_Date DATE;
vr_Visit_ID INT ;
vr_CancelStatus INt;
BEGIN
/*select :NEW.DischargeType into vr_DischargeType from dual;
select :NEW.Visit_ID into vr_Visit_ID from dual;
select :NEW.Discharge_Date into vr_Discharge_Date from dual;
select nvl((select :NEW.CancelStatus from dual),0)
into vr_CancelStatus from dual;
If vr_CancelStatus = 0 then
UPDATE Visit SET DischargeType = :NEW.DischargeType,
DischargeDate =:NEW.Discharge_Date WHERE Visit_ID = :NEW.Visit_ID ;
end if;
END;
but still getting same error
Error report:
ORA-04079: invalid trigger specification
04079. 00000 - "invalid trigger specification"
*Cause: The create TRIGGER statement is invalid.
*Action: Check the statement for correct syntax. -
How to create a trigger for particular value insertion?
If I have a Table T, which has columns as A,B,C,D. I want to create a trigger to give an error message if someone inserts or updates T with values in A as '001' AND value in B as '99'
Please reply soon....
Thanksuser8560155 wrote:
I need a trigger only not a constraint...
Why? Is there any valid reason for that?
I tried the above trigger but it was not successful :(
Can I use 'If statements' as well???The below will work..
create table t
a varchar2(10),
b varchar2(10),
c varchar2(10),
d varchar2(10)
create or replace trigger trig1
after insert or update on t
for each row
--"trigger will be fired only when below condition is satisfied"
when ( new.a = '001' or new.b = '99' )
begin
raise_application_error(-20000, 'Invalid value in A or B');
end;
insert into t(a) values('001');
SQL Error: ORA-20000: Invalid value in A or B
ORA-06512: at "SCOTT.TRIG1", line 2
ORA-04088: error during execution of trigger 'SCOTT.TRIG1'
insert into t(a) values('002');
1 rows inserted. -
ApEx 4.1.1: update record in a view with 'instead of update' trigger
I created a form against a view. The view is complex enough which prevents direct updates. To incorporate the update logic I created an 'instead of update' trigger on the view. When I open up the form, do changes, and click 'Apply Changes' button I am getting the following exception
ORA-02014: cannot select FOR UPDATE from view with DISTINCT, GROUP BY, etc.
I understand that the standard 'Automatic Row Processing' process is trying to lock the record before updating using a cursor like
select *
from my_view
for update
and fails. Is it possible to bypass this locking while using the standard APEX processes?
I think I can create a custom PL/SQL process which would execute the UPDATE statement (at least, it works in SQL*Plus), but I would like to know if I can use a standard ApEx functionality for this.Hello,
Sorry for delay.
I had found a feedback about trigger issue when restore SQL Database from a BACPAC file. Microsoft said the fixed will be available in the next major release of DacFx.
Feedback:
SQL Azure fires a trigger when restoring from bacpac
You can refer to the workarounds in the feedback. For example, if there is small amount of triggers on the database, you can try to remove the triggers and then recreate when restore from bacpac file.
Regards,
Fanny Liu
Fanny Liu
TechNet Community Support -
Help needed in creating a trigger
hi,
I am creating a Trigger which keep track of the updates of a particular table.
Whenver a col value is updated i want to insert a row into newtable, with colname,old value and new value.
How do we get to know which col value is changed in a table?
ThanksI have seen the approach you propose (1 row for each column changed) and it is tedious and prone to maintenance headaches. You have to write code for each column, doing compares (remembering to consider NULLs), dealing with different datatypes, etc. You also have to decide how to record inserts and deletes.
An easier trigger-based solution is to create a history table for the table you want to track, with all of the columns from the original, plus whatever else you need for housekeeping. Write an After Insert/Update/Delete trigger on your base table, and populate/insert rows into the history table:
- For inserts, populate and insert row from the :new. values
- For deletes, populate and insert a row from the :old. values
- For updates, popualte and insert a row from the :old. values and another from the :new. values
I would also have a column to designate whether this is an Insert, Delete, Update-Old or Update-New row.
Once you have done one example, the rest are easy. If you were sufficiently motivated (I have not yet been), you could probably write a script to query DBA_TAB_COLS and generate the code. -
Update Trigger for Subinventory in Apps in Prduction Batch deatils
Dear all
we have the Apps Application and on the Production Module when creating Batch the form takes Subinventory as default from the setup i need to update it so i created Tigger on the Table after Insert each row update the subinventory field by fixed one
but nothing updated ?? can any onw help me??
CREATE OR REPLACE TRIGGER APPS.XXEGYPLAST_UPDATE_SUBINVENTORY
AFTER INSERT
ON GME.GME_MATERIAL_DETAILS
REFERENCING NEW AS New OLD AS Old
for each row
DECLARE
pragma autonomous_transaction;
t_new_rec GME_MATERIAL_DETAILS%rowtype ;
NAME: XXEGYPLAST_UPDATE_SUBINVENTORY
PURPOSE:
REVISIONS:
Ver Date Author Description
1.0 18/09/2012 1. Created this trigger.
NOTES:
Automatically available Auto Replace Keywords:
Object Name: XXEGYPLAST_UPDATE_SUBINVENTORY
Sysdate: 18/09/2012
Date and Time: 18/09/2012, 12:21:47 ?, and 18/09/2012 12:21:47 ?
Username: (set in TOAD Options, Proc Templates)
Table Name: GME_MATERIAL_DETAILS (set in the "New PL/SQL Object" dialog)
Trigger Options: (set in the "New PL/SQL Object" dialog)
PROCEDURE populate_new IS
BEGIN
t_new_rec.MATERIAL_DETAIL_ID := :new.MATERIAL_DETAIL_ID ;
t_new_rec.BATCH_ID := :new.BATCH_ID ;
t_new_rec.FORMULALINE_ID := :new.FORMULALINE_ID ;
t_new_rec.LINE_NO := :new.LINE_NO ;
t_new_rec.ITEM_ID := :new.ITEM_ID ;
t_new_rec.LINE_TYPE := :new.LINE_TYPE ;
t_new_rec.PLAN_QTY := :new.PLAN_QTY ;
t_new_rec.ITEM_UM := :new.ITEM_UM ;
t_new_rec.ITEM_UM2 := :new.ITEM_UM2 ;
t_new_rec.ACTUAL_QTY := :new.ACTUAL_QTY ;
t_new_rec.RELEASE_TYPE := :new.RELEASE_TYPE ;
t_new_rec.SCRAP_FACTOR := :new.SCRAP_FACTOR ;
t_new_rec.SCALE_TYPE := :new.SCALE_TYPE ;
t_new_rec.PHANTOM_TYPE := :new.PHANTOM_TYPE ;
t_new_rec.COST_ALLOC := :new.COST_ALLOC ;
t_new_rec.ALLOC_IND := :new.ALLOC_IND ;
t_new_rec.COST := :new.COST ;
t_new_rec.TEXT_CODE := :new.TEXT_CODE ;
t_new_rec.PHANTOM_ID := :new.PHANTOM_ID ;
t_new_rec.ROUNDING_DIRECTION := :new.ROUNDING_DIRECTION ;
t_new_rec.CREATION_DATE := :new.CREATION_DATE ;
t_new_rec.CREATED_BY := :new.CREATED_BY ;
t_new_rec.LAST_UPDATE_DATE := :new.LAST_UPDATE_DATE ;
t_new_rec.LAST_UPDATED_BY := :new.LAST_UPDATED_BY ;
t_new_rec.ATTRIBUTE1 := :new.ATTRIBUTE1 ;
t_new_rec.ATTRIBUTE2 := :new.ATTRIBUTE2 ;
t_new_rec.ATTRIBUTE3 := :new.ATTRIBUTE3 ;
t_new_rec.ATTRIBUTE4 := :new.ATTRIBUTE4 ;
t_new_rec.ATTRIBUTE5 := :new.ATTRIBUTE5 ;
t_new_rec.ATTRIBUTE6 := :new.ATTRIBUTE6 ;
t_new_rec.ATTRIBUTE7 := :new.ATTRIBUTE7 ;
t_new_rec.ATTRIBUTE8 := :new.ATTRIBUTE8 ;
t_new_rec.ATTRIBUTE9 := :new.ATTRIBUTE9 ;
t_new_rec.ATTRIBUTE10 := :new.ATTRIBUTE10 ;
t_new_rec.ATTRIBUTE11 := :new.ATTRIBUTE11 ;
t_new_rec.ATTRIBUTE12 := :new.ATTRIBUTE12 ;
t_new_rec.ATTRIBUTE13 := :new.ATTRIBUTE13 ;
t_new_rec.ATTRIBUTE14 := :new.ATTRIBUTE14 ;
t_new_rec.ATTRIBUTE15 := :new.ATTRIBUTE15 ;
t_new_rec.ATTRIBUTE16 := :new.ATTRIBUTE16 ;
t_new_rec.ATTRIBUTE17 := :new.ATTRIBUTE17 ;
t_new_rec.ATTRIBUTE18 := :new.ATTRIBUTE18 ;
t_new_rec.ATTRIBUTE19 := :new.ATTRIBUTE19 ;
t_new_rec.ATTRIBUTE20 := :new.ATTRIBUTE20 ;
t_new_rec.ATTRIBUTE21 := :new.ATTRIBUTE21 ;
t_new_rec.ATTRIBUTE22 := :new.ATTRIBUTE22 ;
t_new_rec.ATTRIBUTE23 := :new.ATTRIBUTE23 ;
t_new_rec.ATTRIBUTE24 := :new.ATTRIBUTE24 ;
t_new_rec.ATTRIBUTE25 := :new.ATTRIBUTE25 ;
t_new_rec.ATTRIBUTE26 := :new.ATTRIBUTE26 ;
t_new_rec.ATTRIBUTE27 := :new.ATTRIBUTE27 ;
t_new_rec.ATTRIBUTE28 := :new.ATTRIBUTE28 ;
t_new_rec.ATTRIBUTE29 := :new.ATTRIBUTE29 ;
t_new_rec.ATTRIBUTE30 := :new.ATTRIBUTE30 ;
t_new_rec.ATTRIBUTE_CATEGORY := :new.ATTRIBUTE_CATEGORY ;
t_new_rec.LAST_UPDATE_LOGIN := :new.LAST_UPDATE_LOGIN ;
t_new_rec.SCALE_ROUNDING_VARIANCE := :new.SCALE_ROUNDING_VARIANCE ;
t_new_rec.SCALE_MULTIPLE := :new.SCALE_MULTIPLE ;
t_new_rec.CONTRIBUTE_YIELD_IND := :new.CONTRIBUTE_YIELD_IND ;
t_new_rec.CONTRIBUTE_STEP_QTY_IND := :new.CONTRIBUTE_STEP_QTY_IND ;
t_new_rec.WIP_PLAN_QTY := :new.WIP_PLAN_QTY ;
t_new_rec.ORIGINAL_QTY := :new.ORIGINAL_QTY ;
t_new_rec.BY_PRODUCT_TYPE := :new.BY_PRODUCT_TYPE ;
END populate_new ;
BEGIN
-- if :New.created_by = '2078' then
update GME.GME_MATERIAL_DETAILS
set SUBINVENTORY = 'M . B'
where LINE_TYPE = :New.LINE_TYPE
and BATCH_ID = :New.BATCH_ID
and LINE_NO = :New.LINE_NO;
COMMIT;
--end if;
EXCEPTION
WHEN OTHERS THEN
FND_MESSAGE.SET_NAME('GME', 'GME_UNEXPECTED_UPDATE_ERROR');
FND_MESSAGE.SET_TOKEN('ERROR', sqlerrm);
fnd_message.raise_error;
RAISE_APPLICATION_ERROR(-20400,'An error has occured.Please contact your system administrator'||SQLCODE||SQLERRM);
END XXEGYPLAST_UPDATE_SUBINVENTORY;
/If I try to remove anything unused from your long post this is what I get:
+(And please another time format your code - makes it very much easier to read...)+
user11973451 wrote:
CREATE OR REPLACE TRIGGER APPS.XXEGYPLAST_UPDATE_SUBINVENTORY
AFTER INSERT
ON GME.GME_MATERIAL_DETAILS
REFERENCING NEW AS New OLD AS Old
for each row
DECLARE
pragma autonomous_transaction;
BEGIN
update GME.GME_MATERIAL_DETAILS
set SUBINVENTORY = 'M . B'
where LINE_TYPE = :New.LINE_TYPE
and BATCH_ID = :New.BATCH_ID
and LINE_NO = :New.LINE_NO;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
FND_MESSAGE.SET_NAME('GME', 'GME_UNEXPECTED_UPDATE_ERROR');
FND_MESSAGE.SET_TOKEN('ERROR', sqlerrm);
fnd_message.raise_error;
RAISE_APPLICATION_ERROR(-20400,'An error has occured.Please contact your system administrator'||SQLCODE||SQLERRM);
END XXEGYPLAST_UPDATE_SUBINVENTORY;
/That big local procedure wasn't used in your code, so the above is easier to see what you are doing.
And I don't understand what you are trying to do here?
You have an AFTER INSERT trigger that tries with an autonomous transaction to update a column of the same record (and maybe some other records with same LINE_TYPE / BATCH_ID / LINE_NO as well?)
What is the purpose of this?
I think what you maybe is experiencing is, that you execute an insert, then in the trigger you try to update the same record, but to avoid mutating table error you have created the trigger in an autonomous transaction, and therefore the trigger cannot yet see the inserted record as that has not yet been committed.
If the update is supposed to update just one record, then maybe a BEFORE INSERT trigger to just set the value of :new.SUBINVENTORY?
If supposed to update more than one, then exchange your autonomous transaction with one of the better ways of avoiding mutating table error by remembering the rows to update in "for each row" triggers and then do the updates at the end in an after insert trigger without "for each row." -
Creating a Trigger and some Database Design
Here is the scenario, we have the following tables
Orders, OrderDetails, Products, ProductsToInventory, Inventory, and InventoryDetails
Orders is where the orders are saved and their details are in OrderDetails (orderdetails has a column called Type and that type can either be a product, inventory, shipping, fee, so that we can distinguish what each one is in the order)
Products are the products we sell and ProductsToInventory refers each product to the inventory items required for it.
Inventory lists the the name, size, and weight of the item
then InventoryDetails stores the cost, original quantity received, and the current quantity (since the company receives different quantities of the same product at different pricing all the time) (I would appreciate all the comments on this, this is
the best way I thought of doing this but if you have another way i'd appreciate it)
So that's the design, now we created a trigger that basically does this...
When an order is created and a PRODUCT is inserted into the the orderdetails, we will, using trigger, run the following query to insert the INVENTORY into the orderdetails
INSERT INTO OrderDetails (...., OrderDetailPrice)
SELECT ..., OrderDetailPrice?
FROM inserted i INNER JOIN ProductToInventories pt
ON i.productid = pt.id
INNER JOIN Inventories inv
ON pt.InventoryID = inv.InventoryID
LEFT JOIN InventoryDetails idet
ON inv.InventoryID = idet.InventoryDetailInventoryID
WHERE OrderDetailType = "PRODUCT"
This works perfectly fine, however... for the price, we don't know what to do here, since the price is not in the inventory, the price is under the inventorydetails and we will have to look up to that table to see which one has quantity > the quantity
needed here and then grab the price for that and then we need to update the quantity on that as well.Here is the scenario, we have the following tables
Orders, OrderDetails, Products, ProductsToInventory, Inventory, and InventoryDetails
Orders is where .....
Good day TheSQLNewb,
I did not read more than I quote above... This is a starting of a nice story :-) but in the forum and in DBA's life we prefer to get DDL+DML instead of stories.
Please post queries to create the relevant tables (this is DDL by the way), and queries to insert some sample data (DML). with this information we will be able to reproduce the tables in our server and work on them.
Thanks :-)
Ronen Ariely
[Personal Site] [Blog] [Facebook] -
Update trigger is not working...
Hi
I am writing an update trigger.
We have a two DB, one is application DB and other is reporting DB. We are writing trigger on Reporting DB. There is a job schedule for synchronizing the application data to reporting DB , this daly basis synchronization. So when the synchronization runs and if the FUNDING_RULE_TABLE is updated them my trigger gets called.
CREATE OR REPLACE
TRIGGER COMM_EXISTING_REP_TRIGGER AFTER UPDATE OF FR_IR_NAME ON FUNDING_RULE_TABLE
DECLARE
serialno INTEGER;
CURSOR C_CES_REP IS
Select distinct FR_IR_NAME,FR_IR_CODE from FUNDING_RULE_TABLE ;
V_IR_NAME FUNDING_RULE_TABLE.FR_IR_NAME%TYPE;
V_IR_CODE FUNDING_RULE_TABLE.FR_IR_CODE%TYPE;
CURSOR C_CES_COMIT IS
SELECT DISTINCT FR_IR_NAME1,FR_IR_CODE from COMM_EXSTS_COMIT_AGGR;
IR_NAME VARCHAR2(20);
IR_CODE VARCHAR2(10);
BEGIN
OPEN C_CES_REP;
LOOP
FETCH C_CES_REP INTO V_IR_NAME,V_IR_CODE;
IF C_CES_REP%NOTFOUND THEN
EXIT;
END IF;
OPEN C_CES_COMIT;
LOOP
FETCH C_CES_COMIT INTO IR_NAME,IR_CODE;
IF(V_IR_CODE = IR_CODE AND V_IR_NAME = IR_NAME) THEN
EXIT;
ELSE
update COMM_EXSTS_COMIT_AGGR set FR_IR_NAME1 = IR_NAME where FR_IR_CODE = IR_CODE;
END IF;
END LOOP;
CLOSE C_CES_COMIT;
END LOOP;
CLOSE C_CES_REP;
END COMM_EXISTING_REP_TRIGGER;
The problem is:
When the synchronization runs the trigger will gets called and the synchronization prc never stops because of the table locks.
1) why some tables are getting locks? (I think this is becuse some source is waiting for another to release-deadlock)
2) Is there any problem in trigger? (I think there is some problem is trigger)
3) When I comment below part then sync procedure works fine
OPEN C_CES_COMIT;
LOOP
FETCH C_CES_COMIT INTO IR_NAME,IR_CODE;
IF(V_IR_CODE = IR_CODE AND V_IR_NAME = IR_NAME) THEN
EXIT;
ELSE
update COMM_EXSTS_COMIT_AGGR set FR_IR_NAME1 = IR_NAME where FR_IR_CODE = IR_CODE;
END IF;
END LOOP;
CLOSE C_CES_COMIT;
It menas that there is somr problem in trigger because i am reading and updation is performed on the same table "COMM_EXSTS_COMIT_AGGR ".
Is this is the problem?
waitting for ur rply...thx..
Edited by: 931005 on Apr 30, 2012 2:38 AMWelcome to the forum!
Whenever you post provide your 4 digit Oracle version (result of SELECT * FROM V$VERSION).
>
1) why some tables are getting locks? (I think this is becuse some source is waiting for another to release-deadlock)
>
Because you have an UPDATE statement in your inner loop that may lock one or more rows that are updated.
>
2) Is there any problem in trigger? (I think there is some problem is trigger)
>
Many problems
1. The outer query queries the same table that the update trigger is updating. So some rows may never get seen; rows inserted or updated by other sessions. This means the DISTINCT results may not be distinct at all.
2. The cursors select into SCALAR variables so if either cursor returns more than one row the trigger will raise an exception.
3. The nested cursor loops could be replaced by a simple update statement.
4. The original issue of updating the same table queried by your cursor.
Whatever it is you are trying to do - this isn't the way to do it. -
Instead of Update Trigger error
Hi all,
I've been trying to solve this issue from past 4 to 5 days..I am unable to solve...Can someone please help....
I hhave a requirement in which I need to update 4 tables from a single form...I created a view which will get the required fields along with the primary keys from all these 4 tables.
Then I created a Instead of Update trigger as below
CREATE OR REPLACE TRIGGER "HOMEPAGEVIEW_UPDATE"
INSTEAD OF UPDATE ON cts_homepageview
BEGIN
DECLARE
vID NUMBER;
UPDATE cts_hardware_info
SET STATUS_ID = :NEW.STATUS_ID,
COMPUTER_NAME = :NEW.COMPUTER_NAME,
OPERATINGSYSTEM_ID = :NEW.OPERATINGSYSTEM_ID
where computer_id = :NEW.COMPUTER_ID;
UPDATE cts_server_administrator
SET PRIMARY_ADMIN_ID = :NEW.PRIMADMIN_ID,
SECONDARY_ADMIN_ID = :NEW.SECONDADMIN_ID
WHERE ID = :NEW.ID;
UPDATE cts_location_info
SET BUILDING_ROOM_RACK = :NEW.BUILDING_ROOM_RACK
WHERE LOCATION_ID = :NEW.LOCATION_ID;
UPDATE cts_maintenace_info
SET MAINTENANCE_WINDOW = :NEW.MAINTENANCE_WINDOW
WHERE MAINTENANCE_ID = :NEW.MAINTENANCE_ID;
END;
When I try to update a record, am gettting the following error
ORA-20505: Error in DML: p_rowid=488, p_alt_rowid=COMPUTER_ID, p_rowid2=, p_alt_rowid2=. ORA-02014: cannot select FOR UPDATE from view with DISTINCT, GROUP BY, etc.
Error Unable to process row of table CTS_HOMEPAGEVIEW.
OK
I have already posted this question on the forum, but dint get any replies so trying my luck again....Can someone plzzzzzz help...I searched on ths forum for similar requests...Found one post bt hte solution wasnt given...
Thanks,
Shravanthi
Edited by: user0012 on Apr 29, 2009 9:54 AMHi Varad and Andy,
Thank you both for your responses first..I was soo tensed since no one replied to my previous post fr 5 days..
Varad,
With the change Andy told ('Begin & END'), I tried in SQL Workshop updated computer_name (of cts_hardware_info) data in the view..It updated the data. But from the form, it is still giving the same error.
Andy,
Here is my view.. All the table are associated with the cts_hardware_info using computer_id. And using this computer_id I have put all the data together.
CREATE OR REPLACE FORCE VIEW "CTS_HOMEPAGEVIEW" ("COMPUTER_ID", "COMPUTER_NAME", "STATUS_ID", "DESCRIPTION", "OPERATINGSYSTEM_ID", "ID", "PRIMADMIN_ID", "PRIMARYADMIN_PHONE1", "SECONDADMIN_ID", "SECONDARYADMIN_PHONE1", "LOCATION_ID", "BUILDING_ROOM_RACK", "MAINTENANCE_ID", "MAINTENANCE_WINDOW") AS
select g.computer_id,g.computer_name,g.status_id,cts_hardware_status.DESCRIPTION,g.operatingsystem_id,g.id,g.PrimAdmin_ID,g.PrimaryAdmin_Phone1,g.SecondAdmin_ID, g.SecondaryAdmin_PHONE1,g.location_id,g.BUILDING_ROOM_RACK,g.MAINTENANCE_ID,g.MAINTENANCE_WINDOW from
(select e.computer_id,e.computer_name,e.status_id,e.operatingsystem_id,e.id,e.PrimAdmin_ID,e.PrimaryAdmin_Phone1,e.SecondAdmin_ID,e.SecondaryAdmin_PHONE1,
e.location_id,e.BUILDING_ROOM_RACK,f.MAINTENANCE_ID,f.MAINTENANCE_WINDOW from
(select c.computer_id,c.computer_name,c.status_id,c.operatingsystem_id,c.id,c.PrimAdmin_ID,c.PrimaryAdmin_Phone1,c.SecondAdmin_ID,c.SecondaryAdmin_PHONE1,
d.location_id,d.BUILDING_ROOM_RACK from
(select a.computer_id,a.computer_name,a.status_id,a.operatingsystem_id,b.id,b.PrimAdmin_ID,b.PrimaryAdmin_Phone1,b.SecondAdmin_ID,b.SecondaryAdmin_PHONE1 from
(select cts_hardware_info.computer_id,cts_hardware_info.computer_name,cts_hardware_info.status_id,operatingsystem_id from cts_hardware_info) a
left join
(select cts_server_administrator.id,cts_server_administrator.computer_id,cts_administrator_contacts.ADMIN_id as PrimAdmin_ID,Phone1 as PrimaryAdmin_Phone1,
(select ADMIN_id from cts_administrator_contacts where admin_id = CTS_Server_Administrator.Secondary_ADMIN_ID) as SecondAdmin_ID,
(select Phone1 from cts_administrator_contacts where admin_id = CTS_Server_Administrator.Secondary_ADMIN_ID) as SecondaryAdmin_PHONE1
from cts_server_administrator,cts_administrator_contacts where cts_administrator_contacts.admin_id = cts_server_administrator.PRIMARY_ADMIN_ID) b
on a.computer_id = b.computer_id) c
left join
(select location_id,COMPUTER_ID,BUILDING_ROOM_RACK from cts_location_info) d
on c.computer_id = d.computer_id) e
left join
(select MAINTENANCE_ID,COMPUTER_ID,MAINTENANCE_WINDOW from CTS_MAINTENACE_INFO) f
on e.computer_id = f.computer_id) g left join cts_hardware_status on g.status_id = cts_hardware_status.STATUS_ID
Maybe you are looking for
-
Has anyone figured out how to define a print range. Specifically, I'd like to view and print the rightmost (totals) column and the first Titles column? In Appleworks it was rather simple, Options/Set Print Range ~ lock title position. My accountant i
-
anybody have any idea what would cause my wi-fi to state "unable to join network when all other devices are haveing no connection problem.?
-
i'm having trouble finding one that... 1) reads all the mac extra keys - volume up/down, mute, cd eject 2) allows hotkey switching without needing a pc keyboard (scroll lock) to program, and 3) reads dvi from my g4's adc output with it's dvi adapter
-
Hello expert, I am thinking to create Alias for FQDN for the BSP page for SRM EBP(bbpstart). I know there is external alias function from SICF. But that is for the subfix. I want to have alias replacing the fully qualied domain name part. I know we c
-
Migrating to Oracle Reports 6i from Oracle Report 9i
Hi all, We re-compiled original Forms & Reports 6i source code with Oracle 9i Forms & Reports. Forms are working really nice with almost no change at all with Oracle 9ias Forms services and Oracle 8i as db. The Oracle 9ias server is W2k. Will be upgr