Skip to Main Content
  • Questions
  • Hybridized Database after an upgrade of a retail Point of Sale application.

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Soundaravadi.

Asked: January 13, 2017 - 3:29 pm UTC

Last updated: January 17, 2017 - 1:25 am UTC

Version: Oracle 11g

Viewed 1000+ times

You Asked

Background: Point of Sale product running on retail stores. Each store has a store primary database and there is a centralized database. The data from the stores get replicated real time to the central Database. The Front end application and the DB is being upgraded to the current version. The Database has undergone many changes - new tables added and old tables or sometimes columns in some tables dropped. Many tables have been created as "properties" tables so new attributes can be added as properties instead of ever increasing # of columns. We are creating a backward compatible hybridized script so the central database caters to stores in either version as all stores will not get the upgrade roll-out at the same time. So the old tables and columns will not be dropped from the central DB but the new tables/columns will be added so the data will be available to stores in both versions. This is necessary so returns from one store can be processed in another regardless of the version they are in.

Now to the problem of recursive triggers:

We need to write triggers so when "old columns" in the central DB is updated the properties tables should be inserted/updated with data and vice versa. The code below is not exact but hope it gives an idea of what we are trying to do. A similar trigger from prop table needs to update the table with the old columns. I am encountering table mutating error when I try to update the properties table. I am not a DBA but I have the task of completing these triggers. I'd appreciate your valuable suggestions regarding how to avoid the table mutating error.

CREATE OR REPLACE TRIGGER trg_upd_prop_stat
AFTER UPDATE OR INSERT
ON tender_lineitem
FOR EACH ROW
DECLARE
vcount int;
BEGIN
select decode(instr(DBMS_UTILITY.format_call_stack,upper('trg_upd_prop')),0,0,1) into vcount from dual;
if vcount>0 then
return;
end if;

if :new.status is null THEN
return;
END IF;
IF updating(upper('status')) or inserting THEN
select count(*) into vcount from trl_prop where property_code='STATUS';

if vcount>0 then
update trl_prop set string_value=:new.status WHERE property_code='STATUS';
else
insert into trl_prop (property_code,string_value)
values('STATUS',:new.status);
END if;
end if;
END IF;
END;
/

and Connor said...

Here is some info on mutating tables

https://docs.oracle.com/cd/B28359_01/appdev.111/b28370/triggers.htm#g1699708

and a link to the docs on using compound triggers to workaround it

https://docs.oracle.com/cd/B28359_01/appdev.111/b28370/triggers.htm#CHDFEBFJ


But in a nutshell - a row level trigger generally isn't allowed to mess with the table its triggering on. The key term in that sentence is "row level", so the resolution to mutating table/triggers is to

a) use the row level trigger to *store* information about what you *intended* to do
b) then use that stored information in a *statement* level after-trigger to actually go head and do the work.

If you go the Resources tab in AskTom, and in the Presentation section do a filter on "Mutate" you'll see a html demo of this. The links above also cover how compound triggers can make this easier to code up.



Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Triggers and Table mutation

Venkat (Soundaravadi Venkataraman), January 16, 2017 - 5:55 pm UTC

Hi Connor,

Thanks for the quick response.

I'll try this. I am sure we'll be encountering various avatars of this issue and your response should help us a lot.

Venkat
Connor McDonald
January 17, 2017 - 1:25 am UTC

glad we could help

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library