Oracle 如果不是在存储过程中创建的,则创建DB链接
我正在尝试用Oracle编写一个存储过程。我在这方面没有太多的经验,我正面临一个问题。该过程的最终目标是从一个数据库中获取数据,并以不同的形式将其放入另一个数据库中。我的大部分程序似乎都能正常工作,但我有一些问题,似乎应该很简单。在代码的开头,我想检查以确保创建了DB链接。如果没有,那么我想创建db链接 这是我在我的程序中所做的:Oracle 如果不是在存储过程中创建的,则创建DB链接,oracle,stored-procedures,database-link,Oracle,Stored Procedures,Database Link,我正在尝试用Oracle编写一个存储过程。我在这方面没有太多的经验,我正面临一个问题。该过程的最终目标是从一个数据库中获取数据,并以不同的形式将其放入另一个数据库中。我的大部分程序似乎都能正常工作,但我有一些问题,似乎应该很简单。在代码的开头,我想检查以确保创建了DB链接。如果没有,那么我想创建db链接 这是我在我的程序中所做的: IF (select count(1) from ALL_DB_LINKS where db_link = 'DB_LINK.NAME.COM') = 0 THEN
IF (select count(1) from ALL_DB_LINKS where db_link = 'DB_LINK.NAME.COM') = 0 THEN
CREATE DATABASE LINK LINK_NAME
CONNECT TO username IDENTIFIED BY password
USING 'SID';
END IF;
我知道这个链接是有效的,因为我在这之外做过,并用它进行了查找。我尝试编译时遇到的错误如下:
预期出现以下情况之一时遇到符号“CREATE”:
我已经做了所有我认为我能做的谷歌搜索,但我不知道我做错了什么。为了避免我提出的另一个问题,我还试着提出:
声明测试计数编号
select count(1) into test_count from ALL_DB_LINKS where db_link = 'DB_LINK.NAME.COM';
BEGIN
IF test_count = 0 THEN
CREATE DATABASE LINK LINK_NAME
CONNECT TO username IDENTIFIED BY password
USING 'SID';
END IF;
END;
但我也犯了同样的错误。我也不确定在begin中设置begin是否有效。任何帮助都将是一个伟大的。。。哦,救命啊 Oracle编译包,为了做到这一点,代码中引用的所有对象都必须已经存在。这包括通过数据库链接引用的对象。如果引用的对象不存在,则将标记为无效。通常,DBA将使用PL/SQL脚本而不是存储过程来创建和维护这样的环境 如果您真的想这样做:
EXECUTE IMMEDIATE q'[ CREATE DATABASE LINK LINK_NAME
CONNECT TO username IDENTIFIED BY password
USING 'SID']';
如果确实需要这样做,可以按照Ed Gibbs的建议和Brian的演示,使用动态SQL创建链接,只要在创建过程时链接已经存在:
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.
但是,如果链接不存在,该过程将不会编译:
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
奇怪的是,如果在链接存在时创建过程,然后删除链接,它并不反对;该过程保持有效,动态SQL工作以重新创建链接,并且该过程成功运行:
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.
我本以为删除链接会使过程无效,但显然不是,尽管它出现在所有依赖项中。但无法重新编译过程:
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
为了让您在链接不存在时编译(或重新编译),您还需要使用动态SQL引用链接:
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.
在Oracle中,不能直接在过程中执行DDL。您可以通过使用立即执行来解决这个问题;我现在无法测试,但我非常确定,如果您从静态SQL中不存在的链接中进行选择,该过程将不会编译,如果随后删除该链接,该过程将无效。在运行时创建对象听起来像是你需要重新思考的事情……是的,这就是我想要的。我知道这不是最好的方式,但现在这是我需要的方式,因为其他情况。谢谢你的帮助!