views:

90

answers:

2

Let's say I have two schemas: HR and Orders.

[HR].Employees         [Orders].Entries
--------------         ----------------
Id_Employee    ---->   Employee
Fullname               Id_Entry
Birthday               Description
                       Amount

As you can see, what I'd want is to be able to establish a cross-database foreign key, but when I try this using a database link, I get:

-- From [Orders]
ALTER TABLE Entries
    ADD CONSTRAINT FK_Entries_Employees FOREIGN KEY (Employee)
    REFERENCES Employees@HR;
COMMIT;

ORA-02021: DDL operations are not allowed on a remote database

Is there a way around this? It's a legacy database, so I can't change the existing schema.

For the NHibernate crowd: I would then use this relation to map the NHibernate's domain objects.

+1  A: 

As far as I know constraints and referential integrity are only supported within one single database.

If you need to cross the boundaries of the database, you'd have to be creative. Maybe write some triggers checking for data in the other database or enforce these constraints on the application level. But then you may encounter the problem with transaction scope limited to one single database.

Developer Art
+6  A: 

One option would be to create a materialized view of Employees on [Orders] and then use that as the parent for the foreign key.

Of course, that has some drawbacks. In particular,

-- you won't be able to do a complete refresh of the materialized view without disabling the foreign key, so it'll have to fast refresh.

-- keys entered into EMPLOYEES won't be available to ENTRIES until the materialized view refresh. If that's critical, you may want to set it to refresh on commit.

Other alternatives are to handle the key enforcement yourself through a trigger or through a post cleanup process. Or convince the DBA's that these schemas can reside on the same database instance.

Jim Hudson
@Jim: Thanks. I'd never even used a materialized view before. That being said, how would you disable the constraint on commit in order to refresh the materialized view? Again, thanks.
Rafael Belliard
The other issue is if you have to do a restore of either database to a point-in-time. This can put the databases out of sync
Gary
With any materialized view of this sort, you're doing a query against the master table using the DB link. If you do things right, you can get the MV to do a "fast" refresh -- that is, just insert/update/delete the rows in the MV that have been modified in the master. To do that, you should have a primary key on the master table. Then you need to create a materialized view log for the master table based on that PK. And create the materialized view as "refresh fast using primary key" so it'll just process incremental changes. Then you can set the refresh to be done on a schedule or ON COMMIT.
Jim Hudson
If your DB link is connecting as the schema owning the master table, that's about it. If it's not, you'll need to check the manuals for some subtleties -- like fully qualifying the name of the master in materialized view query since those don't really like synonyms.
Jim Hudson