0

Oracle でストアド プロシージャをコーディングしようとしています。私はそれについて多くの経験がなく、問題に直面しています。この手順の最終目標は、ある DB からデータを取得し、それを別の形式で別の DB に入れることです。ほとんどの手順は機能しているようですが、単純なはずの何かに問題があります。コードの冒頭で、DB リンクが作成されていることを確認したいと思います。そうでない場合は、db リンクを作成します。

これは私が私の手順の中に入れたものです:

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」が発生しました:

私は自分ができると思うすべてのグーグルを実行しましたが、何が間違っているのかわかりません。私が持っている他の質問を回避するために、次のものを入れてそれをやろうとしました:

DECLARE 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 に答える