0

我正在尝试在 Oracle 中编写存储过程。我没有大量的经验,我遇到了一个问题。该过程的最终目标是从一个数据库中获取数据并以不同的形式将其放入另一个数据库中。我的大部分程序似乎都在工作,但我遇到了一些看起来应该很简单的问题。在代码的开头,我想检查以确保创建了数据库链接。如果没有,那么我想创建数据库链接。

这是我在我的程序中放入的内容:

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”:

我已经完成了所有我认为可以做的谷歌搜索,但我无法弄清楚我做错了什么。为了避免我遇到的另一个问题,我还尝试通过输入:

声明 test_count 数;

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 是否有效。任何帮助都会很棒......好吧,帮助。

4

2 回答 2

2

Oracle 编译包,为了做到这一点,代码中引用的所有对象都需要已经存在。这包括通过数据库链接引用的对象。如果引用的对象不存在,事物将被标记为无效。通常,DBA 将使用 PL/SQL 脚本而不是存储过程来创建和维护这样的环境。

如果你真的想这样做:

EXECUTE IMMEDIATE q'[ CREATE DATABASE LINK LINK_NAME
      CONNECT TO username IDENTIFIED BY password
      USING 'SID']';
于 2013-04-26T22:49:07.877 回答
0

如果您确实需要这样做,您可以按照 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.

我本来希望删除链接以使程序无效,但显然不是,尽管它出现在all_dependencies. 但是,您不能重新编译该过程:

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.
于 2013-04-27T10:59:39.143 回答