Oracle Trigger that will update tables in a different DSN - oracle

During update or insert on 1 table, is there a way to update a table that is on a different DSN? I want to interface 2 systems that are using different databases and would like to have a trigger that could do such updates. Thanks.

You can create a database link from one Oracle database to the other one. This gives you access to reference remote tables from within your trigger.
This solution has a the merits of simplicity but is not the most efficient (consider bulk updates) or robust (consider downtime of the remote database).
Oracle Replication is a full-on solution that allows you to trade-off consistency, availability , performance, etc.

Related

Data replication between Oracle and Postgres

Is there a way to replicate data(like triggers or jobs) from oracle tables to postgres tables and vice versa(for different set of tables) without using external tools? Just one way replication for both the scenarios.
Just a hint:
You can think of create a DB link from Oracle to Postgres which is called heterogeneous connectivity which makes it possible to select data from Postgres with a select statement in Oracle.
Then use materialized views to schedule and store the results of those selects.
As you don't want to use any external tool otherwise the solution should have been much simpler
for 20 tables I need to replicate data from oracle to postgres. For 40 different tables, I need to replicate from postgres to oracle.
I could imagine the following setup:
For the Oracles tables that need to be accessible from Postgres, simply create foreign tables inside the Postgres server. They appear to be "local" tables in the Postgres server, but the FDW ("foreign data wrapper") will forward any request to the Oracle server. So no replication required. Whether or not this will be fast enough depends on how you access the tables. Some operations (WHERE clause, ORDER BY etc) can be pushed down to the Oracle server, some will be done by the Postgres server after all the rows have been fechted.
For the Postgres tables that need to be replicated to Oracle you could have a similar setup: create a foreign table that points to the target table in Oracle. Then create triggers on the Postgres table that will update the foreign table, thus sending the changes to Oracle.
This could all be managed on the Postgres side.

Synonym or view over dblink

We are writing some interfacing routines in PL/SQL to transfer data between several oracle database by using another oracle database as host. (ie hr -> host -> finance)
the transfers are happening over db_links
essentially
insert into schema.tablname#dblink1 select * from schema.tablename#dblink2;
(its more complicated then that with multiple tables and transformations etc.. but that's the general idea)
the discussion we have been having here is which of the following should do
reference "schema.tablename#dblink" everywhere in out code
create synonyms (public or private) "create synonym tablename for schema.tablename#dblink"
create views on the object " create view tablename as select * from schema.tablename#dblink"
are there any other options?
are any inherently better then the others?
NB:the dblink names are standardised throughout each level dev/test/prod
so that dblink 'server1' goes to the dev server on the dev host and the test server on test host etc..
none of the table names should ever exist on multiple servers
Location transparency is easiest setup by creating synonyms for your remote objects. That is easier to maintain than having the remote addresses in every SQL. How would you make a quick test for something in an other remote database? Just re creating the involved database links is enough to accomplish that.
An other option could be to create snapshots are materialized views from the remote tables in the local database but that also requires a database link. It would have a good performance at the cost of extra space.

Cache table on one side of datalink in Oracle

I would like to create a cached copy of a table via dblink in oracle. The story is the following:
I have two tables (employee, work) which are joined via a third table (emloyee_work) in a remote database. The reason for that is to decouple the connection between the two entities so that they are not able to be connected directly.
To handle the data easily we have a view that connects the tables via the join table. One can argue that this is the same as having the join table in the same database as the other two but that in not the point right now.
On a new site, the db link latency is very high which causes a major drop in performance since for every select the view is built and a select is executed for each employee through the db link.
The structure has relative high read count and low write count.
The question is whether there is a possibility to "mirror" or copy the remote join table to the local database? This copy should be temporary and should not be persisted.
This way the view would be executed on the local copy.
EDIT: Oracle version is 11gR2
You could use refreshed on demand materialized views.
See also this link where they talk about implementing a materialized view over a dblink.
Since you are using Oracle 11g, you may create an ad-hoc, RAM-based Materialized View.

Why regular oracle table support DML statements,but not the same for External table?

This is known to us that all DML statement has been supported by Oracle Regular Table but not the same for External Table? I tried below :
SQL> INSERT INTO xtern_empl_rpt VALUES ('70','Rakshit','Nantu','4587966214','na
tu.rakshit#ge.com','55');
INSERT INTO xtern_empl_rpt VALUES ('70','Rakshit','Nantu','4587966214','natu.ra
kshit#ge.com','55')
*
ERROR at line 1:
ORA-30657: operation not supported on external organized table
SQL> update xtern_empl_rpt set FIRST_NAME='Arup' where SSN='896743856';
update xtern_empl_rpt set FIRST_NAME='Arup' where SSN='896743856'
*
ERROR at line 1:
ORA-30657: operation not supported on external organized table
SQL>
So it seems External table not support this. But my question is - what the logical reason behind this design?
There is no mechanism in Oracle for locking rows in external tables, none of the concurrency controls which we get with regular heap tables. So updating is not allowed.
External tables created with the Oracle Loader driver are read only; the Datapump driver allows us to write to external table files but only in an CTAS mode.
The problem is that eternal tables are basically windows on OS files, without the layer of abstraction and control that internal tables offer. Basically, there is no way for the database to lock a record in an OS file, because the notion of a "record" is a databse thang, not an OS file thang.
External tables are designed for only one thing: data loading and unloading. They are simply not meant to be used with normal DML, and they're not really meant for normal selects either - that works, but if you need to do a lot of selections on an external table, you're "doing it wrong": load the data into proper tables, calculate statistics & add indexes as necessary.
Having external tables behave like normal tables would need that all the transactional machinery be implemented for them, which is very complex, and not worth it since that's not what they are meant for.
If you need normal tables and want to transplant them from one Oracle database to another, you should evaluate using transportable tablespaces too.
Limitations of external table are an obvious consequence of their being read-only; they are an adapter to involve in SQL queries either arbitrary record-organized files (ORACLE_LOADER type) or exported copies of tables in another database (ORACLE_DATAPUMP type).
As already mentioned, external tables are only good for full table scan queries; if one needs to use indexes in heavy duty queries or to modify foreign data sets that have been imported from files, regular tables can be populated using the SQL Loader tool.

Monitoring which statement updates (and when) a certain table row with Oracle 10

I'm using (have to) a badly designed Oracle(10) DB, for which I don't have admin rights (although I can create tables, triggers, etc in my scheme).
Now I had run into a problem: this DB connected with several users/programs. I must find out who updates a certain row, when, and if possible: with what kind of statement. Is it possible?
Thanks in advance!
It would be easier to do this if you had admin rights to enable auditing. Without the power of auditing you are left with the use of triggers to handle the logging of inserts/updates/delete. In your case since you are interested in only update, you can put a trigger on the table to fire after the update which logs to another table what was changed, by whom, from where and to what and on what day.
I would create a journal table for the table you are working with. It will show you the operation type and the oracle user...as well as a bunch of other data if you need it.

Resources