Synonym or view over dblink - oracle

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.

Related

Do two users access the same database or different?

I installed Oracle on my system, so now orcl is the SID, which is the unique identifier of my database instance.
Now starter db was created as part of the installation. I created 2 users user1 and user2 using the system account.
Using SQL developer I am accessing the users, this shows me 2 different connections with all the database objects like tables, stored procedures views etc.
so
When using these 2 users, am I accessing the same database? I am giving all the ddl commands by logging into the user1 or user 2, does all this data goes into the same .dbf file?
The database instance can be connected to only one database, then does this essentially mean that everytime I create a new database, to make a database instance to point to that, I need to do a configuration change?
In my experience with Oracle, the typical unit of division is a schema. Schemas in Oracle are used more like you would use databases in SQL Server or PostgreSQL. They represent both users and a logical separation of objects. Physical separation would usually be done using tablespaces. Tablespaces are a group of physical files where data is stored. Schemas can share or use different tablespaces. Having one tablespace per schema is uncommon; they usually share a few tablespaces or often even just one.
With that in mind, to answer your questions more directly,
1) Like in any other database, you can specify the schema the object belongs to:
CREATE TABLE MY_SCHEMA.TABLE_X ( X NUMBER )
If the schemas on two CREATE statements are different, then it will create different objects. What's different in Oracle is that the default schema changes for every user. The default schema is always the currently connected schema/user. So if you omit the schema like so:
CREATE TABLE TABLE_X ( X NUMBER )
then the implied schema is the currently connected schema/user. So if I'm logged in as MY_SCHEMA, then the above is equivalent to the first example. When connecting as two different users, then the implied schema will be different and the DDL is not equivalent between the two users. So running the same statement would create two different objects if you do not specify a schema.
The two objects may be stored in the same physical file if they are in the same tablespace. (They are most likely in the USERS tablespace if you did not create one explicitly and did not specify a different default tablespace when creating the schemas.) Regardless, they are still two completely separate objects.
If you specify the schema explicitly like in the first example, then the DDL is equivalent regardless of who executes it (although permissions may prevent some users from executing it). So it would result in creating the object once, and attempting to create it a second time would result in an error unless you're using CREATE OR REPLACE or something similar.
2) I don't know the answer to this question, but as I said, in Oracle, the basic unit of separation is usually the schema, not a database. I believe the question you're asking is a large part of the reason why the schemas are used in the way they are. Having multiple actual databases on the same machine/instance is far more difficult in Oracle than in other databases (if not impossible), so it's much simpler to have a single database with many schemas.

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.

Oracle Trigger that will update tables in a different DSN

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.

Creating re-runnable Oracle DDL SQL Scripts

Our development team does all of their development on their local machines, databases included. When we make changes to schema's we save the SQL to a file that is then sent to the version control system (If there is a better practice for this I'd be open to hearing about that as well).
When working on SQL Server we'd wrap our updates around "if exists" statements to make them re-runnable. I am not working on an Oracle 10g project and I can't find any oracle functions that do the same thing. I was able to find this thread on dbaforums.org but the answer here seems a bit kludgy.
I am assuming this is for some sort of Automating the Build process and redoing the build from scratch if something fails.
As Shannon pointed out, PL/SQL objects such as Procedures, functions and Packages have the "create or replace" option, so a second recompile/re-run would be ok. Grants should be fine too.
As for Table creations and DDLs, you could take one of the following approaches.
1) Do not add any drop commands to the scripts and ask your development team to come up with the revert-script for the individual modules.
So for each create table that they add to the build, they will have an equivalent "DROP TABLE.." added to a script say."build_rollback.sql". If your build fails , you can run this script before running the build from scratch.
2)The second (and most frequently used approach I have seen) is to include the DROP table just before the create table statement and then Ignore the"Table or view does not exist" errors in the build log. Something like..
DROP TABLE EMP;
CREATE TABLE EMP (
.......
.......
);
The thread you posted has a major flaw. The most important one is that you always create tables incrementally. Eg, your database already has 100 tables and you are adding 5 more as part of this release. The script spools the DROP Create for all 100 tables and then executes it which does not make a lot of sense (unless you are building your database for the first time).
An SQL*Plus script will continue past errors unless otherwise configured to.
So you could have all of your scripts use :
DROP TABLE TABLE_1;
CREATE TABLE TABLE_1 (...
This is an option in PowerDesigner, I know.
Another choice would be to write a PL/SQL script which scrubs a schema, iterating over all existing tables, views, packages, procedures, functions, sequences, and synonyms in the schema, issuing the proper DDL statement to drop them.
I'd consider decomposing the SQL to create the database; one giant script containing everything for the schema sounds murderous to maintain in a shared environment. Dividing at a Schema / Object Type / Name level might be prudent, keeping fully dependent object types (like Tables and Indexes) together.

How to create partition on remote tablespace in Oracle?

I'm a noob in Oracle, is it possible to partition a table to remote server using db link? is it possible at all?
I'm trying something like this:
CREATE TABLE Test (
TestID integer not null,
Name varchar2(20) not null
)
PARTITION BY LIST (TestID)
(PARTITION testPart1 VALUES (1)
TABLESPACE tbspc1,
PARTITION testPart2 VALUES (2)
TABLESPACE tbspc2#RemoteServer);
thank you
No, that will not work. You're confusing an instance with a database.
A database is the physical storage of the data and metadata. The number of disks you use and the location of the disks is up for management. You can put indexes one place, data in another; you can put some data on local drives and some on mounted drives. That's a database.
An Instance is the memory structures and computer processes which access a database and make it possible to query it, write to it, update it, etc.
When you say #DB_LINK... you're saying "That set of memory and cpu processes".
When you say Tablespace, you're saying "On those files, on those disks"
If you want to store data on the same drives that your #dblink is storing data then mount that drive and build a new tablespace there.
If you're trying to OPEN the database with more than one instance, that's called RAC and it's bit over your head. <-- I say this because you have to have these concepts mastered before you'd ever consider RAC.
It's hard to say that something is impossible, but based on the syntax diagram for CREATE TABLE this doesn't look possible. For the select statement you can see that the dblink syntax (# dblink): http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_10002.htm#i2126073 But for partitioning storage there is no such remote syntax: http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_7002.htm#CJADDEEH
Perhaps the following would be a reasonable starting point:
Have a database at the "home office" to contain the common data.
Have a "local" database at each branch to store branch-specific data, with links to the "home office" database to access the common data.
To help eliminate the "single point of failure" which could occur if the central database was to go down or communications were to be lost, you might try replicating the common data from the central database to the branch databases so that each branch has a complete copy of the common data which could be updated on some sort of regular schedule.
Share and enjoy.

Resources