If you really need to do this, you can create the link using dynamic SQL as Ed Gibbs suggested and Brian showed, as long as the link already exists at the point the procedure is created:
create database link test_link
connect to scott identified by oracle
using 'ORCL';
Database link created.
create or replace procedure p42 as
l_count number;
l_dummy dual.dummy%type;
begin
select count(*) into l_count
from all_db_links
where db_link = 'TEST_LINK';
if l_count = 0 then
execute immediate q'[
create database link test_link
connect to scott identified by oracle
using 'ORCL'
]';
end if;
select dummy into l_dummy from dual@test_link;
dbms_output.put_line('Value from remote database: ' || l_dummy);
end;
/
Procedure created.
exec p42;
Value from remote database: X
PL/SQL procedure successfully completed.
But the procedure won't compile if the link doesn't already exist:
drop database link test_link;
create or replace procedure p42 as
...
end;
/
Warning: Procedure created with compilation errors.
show errors
Errors for PROCEDURE P42:
LINE/COL ERROR
-------- -----------------------------------------------------------------
16/5 PL/SQL: SQL Statement ignored
16/5 PL/SQL: ORA-00942: table or view does not exist
Curiously it doesn't object if you create the procedure while the link exists, and then drop the link; the procedure stays valid, the dynamic SQL works to recreate the link, and the procedure runs successfully:
drop database link test_link;
Database link dropped.
select object_type, object_name, status from all_objects
where object_type = 'PROCEDURE' and object_name = 'P42';
OBJECT_TYPE OBJECT_NAME STATUS
--------------- --------------- ---------------------
PROCEDURE P42 VALID
exec p42;
Value from remote database: X
PL/SQL procedure successfully completed.
I would have expected dropping the link to invalidate the procedure, but apparently not, despite it appearing in all_dependencies
. You can't recompile the procedure though:
drop database link test_link;
Database link dropped.
alter procedure p42 compile;
Warning: Procedure altered with compilation errors.
show errors
Errors for PROCEDURE P42:
LINE/COL ERROR
-------- -----------------------------------------------------------------
16/5 PL/SQL: SQL Statement ignored
16/5 PL/SQL: ORA-00942: table or view does not exist
In order to let you compile (or recompile) while the link does not exist, you'd need to reference the link using dynamic SQL as well:
drop database link test_link;
drop database link test_link
*
ERROR at line 1:
ORA-02024: database link not found
create or replace procedure p42 as
....
execute immediate 'select dummy from dual@test_link' into l_dummy;
dbms_output.put_line('Value from remote database: ' || l_dummy);
end;
/
Procedure created.
exec p42;
Value from remote database: X
PL/SQL procedure successfully completed.
drop database link test_link;
Database link dropped.
exec p42;
Value from remote database: X
PL/SQL procedure successfully completed.
drop database link test_link;
Database link dropped.
alter procedure p42 compile;
Procedure altered.
exec p42;
Value from remote database: X
PL/SQL procedure successfully completed.