Skip to Main Content
  • Questions
  • Database link GLOBAL NAMES TEST and PRODUCTION

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Kirthi.

Asked: November 09, 2009 - 1:15 pm UTC

Last updated: November 23, 2009 - 12:33 pm UTC

Version: 10.2.0

Viewed 1000+ times

You Asked

I have a database "A" which accesses a table "B_TBL" in database "B" via database link to retrieve and insert data data. I also have a function in database "A" which get a BLOB from a table in database "B" over a database link. Since, I cannot create a View which retrieves a BLOb over a database link I have created a function. I am using a GLOBAL TEMPORARY table to get the BLOB in this function. The GLOBAL_NAMES is set to TRUE therefore I cannot have the same database link name in TEST and PRODUCTION and therefore requires me to change the View the Functions when I publish this from one database to another. I understand the need for the GLOBAL_NAMES to be set to true but is there a way that I could not have to change the View or modifying the functions when I publish on diferent databases? 

------------------------------------------------------------------------------- 

DATABASE A:

GLOBAL_NAMES = TRUE

CREATE PUBLIC DATABASE LINK B_DATABASE.XYZ.WORLD
 CONNECT TO USERB
 IDENTIFIED BY password
 USING 'B_DATABASE.XYZ.WORLD';

CREATE VIEW B_TBL
AS
SELECT ID
FROM B_TBL@B_DATABASE.XYZ.WORLD;


CREATE GLOBAL TEMPORARY TABLE photo_temp
(
  ID         NUMBER,
  photo  BLOB
)
ON COMMIT DELETE ROWS
NOCACHE;



CREATE OR REPLACE function get_photo(id_p in number ) RETURN BLOB
is
photo_data blob := empty_blob();
begin


INSERT INTO photo_temp(ID,photo)
select ID,photo
from B_TBL@B_DATABASE.XYZ.WORLD
WHERE ID = id_p;


select photo_temp
into photo_data
from photo_temp
WHERE ID = id_p;

  return photo_data;  

exception
when NO_DATA_FOUND THEN
  ROLLBACK;
  RETURN NULL;
when others then
 rollback;
 RAISE_APPLICATION_ERROR('-20015','Exception in Function: get_photo(id_p in 
number ). id: ='||id_p||', SQLERRM = '||SQLERRM||', SQLCODE = '||SQLCODE);
end get_photo;
/
 

-------------------------------------------------------------
DATABASE B: 
TNS ENTRY: B_DATABASE.XYZ.WORLD
GLOBAL_NAMES = TRUE

CREATE TABLE B_TBL(
 ID NUMBER,
 PHOTO BLOB
);



and Tom said...

you could use a synonym and create or replace it instead of a view or instead of a procedure referencing it.

but - at the end of the day, you obviously *have* to replace it, that is the entire goal of global names - to ensure "you are doing the right thing to the right database in the right environment".

You NEED them to point to different databases in test versus production.



I will say - your use of rollback is not necessary at all - and in fact I would say "is an extremely bad practice".


You have rollback in your no_data_found handler. If there is no data to be found, that means the insert could not have inserted anything - therefore, the rollback is not necessary (there is nothing to roll back) and - if you did do a rollback - you would EASILY break transactions that call you. If there was work to be rolled back, you should be using a savepoint ONLY - not rollback of the entire transaction:

begin
savepoint foo;
insert this
insert that
update the other thing
select into

exception
when no data found then rollback to FOO; return null;


that would be acceptable, but what you have *is not*, it is a bug.



Additionally, the rollback in the when others - not necessary. You are raising the exception - we'll roll back automagically when the error propagates to the client. consider:


ops$tkyte%ORA11GR2> create table t ( x int check (x>0) );

Table created.

ops$tkyte%ORA11GR2>
ops$tkyte%ORA11GR2> create or replace procedure p
  2  as
  3  begin
  4          insert into t values ( 1 );
  5          insert into t values ( 0 );
  6  exception
  7          when others then raise_application_error( -20015, 'Got error ' || dbms_utility.format_error_stack );
  8  end;
  9  /

Procedure created.

ops$tkyte%ORA11GR2>
ops$tkyte%ORA11GR2> exec p
BEGIN p; END;

*
ERROR at line 1:
ORA-20015: Got error ORA-02290: check constraint (OPS$TKYTE.SYS_C0012816) violated
ORA-06512: at "OPS$TKYTE.P", line 7
ORA-06512: at line 1


ops$tkyte%ORA11GR2> select * from t;

no rows selected




it is done for you automagically.



*remove your rollbacks, they are both wrong and should be consider a definite bug in the developed code*


Rating

  (3 ratings)

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

Comments

Public or private synonym

Kirthi Sreenivasan, November 12, 2009 - 9:20 am UTC

Tom, I have read your other replies to peoples question about the usage of Public synonyms. You have discouraged the usage of Public synonyms. I have removed most of the public synonyms in the database I manage and I have replaced it with a database logon trigger which sets the current_schema as below.

alter session set current_schema=ppirs'

Will you recommend a public synonym in this case? If you would not recommended a public synonym could a private synonym be used and access granted to Roles so other users in the database has access to these tables? Could you please give an example. Thank you.
Tom Kyte
November 15, 2009 - 2:04 pm UTC

... Will you recommend a public synonym in this case? ...

No, you did "pretty good", a logon trigger is a bit of magic - it might come back to bite you in the future (when ppris should NOT be the default schema for something) - so document it well and make sure EVERYONE knows about it - over and over remind them of it.

I don't know what a private synonym would do? You'd have to install that into each and every schema?

Everyone has access to these tables (assuming they have been granted that access), the matter at hand is "scoped name resolution".

anyway can select from ppris.table_name if they have been granted access to it.

the problem you have is that people just query "select from table_name" and want ppris automagically prepended - that is what the alter session is doing (and nothing else, it has nothing to do with security)

Thank you for pointing out the bug in the rollback usage

Kirthi Sreenivasan, November 12, 2009 - 9:31 am UTC

Tom, thanks for pointing out the incorrect usage of Rollback and for providing a detailed explanation. The examples are very useful. I will fix my code. Thank you very much.

Miscommunication

Kirthi Sreenivasan, November 16, 2009 - 5:00 pm UTC

Tom,
I am sorry there is a miscommunication in what I was trying to ask.

1. I was wondering if it is advicable to use Public synonyms for the Views (table on the remote database having a LOB column) and for the remote database table reference (has a LOB column) used within a function. Use of the public Synonym would eliminate the need to change the code in the function when it is created on other databases which makes the maintenence easier. But, I am quesy about this option after reading about the usage of Public Synonyms from your replies to other users.

2. I tested option 1 and it works but I am not sure if it is any better than what I already have in my original post. Since, I cannot create a View which refers to a LOB over a database link I have the function using the database link name in the code. From a maintainability stand point I am not sure if it is a best practice if i have to change the function from test to production etc.

2. If the above option of Public synonyms is not any better than what has been posted in the original post is there another option so I do not have to change the function from test to production. I am aware that either the View/Synonym needs to be changed when changing from one database to another.

I hope I have explained the dilema I have clearly. Please let me know your suggestions. Thank you. I appreciate it.


Tom Kyte
November 23, 2009 - 12:33 pm UTC

1) I recommend against public synonyms, period.

I don't get the maintenance thing, use private synonyms or views in the schema owning the code if you don't want to put the owner in the procedure - or just put the owner in the procedure.

2) you have to use different names in different environments, a private synonym would do it, code that prompts you for the information upon install would do it as well (eg: make it a sqlplus substitution variable for example, when you INSTALL prompt for "how to install")

3) no public synonyms, just say no. private - moderately ok, public - no.

More to Explore

CLOB/BLOB/etc

Complete documentation on Securefiles and Large Objects here