2014-09-15 1 views
0

У меня есть 3 базы данных оракула: db1, db2, db3. Я создал ссылки базы данных с db1 на db2 и db3, называемые db002link и db003link. Теперь у меня есть процедура, которая принимает в качестве входных данных дату и принимает различные действия над таблицами в соответствии с этим вводом. Один из них, однако, требует подключения к одной из баз данных db2 или db3. Перед выполнением процедуры я не знаю, к какому из них, так как это зависит от данных, собранных самой процедурой на предыдущих шагах. Так что мне нужно объединить некоторые переменные, чтобы создать ссылку на db, а затем подключиться через нее.Ссылка на динамическую базу данных Oracle из переменных

У меня есть переменная v_dbnumber, которая является varchar (3) и выглядит, например, как «003» и является результатом выбора из таблицы. Я попытался следующий:

v_dbconn := 'db'||v_dbnumber||'link' 

Но тогда следующий шаг, select * from [email protected]_dbconn получает ошибку компиляции для процедуры: ORA-04052, ORA-00604, ORA-02019 со ссылкой на несуществующие связи. Но объект отображается как: @v_dbconn вместо @ db003link.

Может кто-нибудь, пожалуйста, помогите мне в этом?

ответ

2

Если вам нужно, чтобы оператор был динамическим, вам нужно использовать динамический SQL.

Если вы просто хотите, чтобы открыть курсор, используя динамически сгенерированный оператор SQL, вы можете сделать что-то вроде

DECLARE 
    l_sql_stmt varchar2(1000); 
    l_dblink varchar2(100) := 'db002link'; 
    l_rc  sys_refcursor; 
BEGIN 
    l_sql := 'select * from [email protected]' || l_dblink; 
    open l_rc for l_sql; 
END; 

Обычно, хотя, вы делаете что-то с данными, которые вы выбираете. Это обычно связано с использованием либо dbms_sql, либо EXECUTE IMMEDIATE для выполнения оператора и получения данных в локальную переменную или коллекцию. Предполагая, что определения таблицы одинаковы в каждом из баз данных, вы могли бы сделать что-то вроде

EXECUTE IMMEDIATE l_sql 
    BULK COLLECT INTO <<some appropriate collection>> 
+0

Благодарим вас за руководство. Решаемые. – Geo

0

моего решения очень похоже на Джастин, хотя я использую процедуру с динамическим SQL.

[email protected]> CREATE OR REPLACE PROCEDURE test_dblink(
    2  db_link VARCHAR2) 
    3 AS 
    4 v_sql VARCHAR2(500); 
    5 v_test dual.dummy%TYPE; 
    6 BEGIN 
    7 v_sql := 'select dummy from [email protected]'|| db_link; 
    8 EXECUTE IMMEDIATE v_sql INTO v_test; 
    9 DBMS_OUTPUT.PUT_LINE(v_test); 
10 END; 
11/

Procedure created. 

[email protected]> commit; 

Commit complete. 

[email protected]> 
[email protected]> 
[email protected]> 
[email protected]> begin 
    2 test_dblink('db003link'); 
    3 end; 
    4/
X 

PL/SQL procedure successfully completed. 

У этой функции нет обработки ошибок, и предполагается, что одна запись будет возвращена (как правило, не является хорошим предположением).

+0

Спасибо, я принял тот же подход, внедренный в процедуру. – Geo

Смежные вопросы