2009-07-29 4 views
0

다른 데이터베이스 사용자를 참조해야하는 경우가 있습니다. 그것을 참조하는 동안보기에서 데이터베이스 사용자 이름을 하드 코딩해야합니다.다른 데이터베이스 사용자를 동적으로 참조하는 방법은 무엇입니까?

SELECT * FROM eg001t3.DUAL; // example. 

DB 사용자 (eg001t3)를보기에서 동적으로 또는 데이터베이스 설정을 기준으로 참조 할 수 있습니까?

+0

데이터를 표시해야하거나 DB에서 더 많은 작업을 수행 할 예정입니까? – jva

+0

표시를 위해 다른 데이터베이스 사용자로부터 데이터를 검색하면됩니다. – Ahmed

답변

1

더 세련된 옵션이있을 수 있지만 즉시 동의어를 만들거나 동적 SQL/EXECUTE IMMEDIATE를 사용할 수 있습니다.

3

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 

.

+0

View에서 사용할 수 있습니까? – Ahmed

+0

@Ahmed : 아니요, 조회수에서는 작동하지 않습니다. 뷰는 컴파일 할 때 참조하는 객체를 알아야합니다. –

+0

@ Vincent :보기를 위해이 작업을 수행 할 수있는 방법이 있습니까? – Ahmed

2

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 
1

당신을 위해 일 수있는 또 다른 옵션을 (에 따라 이 작업을 수행해야하는 응용 프로그램 환경)은 일시적으로 네임 스페이스를 원하는 스키마로 변경하는 것입니다.

  1. 세션 변경 설정 current_schema = eg001t3;
  2. select * from whateverTableBelongsToEG001T3; - 어떤 스키마 규정 여기에 필요하지
  3. ALTER 세션 세트 CURRENT_SCHEMA = ... - 다시 연결 스키마 이름을 어떤 방법으로 오라클 권한 모델을 우회하지 않습니다

설정 CURRENT_SCHEMA에 - 당신은 여전히거야 관심있는 다른 스키마의 테이블에서 적어도 SELECT가 필요합니다.

+0

에 의해 제안 된 방법을 보여주는 또 다른 답변을 추가했습니다.이 방법은 효과가 있으며 내 생각보다 훨씬 낫습니다. – jva

관련 문제