Table Update Trigger
Hi,
please help me in writing a trigger after update on a table?
Scenario:
if any update is done on Location_Lat or Location_Lon or both fields then the Geom_Loc should be updated through a trigger. and if there is any update of the lat and lon values inside the sdo_geometry type field SDO_GEOM then respectively the Location_Lat and Location_Lon should be updated
We have 3 important fields in a table.
1) Location_Lat -------------- decimal number ( Geographic Location GIS)
2) Location_Lon------------- decimal number (Geographic Location GIS)
3) Geom_Loc----------------SDO_Geometry (Oracle Type for the oracle Spatial (your database should be Spatial Enabled)
Example of SDO_Geometry:-
(here latitude=23 and longitude=25)
SDO_GEOMETRY(3001,8307,null,sdo_elem_info_array(1,1,1,3,1,0),sdo_ordinate_array(23,25,0,0,0,0))
Thanking you in Advance,
Rashed
Hi,
I am very much new to Oracle and PL/SQL, and i dont have any programming experience, i am facing difficulty in writing a logic for these kind of triggers. I wrote this piece of code but it is giving an error
CREATE OR REPLACE TRIGGER TRG_UPD_TBL_SITE
BEFORE UPDATE
OF Location_Lat,Location_Lon,Geom_Loc
ON TBL_SITE
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
pLocation_Lat NUMBER;
pLocation_Lon NUMBER;
BEGIN
pLocation_Lat :=:new.Location_Lat;
pLocation_Lon :=:new.Location_Lon;
-- Example of SDO_Geometry update---------UPDATE TBL_SITE SET TBL_SITE.Geom_Loc=SDO_GEOMETRY(3001,8307,null,sdo_elem_info_array(1,1,1,3,1,0),sdo_ordinate_array(99.99,77.77,0,0,0,0)),TBL_SITE.Location_Lat=99.99,TBL_SITE.Location_Lon=77.77 where TBL_SITE.SITE_ID=21;
UPDATE TBL_SITE
SET TBL_SITE.Geom_Loc=SDO_GEOMETRY(3001,8307,null,sdo_elem_info_array(1,1,1,3,1,0),sdo_ordinate_array(pLocation_Lat,pLocation_Lon,0,0,0,0)),TBL_SITE.Location_Lat=new.Location_Lat,TBL_SITE.Location_Lon=new.Location_Lon
where TBL_SITE.SITE_ID=old.SITE_ID
END TRG_UPD_TBL_SITE;
Thanks
Similar Messages
-
Please send an query for update trigger for those tables .
1: ap_suppliers
2: ap_supplier_sites_all
3: ap_supplier_contacts.
Thanks,
Chaitanya.Hi,
Actually ID and Data are different names in my API. Here I mentioned like that.
Am using Oracle 10g version.
Yes I am going to get the multiple values using this Ref Cursor. The same ref cursor is used in another API of my package.
In this API, the user actually enters Application_id and data. API should insert/update the version_master table with the inputs. See application_id is the foriegn key for app_master table.
The requirement is whenever they enters application_id and data, if application_id already present in the version_master table, then the data should be updated and we should get a status flag for this using Out variable(i.e. using ref cursor only we are showing the status). if the application_id is not present in the version_master table, new record should be inserted. The sequence will generate the version_id for version_master table.
But the Merge statement is working fine for update and insert also. Problem is am unable to see the success or failure through ref cursor. I don't know how exactly I can use this.
If data is NULL the operation should be failed. i.e. I should get Failure status here. But am not getting this.
Please remove the comments here and then check. If I use the NVL2 function I was able to get the status flag, i.e. S or F.
OPEN resultset_o FOR
SELECT NVL2 (data, 'S', 'F')
FROM version_master
WHERE application_id = application_id_i;
1.How the value of data being not null will determine Success of the api and how null failure
2.If the above select statement goes in to exception when others how I will no the failure
I have to achieve the above scenarios.
Please advice me. -
PL/SQL Trying to update a table through trigger on the same table
Hi everyone my name is Edwin and I'm new to this forum. I hope I can learn a lot from this community and over time contribute to it.
The problem I'm facing at the moment is a tough one. I need to update a table (table a) with a value called block_id. This block_id is generated by a procedure I have written myself, the end result is stored in another table (table b). This block_id needs to be generated after certain rows of table a get updated with a trans_id. The trans_id is all the same for these rows in table a, but the generated block_id isn't. In my code I use an after update on collumn a of table a trigger. So if the the collumn gets updated the trigger fires. The trigger calls the procedure that generates the block_id and the procedure generates table b with all the block_id's. But then I want to update the rows in table a with the generated block_id in table b. The problem is that this self-deadlocks.
You might think that this would call a recursive trigger, but I have written code in the trigger that checks if the block_id isn't allready filled in on table a.
Also I really need all the values wich get updated (table a), so I believe a before update is also out of the question.
And the first update of table a is done through an erp-packet and I can't get at that code, otherwise I would just have run my code from there.
Message was edited by:
user625855CREATE OR REPLACE TRIGGER block_id_trigger AFTER UPDATE ON unload_details_tab
DECLARE
current_transport_id NUMBER;
check_value NUMBER;
check_block_id NUMBER;
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
current_transport_id := get_curent_trans_id; --function that gets the current transport_id
check_value := check_site_and_directive(current_transport_id); --function checks if this transport_id should have a block_id
check_block_id := check_for_block_id(current_transport_id); --function checks if there isn't allready a block_id set.
IF check_value = 1 AND check_block_id = 0 THEN
create_blok_id_table(current_transport_id); --this procedure creates the blok_id in temptable
UPDATE unload_details_tab a SET a.block_id = (SELECT DISTINCT b.blok_id FROM temptable b WHERE b.mark = a.mark_1) WHERE a.transport_id = current_transport_id; --this statement should update the table back, if I leave it out everything works fine, but when I leave it I get the self-deadlock error.
ELSE
null;
END IF;
END block_id_trigger;
Ok, I cleaned the code somewhat.
user625855 -
Update trigger on table fr audit purpose to record column level information
Hi,
I want to create a update trigger which will record data in an audit table.
In audit table I want to have columns like old_value_of_Col and new_value_of_Col.
This is easily achievable. But my main concern is to add three more columns having the information of:
1) Which column was updated?
2) Old value of column that was updated
3) New value of column that was updated
If possible, Also if one updates three columns for example, then in such a case. I would like to have three entries in audit table for the corresponding three columns.
Please help.
Thanks in advance.A few approaches to consider.
First, if you are on 11g, take a look at Flashback Data Archive: http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28424/adfns_flashback.htm#ADFNS01011
Second, you can use Fine-Grained Auditing to capture DML statements and bind variables. It is not as easy to reconstruct the before/after picture, but it may be sufficient for some purposes.
For trigger-based solutions, I 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. We used that design becasue there was an actual requirement to produce a report that needed such a structure.
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. -
How can I access the same table within AFTER UPDATE trigger? mutating
I'm trying to have processing done within a before or after update trigger.
reduced what I want to do down to a select within the trigger.
create or replace TRIGGER "AU_TABLE_A"
after update on "TABLE_A"
for each row
declare
l_res_status NUMBER:=0;
l_count NUMBER:=0;
begin
SELECT COUNT(*) INTO l_count
FROM TABLE_A
WHERE ID = :NEW.ID AND STATUS_ID = 9;
end;
Error in mru internal routine: ORA-20001: Error in MRU: row= 1,
ORA-04091: table TABLE_A is mutating, trigger/function may not see it
ORA-06512: at "BHRS.BU_MR_RES_APPR", line 13
ORA-04088: error during execution of trigger 'BHRS.BU_MR_RES_APPR',
update TABLE_A set "ID" = :b1, "STATUS_ID" = :b2, "COMMENTS" = :b3
where "ID" = :p_pk_col
IS THERE A WAY AROUND IT?
Thank you, BillThe very common approach to workaround mutating table problem is passing the table state through the package variables. I.e. - you create a package with one global variable ( say l_count). Then you need
1) a trigger before update for statement - here you counts your rows and set the package variable accordingly.
2) a trigger after update for each row - here you read the rowcount from a package variable and do your actual work
3) a trigger after update for statement - here you reset your package variable.
This approach uses the fact, that mutating table problem occurs only with triggers for each row and the order of execution of different trigger types.
However, counting records in every update statement (whereas not so worse although as doing this for each row within an update) may consume a lot of resources, so, possibly , you can rethink your business needs/approach.
Best regards
Maxim -
How to update two tables with trigger
Hi:
how to update two tables with trigger ?
I have two tables :
(1)ASIA
MI number;
(2)ASIA_P
ID number;
When I insert a new value into the asia.MI ,I also can
insert the same value into the asia_p.id field.
I have write a trigger as follows but it does't work.
create or replace trigger MI_TRG
before insert on asia
for each row
declare
seq number;
begin
select MI_SEQ.Nextval into seq from dual;
:new.MI:=seq;
insert into ASIA_PRO(MI_ID)
values
(seq);
end MI_TRG;
How to realize it ?
thanks
zzmWhy do you say it does not work?
-
Submitting multiple job on teh same table via trigger
Hi All,
I have a trigger that run multiple jobs using dbms_job on the same table. I am trying to refresh two materialized views complete via dbms_job.
Issue is when data is inserted into NET_CAB table , the trigger kicks off the bothe procedures but only the first materialized view is refreshed and not the other one.
Attached is the trigger, the procedure and materialized view
<pre>
create or replace
TRIGGER NET_CAB_TRG
AFTER INSERT OR UPDATE OR DELETE ON NET_CAB
DECLARE
pbl NUMBER;
pbl1 number;
BEGIN
SYS.DBMS_JOB.SUBMIT( JOB => pbl,what => 'P_CAB_PROC;' ) ;
SYS.DBMS_JOB.SUBMIT( JOB => pbl1,what => 'P_CABAS_PROC;') ;
END;
</pre>
<pre>
create or replace
procedure P_CAB_PROC
is
BEGIN
dbms_mview.REFRESH('P_CAB','C');
COMMIT;
END;
</pre>
<pre>
create or replace
procedure P_CABAS_PROC
is
BEGIN
dbms_mview.REFRESH('P_CABAS','C');
COMMIT;
END;
</pre>
<pre>
CREATE MATERIALIZED VIEW P_CAB
BUILD DEFERRED
USING INDEX
REFRESH COMPLETE ON DEMAND
USING DEFAULT LOCAL ROLLBACK SEGMENT
DISABLE QUERY REWRITE
AS
SELECT
seq_nextval AS ID,
NAME,
SEGMENT_ID,
reproject(geometry) AS GEOMETRY
FROM NET_CAB
where sdo_geom.validate_geometry(geometry,0.005) = 'TRUE'
</pre>
<pre>
CREATE MATERIALIZED VIEW P_CABAS
BUILD DEFERRED
USING INDEX
REFRESH COMPLETE ON DEMAND
USING DEFAULT LOCAL ROLLBACK SEGMENT
DISABLE QUERY REWRITE
AS
SELECT
seq_nextval AS ID,
NAME,
SEGMENT_ID,
reproject(geometry) AS GEOMETRY
FROM NET_CAB
where sdo_geom.validate_geometry(geometry,0.005) = 'TRUE'
AND cis > 4;
</pre>
Edited by: CrackerJack on May 22, 2012 8:58 PMI can run many procedures in a job:
BEGIN
SYS.DBMS_SCHEDULER.CREATE_JOB
job_name => 'JOB_REPORT_FPD'
,start_date => TO_TIMESTAMP_TZ('2012/05/31 23:30:00.000000 +07:00','yyyy/mm/dd hh24:mi:ss.ff tzh:tzm')
,repeat_interval => 'FREQ=MONTHLY;BYMONTHDAY=-1'
,end_date => NULL
,job_class => 'DEFAULT_JOB_CLASS'
,job_type => 'PLSQL_BLOCK'
,job_action => '
DECLARE
BEGIN
ibox_file.fpd_nbot_report;
ibox_file.fpd_nbot_report(''NBOT'');
ibox_file.order_report;
COMMIT;
EXCEPTION
WHEN OTHERS THEN ROLLBACK;
END;
,comments => 'USED FOR REPORTING FPD'
SYS.DBMS_SCHEDULER.SET_ATTRIBUTE
( name => 'JOB_REPORT_FPD'
,attribute => 'RESTARTABLE'
,value => FALSE);
SYS.DBMS_SCHEDULER.SET_ATTRIBUTE
( name => 'JOB_REPORT_FPD'
,attribute => 'LOGGING_LEVEL'
,value => SYS.DBMS_SCHEDULER.LOGGING_RUNS);
SYS.DBMS_SCHEDULER.SET_ATTRIBUTE_NULL
( name => 'JOB_REPORT_FPD'
,attribute => 'MAX_FAILURES');
SYS.DBMS_SCHEDULER.SET_ATTRIBUTE_NULL
( name => 'JOB_REPORT_FPD'
,attribute => 'MAX_RUNS');
BEGIN
SYS.DBMS_SCHEDULER.SET_ATTRIBUTE
( name => 'JOB_REPORT_FPD'
,attribute => 'STOP_ON_WINDOW_CLOSE'
,value => FALSE);
EXCEPTION
-- could fail if program is of type EXECUTABLE...
WHEN OTHERS THEN
NULL;
END;
SYS.DBMS_SCHEDULER.SET_ATTRIBUTE
( name => 'JOB_REPORT_FPD'
,attribute => 'JOB_PRIORITY'
,value => 3);
SYS.DBMS_SCHEDULER.SET_ATTRIBUTE_NULL
( name => 'JOB_REPORT_FPD'
,attribute => 'SCHEDULE_LIMIT');
SYS.DBMS_SCHEDULER.SET_ATTRIBUTE
( name => 'JOB_REPORT_FPD'
,attribute => 'AUTO_DROP'
,value => FALSE);
SYS.DBMS_SCHEDULER.ENABLE
(name => 'JOB_REPORT_FPD');
END;
/ -
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 -
After Update Trigger executes twice when single row is uptd thro proc
We have the below trigger in our db. When a single record is updated using a procedure the trigger is executed twice and it inserts two records in other table.
But when i issue an update statement using any sql client tool it is executing only once and inserts only one record in other table.
Can any one please help me to find the reason?
Trigger:*
create or replace TRIGGER CX_HEADER_ESCL_T1 AFTER UPDATE OF STATUS ON CX_HEADER
FOR EACH ROW
DECLARE
"b1-CTRIYJ" boolean := FALSE;
BEGIN
IF UPDATING('STATUS') AND(:NEW.status = 'SUCCESS') THEN
"b1-CTRIYJ" := TRUE;
END IF;
IF "b1-CTRIYJ" = TRUE THEN
INSERT
INTO siebel.s_escl_req(req_id, created, bt_row_id, rule_id, tbl_name, created_by, group_id)
VALUES('11111111', CURRENT_DATE, :NEW.row_id, '1-CTRIYJ', 'CX_HEADER', :NEW.last_upd_by, '1-2CU3');
"b1-CTRIYJ" := FALSE;
END IF;
END;
Procedure:
CREATE OR REPLACE
PROCEDURE CLOSE_BATCH
(ChildRecordCount IN NUMBER, HeaderId IN VARCHAR2, CompletionStatus OUT VARCHAR2) AS
CafeChildCount NUMBER;
BEGIN
select count(*) into CafeChildCount from SIEBEL.CX_CHILD where HEADER_ID=HeaderId;
IF ChildRecordCount = CafeChildCount THEN
update SIEBEL.CX_HEADER set STATUS ='SUCCESS', MODIFICATION_NUM = MODIFICATION_NUM+1 where HEADER_ID=HeaderId;
CompletionStatus := 'SUCCESS';
ELSE
update SIEBEL.CX_CHILD set STATUS='FAILED' where HEADER_ID=HeaderId;
update SIEBEL.CX_HEADER set STATUS='FAILED' where HEADER_ID=HeaderId;
CompletionStatus := 'FAILED';
END IF;
commit;
/*CompletionStatus := 'SUCCESS';*/
EXCEPTION
WHEN OTHERS THEN
CompletionStatus := SQLCODE;
rollback;
END;Your problem seems not be related to the trigger restart issue I have already mentioned because you are using a AFTER UPDATE trigger and not a BEFORE UPDATE trigger:
>
BEFORE Triggers Fired Multiple Times
If an UPDATE or DELETE statement detects a conflict with a concurrent UPDATE, then Oracle Database performs a transparent ROLLBACK to SAVEPOINT and restarts the update. This can occur many times before the statement completes successfully. Each time the statement is restarted, the BEFORE statement trigger is fired again. The rollback to savepoint does not undo changes to any package variables referenced in the trigger. Your package should include a counter variable to detect this situation.
>
If you are sure that you update a single row and that your trigger fires twice and if you can easiily reproduce the issue, I recommend that you contact Oracle Support and create a Service Request for your issue that could be an Oracle bug. -
After Update Trigger not triggering for first update
Hi All,
I have written a Trigger on AP_SUPPLIERS table to update AP_SUPPLIER_SITES_ALL when payment priority gets updated on AP_SUPPLIERS table. Trigger calls a pragma autonomous procedure after update happens, and updates sites table. We are on R12 (12.1.3) with DB 11.2.0.3.0
Somehow this is not working for the first update, after that for every update it is working. Any idea why this might be happening?
Trigger Code:
CREATE OR REPLACE TRIGGER XX_AP_SUPPLIER_SIT_UPD_SYNC
AFTER UPDATE
ON AP.AP_SUPPLIERS
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
l_vendor_id NUMBER;
l_paym_priority NUMBER;
BEGIN
XX_AP_SUPSITE_UPDATE(:NEW.PAYMENT_PRIORITY, :NEW.VENDOR_ID);
EXCEPTION
WHEN OTHERS THEN
RAISE;
END XX_AP_SUPPLIER_SIT_UPD_SYNC;
Procedure Code:
CREATE OR REPLACE PROCEDURE APPS.XX_AP_SUPSITE_UPDATE (p_payment_priority IN NUMBER,p_vendor_id IN NUMBER) AS
PRAGMA AUTONOMOUS_TRANSACTION;
ex_custom EXCEPTION;
PRAGMA EXCEPTION_INIT( ex_custom, -20001 );
BEGIN
UPDATE AP_SUPPLIER_SITES_ALL
SET PAYMENT_PRIORITY =p_payment_priority
WHERE VENDOR_ID = p_vendor_id;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
raise_application_error( -20001, 'Error while updating payment priority on Site '||SQLERRM );
END XX_AP_SUPSITE_UPDATE;Thanks for your replies Saubhik/VT,
now my trigger is compiled. but is not triggering. pl help me to resolve .....
create or replace
TRIGGER AUDIT_DEV.trg2
AFTER DELETE OR UPDATE OF EMP_STATUS ON AUDIT_DEV.AUDIT_PERSONS
FOR EACH ROW
declare
OSUSER varchar2(30);
MACHINE varchar2(30);
logon_time date;
db_user varchar2(30);
USERNAME VARCHAR2(30);
EMP_USER_MODIFIED AUDIT_PERSONS.EMP_USER_MODIFIED%TYPE;
EMP_DATE_MODIFIED AUDIT_PERSONS.EMP_DATE_MODIFIED%TYPE;
EMP_SK AUDIT_PERSONS.EMP_SK%TYPE;
EMP_ID AUDIT_PERSONS.EMP_ID%TYPE;
EMP_NAME AUDIT_PERSONS.EMP_NAME%TYPE;
EMP_RESIGNATION_DATE AUDIT_PERSONS.EMP_RESIGNATION_DATE%TYPE;
BEGIN
select username,osuser,machine,logon_time into db_user,osuser,machine,logon_time from v$session where sid=(select sid from v$mystat where rownum=1);
INSERT INTO AUDIT_DEV.AUDIT_PERSONS_LOG (EMP_USER_MODIFIED,EMP_DATE_MODIFIED,EMP_SK,EMP_ID,EMP_NAME,EMP_RESIGNATION_DATE,EMP_STATUS_OLD,EMP_STATUS_NEW,osuser,db_user,machine)
VALUES(EMP_USER_MODIFIED,EMP_DATE_MODIFIED,EMP_SK,EMP_ID,EMP_NAME,EMP_RESIGNATION_DATE,:old.EMP_status,:new.EMP_status,osuser,db_user,machine );
COMMIT;
END;
09:59:06 AUDIT_DEV@dev>UPDATE AUDIT_DEV.AUDIT_PERSONS SET EMP_STATUS='TEST' WHERE EMP_ID='4234';
EMP_STATUS
TEST
1 row selected.
Elapsed: 00:00:00.01
10:00:03 AUDIT_DEV@dev>commit;
Commit complete.
Elapsed: 00:00:00.01
10:00:17 AUDIT_DEV@dev>select * from AUDIT_persons_log;
no rows selected
Elapsed: 00:00:00.00
10:00:17 AUDIT_DEV@dev>
Edited by: Abk on Nov 4, 2010 10:42 AM -
Hello,
I have this issue where I'm getting the following error when executing an update in a view. Insert command appears to be OK. Any idea on what am I missing?
ORA-01084: invalid argument in OCI call
ORA-06512: at "APPS.XXRVM_TEMP_B_UPD_TR", line 2
ORA-04088: error during execution of trigger 'APPS.XXRVM_TEMP_B_UPD_TR'
-- sample update statement:
update xxrvm_temp_b_v
set text1 = 'ddd'
where text1 = 'aaa'
Thanks,
Rownald
----- object definitions ----
-- Located in TEST1 Dbase
create table xxrvm_temp_b
(text1 varchar2(30)
,text2 varchar2(30)
-- Located in TEST2 Dbase
-- view definition based on table at dblink
create or replace force view xxrvm_temp_b_v
(pri_key, text1, text2) as select rowid pri_key, text1, text2 from xxrvm_temp_b@test1;
-- trigger definition for insert
create or replace trigger xxrvm_temp_b_ins_tr
instead of insert on xxrvm_temp_b_v referencing new as new old as old
for each row
begin
insert into xxrvm_temp_b@test1 (text1, text2)
values (:new.text1, :new.text2);
end;
-- trigger definition for update
create or replace trigger xxrvm_temp_b_upd_tr
instead of update on xxrvm_temp_b_v referencing new as new old as old
for each row
begin
update xxrvm_temp_b@test1
set text1 = :new.text1 ,text2 = :new.text2
where rowid = :new.pri_key;
end;Hello:
Check if the update works if you re-write the on-update trigger as-- trigger definition for update
create or replace trigger xxrvm_temp_b_upd_tr
instead of update on xxrvm_temp_b_v referencing new as new old as old
for each row
begin
update xxrvm_temp_b@test1
set text1 = :new.text1 ,text2 = :new.text2
where text1=:old_text1 and text2=:old_text2
end;Varad -
Update Trigger and COLUMNS_UPDATED()
Let me rephrase my question:
I want to know if there is a faster way (probably using bit operators) to see if COLUMNS_UPDATED() in an update trigger on a table with more than 8 columns contains any column other than 1 specific column I will refer
to as 'columnToIgnore'. I don't care about which columns are included or if the value has actually changed, only that there are other columns present.
Original question:
I have inherited a Sql Server database + schema and corresponding application and I have been tasked with speeding up the batch update of users in the database. After running some profiling I discovered that the reason it was slow is because of an update
trigger on the users table. I did some “cleaning up” of the trigger and now it runs faster but I still think it could be more efficient. The objective of the trigger is to write to an Audit table any time an update takes place and any column is updated (it
does not actually matter if the value has changed or not) with the exception of 1 specific column. Now I have the following code in the trigger which I had refactored from something much uglier.
DECLARE @ColumnsUpdated VARBINARY(100)
SET @ColumnsUpdated = COLUMNS_UPDATED()
DECLARE @onlyIgnoreColumnChanged int
SET @onlyIgnoreColumnChanged = 1
SET @onlyIgnoreColumnChanged = 1
IF (EXISTS(SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS Field
WHERE TABLE_NAME = 'users'
AND sys.fn_IsBitSetInBitmask(@ColumnsUpdated, COLUMNPROPERTY(OBJECT_ID('dbo.users'), COLUMN_NAME, 'ColumnID')) <> 0
AND column_name !='columnToIgnore')) BEGIN
SET @onlyIgnoreColumnChanged = 0
END
Ideally I would change the code to disable the trigger and do the insert myself BUT the code is old Classic ASP ( ie. VBScript with ODBC database connections) so I am not going to change any of the calling code because that would cost too much time and probably
create more problems than I am solving.
My proposed fix which I am unsure of how to code in SQL:
It seems to me that there should be a way to get the proper id or position for the column and see if the column was used in the COLUMNS_UPDATED().
If it was not used then we can set @onlynieuwchanged to 0 for the remaining code (not shown)
If it was used then remove the bit from the COLUMNS_UPDATED() and see if it is empty
If its empty then then we can set @onlynieuwchanged to 1 for the remaining code (not shown)
If it’s not empty then then we can set @onlynieuwchanged to 0 for the remaining code (not shown)
My problem is I am not sure how to go about coding this logic in SQL. I would think it would be possible with BIT operators? It would seem this could be more efficient than what I have now as it would get rid of the select statement which could slow down
a large batch update.
Notes
My table has 30+ some columns so more than 8 which is relevant when working with COLUMNS_UPDATED() from what I have read. It also means that testing each column with UPDATE() would probably be more inefficient than what I have now.
The update is called from the front end code (VBScript) which currently times out although not as much as it used to with my latest change. I cannot alter the code to run async mode and show progress, it would be easier for me to update the trigger.
Reason for audit - we only record the user id in an audit table. This is then used to force a sync to another system outside of our source control that is used for various other tasks (mailings, views, etc). Again, I do not want to change how this system
works, I only want to speed up the existing trigger with minimal effort.
Sql Server version 2012, database Schema is set to Sql server 2005 compatibility mode.
Any help would be greatly appreciated. Thank you in advance!
-IgorThank you again everyone for your input. As I mentioned there is much out of my control. This is an active application worked on by many developers and has been pieced together over the past 10+ years. It is NOT well written, the database schema has MUCH
to be desired, and the code is the classic definition of 'spaghetti' code and multiple platforms are used to access the data, and there are millions of lines of code. There is nothing I can do about all of this which is why I am ignoring much of the advice.
Sure, if this was a new application or something that was well written and possible to do some modifications then I would BUT it's not. If I was given 1 year of dedicated time to fix everything... well, I would probably throw it all away and start from scratch.
Here is what I finally came up with. It is probably not much faster, if at all, but when I started this I thought there would be a simple solution that I did not see. I will probably leave my code the way it was but will include the following for reference.
DECLARE @bit int, @field int, @char int, @comparisonField VARBINARY(100)
-- the following segment recreates the value contained in COLUMNS_UPDATED() if only the field nieuw was altered and stores that value in field @comparisonField
SET @field = (SELECT COLUMNPROPERTY(OBJECT_ID('dbo.users'), 'columnToIgnore', 'ColumnID')) -- geth the field id for column nieuw
select @bit = (@field - 1 )% 8 + 1
select @bit = power(2,@bit - 1)
select @char = ((@field - 1) / 8) + 1
-- select @field AS [Field number], @char AS [Char], @bit AS [Bit] -- debug code to check the bits that are tested.
-- Recreate the binary value of just having the field present in the columns_updated
SELECT @comparisonField = CONVERT(VARBINARY(100),'0x' + RIGHT('000000000000000000' + RIGHT(CONVERT(VARCHAR(30), CONVERT(varbinary(1), @bit), 1), 2), @char*2), 1)
-- if the generated value in @comparisonField is the same as COLUMNS_UPDATED() then only nieuw was updated
IF @comparisonField <> COLUMNS_UPDATED() BEGIN
-- code to add to the tracking table
END
-Igor -
How to use update trigger in sql server 2008 with specific column
Hello friends currently my trigger updates on table update, and I need to change this to only fire when specific column changes.
/****** Object: Table [dbo].[User_Detail] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[User_Detail](
[sno] [int] IDENTITY(1,1) NOT NULL,
[userid] [nvarchar](50) NULL,
[name] [nvarchar](max) NULL,
[jointype] [nvarchar](50) NULL,
[joinside] [nvarchar](50) NULL,
[lleg] [nvarchar](50) NULL,
[rleg] [nvarchar](50) NULL,
[ljoining] [int] NULL,
[rjoining] [int] NULL,
[pair] [int] NULL
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[User_Detail] table data ******/
SET IDENTITY_INSERT [dbo].[User_Detail] ON
INSERT [dbo].[User_Detail] values (1, N'LDS', N'LDS Rajput', N'free', N'Left', N'jyoti123', N'SUNIL', 6, 4, 4)
INSERT [dbo].[User_Detail] VALUES (2, N'jyoti123', N'jyoti rajput', N'free', N'Left', N'mhesh123', N'priya123', 3, 2, 2)
SET IDENTITY_INSERT [dbo].[User_Detail] OFF
/****** Object: Table [dbo].[User_Detail] trigger ******/
CREATE TRIGGER triggAfterUpdate ON User_Detail
FOR UPDATE
AS
declare @userid nvarchar(50);
declare @pair varchar(100);
select @userid=i.userid from inserted i;
select @pair=i.pair from inserted i;
SET NOCOUNT ON
if update(pair)
begin
insert into Complete_Pairs(userid,pair)
values(@userid,1);
end
GO
/****** Object: Table [dbo].[Complete_Pairs] Script Date: 05/22/2014 21:20:35 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Complete_Pairs](
[Sno] [int] IDENTITY(1,1) NOT NULL,
[userid] [nvarchar](50) NULL,
[pair] [int] NULL
) ON [PRIMARY]
GO
my query is TRIGGER triggAfterUpdate is fired only when pair column in User_Details table is update only and when we update other column like ljoin or rjoin then my trigger is not fired
please any one can suggest us how it can done or provide solution
Jitendra Kumar Sr. Software Developer at Ruvixo Technologies 7895253402>select @userid=i.userid
frominserted i;
select
@pair=i.pair
frominserted i;
The code above assumes a single row UPDATE.
You have to setup the trigger for set processing like when 100 rows are updated in a single statement.
UPDATE trigger example: http://www.sqlusa.com/bestpractices2005/timestamptrigger/
Kalman Toth Database & OLAP Architect
SQL Server 2014 Design & Programming
New Book / Kindle: Exam 70-461 Bootcamp: Querying Microsoft SQL Server 2012 -
How to convert clob to varchar2 in an update trigger
Hi,
I need to convert a field (clob) to varchar2 in a update trigger, how can I do that?
regards.The maximum amount of data you can store in CLOB column is 4GB.
You have table TABLE1 having col1 CLOB datatype.You have one more table
Table_audit_1 without having CLOB datatype column and want to move CLOB
data into VARCHAR2 column which has maximum length of 4000 and want to
audit col1 CLOB into VARCHAR2.It seems to me you dont care about the data
beyond 4000 bytes.
In 9i SUBSTR, INSTR can be performed without reference to the DBMS_LOB
package.
SQL> DROP TABLE mytable
2 /
Table dropped.
SQL> DROP TABLE mytable1
2 /
Table dropped.
SQL> CREATE TABLE mytable
2 (a NUMBER,b CLOB)
3 /
Table created.
SQL> CREATE TABLE mytable1
2 (c NUMBER,d VARCHAR2(4000))
3 /
Table created.
SQL> DECLARE
2 loc CLOB;
3 BEGIN
4 FOR i IN 1..5000
5 LOOP
6 loc:=loc||i;
7 END LOOP;
8 INSERT INTO mytable (a,b) VALUES (1,loc);
9 INSERT INTO mytable1 (c,d) VALUES (1,SUBSTR(loc,1,4000));
10 COMMIT;
11 END;
12 /
PL/SQL procedure successfully completed.
SQL> SET LONG 5000
SQL> CREATE OR REPLACE TRIGGER mytrigger BEFORE UPDATE ON mytable FOR EACH ROW
2 BEGIN
3 UPDATE mytable1
4 SET d=SUBSTR(:NEW.b,1,4000)
5 WHERE c=:NEW.a;
6 END;
7 /
Trigger created.
SQL> DECLARE
2 loc CLOB;
3 BEGIN
4 FOR i IN 1..1000
5 LOOP
6 loc:=loc||'A '||i;
7 END LOOP;
8 UPDATE mytable
9 SET b=loc
10 WHERE a=1;
11 COMMIT;
12 END;
13 /
PL/SQL procedure successfully completed.
SQL> SELECT LENGTH(b) FROM mytable
2 /
LENGTH(B)
4893
SQL> SELECT LENGTH(d) FROM mytable1
2 /
LENGTH(D)
4000
SQL> Khurram
Maybe you are looking for
-
Dear All we have two purchase order that one of them is created automatically in the during of goods receipt in transaction MB01 or MIGO and one of them is created normally ,how can recognize which one is created automativcally?. best regards R.T
-
Dynamically Modifying Target XML Namespace
Dear All, We have a requirement of dynamically modifying the namespace of the target XML . The scenario is as follows: There are multiple recipients of a message, and two of the recipients are using the same target structure, but with a different X
-
Asign paragraph styles to xml nodes
Hello all, I try to asign paragraph styles to xml nodes. I tried to autoasign the styles to tags and also to assign the styles directly to the xml tags with aid:pstyle. None of it with success. I think that this happens because there is a paragraph f
-
Importing errors - photos moved but not cataloged
Hello all, I'm having an issue with LR3 (Mac OSX 10.6.4) when importing photos from HDD into the catalog. Some of the photos imported (seemingly random) will error out with a code (8) "some files could not be moved".. or something to that effect. I
-
When composing a new mail, how can I add more fonts to the choices available when I open "show fonts" ? In previous versions of Mail, I could search my font library and add fonts to my list. That doesn't work in this version. The preferences dialog i