9
votes

I have created a synonym for a dblink.

create synonym dblink2 for dblink1

But when I query anything using the synonym instead of the dblink, I'm getting connection description for remote database not found error.

SELECT * FROM DUAL@DBLINK2

How do I query using the synonym?

Edit: I know that it'll work if I create a view of the table using dblink. But my requirement is the above question.

5
It would make more sense to create a synonym for the tables in the remote db, rather than a synonym for the dblink itself. E.g.: create synonym dual_dblink2 for dual@dblink1Boneist
100 tables. Cannot create 100 synonyms.Nitish
You can't actually do what you are asking. Why do you want to do it? There seems no obvious advantage over creating a db_link with a different name that points to the same place and even that seems an odd requirement. If you explain a bit about why you want this someone may be able to suggest an alternative solution that would work just as well.user672739
What is exactly your problem with the 100 synonym? I mean are you concerned about the number of objects or just the time it would take to create them?Gergely Bacso
@Nitish, there are virtually no limits to the number of synonyms you can define in a database. If your database has 100 tables, there's nothing stopping you from creating 100 synonyms.Jeffrey Kemp

5 Answers

16
votes

Unfortunately creation of synonyms for dblinks is not supported. If you read the documentation on synonyms, you will find that the permitted objects for synonyms are only:

Use the CREATE SYNONYM statement to create a synonym, which is an alternative name for a table, view, sequence, procedure, stored function, package, materialized view, Java class schema object, user-defined object type, or another synonym.

The reason why your second query fails is that the synomym you have created is not functioning correctly. It is not being validated properly at creation time, and you can create any sort of incorrect synonyms like that. To verify, just test the following statement:

create synonym dblink3 for no_object_with_this_name;

You will still get a response like this:

*Synonym DBLINK3 created.*

But of course nothing will work via this synonym.

5
votes

I don't see the point in creating a synonym for the dblink itself. Ideally you create the synonym for the remote table using the dblink.

CREATE DATABASE LINK my_db_link CONNECT TO user IDENTIFIED BY passwd USING 'alias';
CREATE SYNONYM my_table FOR remote_table@my_db_link;

Now, you could query the remote table using the synonym:

SELECT * FROM my_table;
3
votes

I'm trying to think of the business issue that gets solved by putting a synonym on a db_link, and the only thing I can think of is that you need to deploy constant code that will be selecting from some_Table@some_dblink, and although the table names are constant different users may be looking across different db_links. Or you just want to be able to swap which db_link you are operating across with a simple synonym repoint.

Here's the problem: it can't be done that way. db_link synonyms are not allowed.

Your only solution is to have the code instead reference the tables by synonyms, and set private synonyms to point across the correct db_link. That way your code continues to "Select from REMOTE_TABLE1" and you just can flip which DB_LINK you are getting that remote table from.

Is it a pain to have to set/reset 100+ private synonyms? Yep. But if it is something you need to do often then bundle up a procedure to do it for you where you pass in the db_link name and it cycles through and resets the synonyms for you.

0
votes

If you are trying to have the DB link accessible for multiple schemas (users) the answer is to create a public db link

example:

CREATE PUBLIC DATABASE LINK dblink1 CONNECT TO user IDENTIFIED BY password USING 'tnsalias';

After that any schema can issue a:

SELECT * FROM TABLE@dblink1
0
votes

While I understand that this question is 3+ years old, someone might be able to benefit from a different answer in the future.

Let's imagine that I have 4 databases, 2 for production and 2 for dev / testing.

Prod DBs: PRDAPP1DB1 and PRDAPP2DB1 Dev DBs: DEVAPP1DB1 and DEVAPP2DB1

The "APP2" databases are running procedures to extract and import data from the APP1 databases. In these procedures, there are various select statements, such as:

declare
iCount INTEGER;
begin
  insert into tbl_impdata1
  select sysdate, col1, col2, substr(col3,1,10), substr(col3,15,3)
  from tbl1@dblink2; -- Where dblink2 points to DEVAPP1DB1
  ...
  <more statements here>
  ...
EXCEPTION
  <exception handling code here>
end;

Now that is okay for development but the dblink2 constantly needs to be changed to dblink1 when deploying the updated procedure to production.

As it was pointed out, synonyms cannot be used for this purpose. But instead, create the db links with the same name, different connection string.

E.g. on production:

CREATE DATABASE LINK "MyDBLINK" USING 'PRDAPP1DB1';

And on dev:

CREATE DATABASE LINK "MyDBLINK" USING 'DEVAPP1DB1';

And then in the procedures, change all "@dblink1" and "@dblink2" to "@mydblink" and it all should be transparent from there.