私は別のデータベースユーザーを参照する必要がある場合があります。私はそれを参照しながら、ビューでデータベースのユーザー名をハードコードする必要があります。他のデータベースユーザを動的に参照する方法は?
SELECT * FROM eg001t3.DUAL; // example.
ビューを動的またはデータベースのセットアップに基づいてからそのDBユーザー(eg001t3)を参照する方法はありますか?
私は別のデータベースユーザーを参照する必要がある場合があります。私はそれを参照しながら、ビューでデータベースのユーザー名をハードコードする必要があります。他のデータベースユーザを動的に参照する方法は?
SELECT * FROM eg001t3.DUAL; // example.
ビューを動的またはデータベースのセットアップに基づいてからそのDBユーザー(eg001t3)を参照する方法はありますか?
さらに高度なオプションがありますが、その場で同義語を作成するか、動的SQL/EXECUTE IMMEDIATEを使用することができます。
pl/sqlでは、EXECUTE IMMEDIATEまたはDBMS_SQLを使用してオブジェクトを動的に参照します。
EXECUTE IMMEDIATEとExemple:
SQL> VARIABLE dyn_user VARCHAR2(30);
SQL> EXEC :dyn_user := 'SYS';
PL/SQL procedure successfully completed
dyn_user
---------
SYS
SQL> DECLARE
2 ln NUMBER;
3 BEGIN
4 EXECUTE IMMEDIATE 'SELECT 1
5 FROM ' || dbms_assert.schema_name(:dyn_user)
6 || '.DUAL'
7 INTO ln;
8 dbms_output.put_line(ln);
9 END;
10/
1
PL/SQL procedure successfully completed
あなたはまた、動的に構築されたREF CURSORを使用することができます:あなたはあなたの入力を検証するためにDBMS_ASSERTを使用することができます示すように
SQL> DECLARE
2 lc SYS_REFCURSOR;
3 ln NUMBER;
4 BEGIN
5 OPEN lc FOR 'SELECT 1
6 FROM ' || dbms_assert.schema_name(:dyn_user) || '.DUAL
7 CONNECT BY level <= 2';
8 LOOP
9 FETCH lc
10 INTO ln;
11 EXIT WHEN lc%NOTFOUND;
12 dbms_output.put_line(ln);
13 END LOOP;
14 CLOSE lc;
15 END;
16/
1
1
を。
jvaで提案されている別の方法を示す新しい回答を追加します。すべての表は共通の構造を共有する必要があります(コンパイル時にOracleがビューの列のデータ型を認識できるようにする必要があります)。
セットアップ:
-- create 2 schemas
CREATE USER u1 IDENTIFIED BY u1;
CREATE USER u2 IDENTIFIED BY u2;
GRANT RESOURCE TO u1;
GRANT RESOURCE TO u2;
-- one table in each schema
CREATE TABLE u1.t AS
SELECT 2 * ROWNUM ID, 'foo' DATA FROM dual CONNECT BY LEVEL <= 5;
CREATE TABLE u2.t AS
SELECT 2 * ROWNUM - 1 ID, 'bar' DATA FROM dual CONNECT BY LEVEL <= 5;
GRANT SELECT ON u2.t TO u1;
-- the common structure
CREATE TYPE u1.t_row AS OBJECT (ID NUMBER, DATA VARCHAR2(3));
/
CREATE TYPE u1.t_row_list AS TABLE OF u1.t_row;
/
CREATE OR REPLACE PACKAGE u1.test_pck IS
schema_name VARCHAR2(30) := 'U1';
FUNCTION select_t RETURN u1.t_row_list PIPELINED;
END test_pck;
/
--Definition of the pipelined function and the view:
CREATE OR REPLACE PACKAGE BODY u1.test_pck IS
FUNCTION select_t RETURN u1.t_row_list PIPELINED IS
l_rc SYS_REFCURSOR;
l_id NUMBER;
l_data VARCHAR2(3);
BEGIN
OPEN l_rc FOR 'SELECT id, data
FROM ' || dbms_assert.schema_name(schema_name) || '.t';
LOOP
FETCH l_rc
INTO l_id, l_data;
EXIT WHEN l_rc%NOTFOUND;
PIPE ROW (u1.t_row(l_id, l_data));
END LOOP;
CLOSE l_rc;
END select_t;
END test_pck;
/
CREATE OR REPLACE VIEW u1.v AS
SELECT ID, DATA
FROM TABLE(u1.test_pck.select_t);
あなたは、スキーマ名を含むパッケージでグローバル変数を定義し、ビューを照会します:あなたのために働くかもしれない
SQL> EXEC u1.test_pck.schema_name := 'U1';
PL/SQL procedure successfully completed
SQL> SELECT * FROM u1.v;
ID DATA
---------- ----
2 foo
4 foo
6 foo
8 foo
10 foo
SQL> EXEC u1.test_pck.schema_name := 'U2';
PL/SQL procedure successfully completed
SQL> SELECT * FROM u1.v;
ID DATA
---------- ----
1 bar
3 bar
5 bar
7 bar
9 bar
別のオプション(に応じてあなたがこれを行う必要があるアプリケーション環境)は、あなたの名前空間を関心のあるスキーマに一時的に変更することです:
セットCURRENT_SCHEMAは、どのような方法でのOracle権限モデルをバイパスしません - あなたはまだよ他のスキーマの関心のあるテーブルで少なくともSELECTが必要です。
によって提案された方法を示す別の回答を追加しました。これは機能し、私の考えよりはるかに優れています。 – jva
あなたはそのデータを表示する必要がありますか、それともDBでそれ以上のことをしますか? – jva
私は、表示するために別のデータベースユーザーからデータを取得する必要があります。 – Ahmed