다른 데이터베이스 사용자를 참조해야하는 경우가 있습니다. 그것을 참조하는 동안보기에서 데이터베이스 사용자 이름을 하드 코딩해야합니다.다른 데이터베이스 사용자를 동적으로 참조하는 방법은 무엇입니까?
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 : 당신은 동적 REF CURSOR를 구축 사용할 수 있습니다
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
: 당신이 당신의 입력의 유효성을 검사 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에서 제안한 다른 방법을 보여주기 위해 새로운 대답을 추가했습니다. 모든 테이블은 공통 구조를 공유해야합니다 (오라클은 컴파일시 뷰의 열 데이터 유형을 알 수 있습니다).
설정 :
-- 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에 - 당신은 여전히거야 관심있는 다른 스키마의 테이블에서 적어도 SELECT가 필요합니다.
에 의해 제안 된 방법을 보여주는 또 다른 답변을 추가했습니다.이 방법은 효과가 있으며 내 생각보다 훨씬 낫습니다. – jva
데이터를 표시해야하거나 DB에서 더 많은 작업을 수행 할 예정입니까? – jva
표시를 위해 다른 데이터베이스 사용자로부터 데이터를 검색하면됩니다. – Ahmed