2010-04-13 3 views
4

스키마 A의 일부 데이터를 스키마 B에로드하는 PL/SQL 프로 시저를 작성 중입니다.이 스키마는 모두 매우 다른 스키마이므로 스키마 B의 구조를 변경할 수 없습니다.테이블 열을 키 값 쌍으로 변환

스키마 A의 다양한 테이블에있는 열 (뷰에서 함께 조인 됨)은 테이블의 두 열에 key => value 쌍으로 각각 별도의 행에 스키마 B에 삽입해야합니다. 예를 들어, 직원의 이름은 스키마 A의 employee.firstname로 존재할 수 있지만, 같은 스키마 B에 입력 할 필요가 :

id=>1, key=>'A123', value=>'Smith' 

거의 100 키를 추가 할 더의 가능성이 있습니다 앞으로는. 즉,이 키들을 하드 코드하고 싶지는 않습니다.

샘플 코드 :

create table schema_a_employees (
    emp_id number(8,0), 
    firstname varchar2(50), 
    surname varchar2(50) 
); 
insert into schema_a_employees values (1, 'James', 'Smith'); 
insert into schema_a_employees values (2, 'Fred', 'Jones'); 

create table schema_b_values (
    emp_id number(8,0), 
    the_key varchar2(5), 
    the_value varchar2(200) 
); 

내가 가장 가능성이 조회 테이블을 포함 할 우아한 솔루션은 각각의 키를 삽입 할 값을 결정하기 위해 생각과 같은 유사한 문 효율적으로 하드 코딩 수십 포함되지 않습니다 .. .. 내가 할 수 있도록하고 싶습니다 무엇

insert into schema_b_values (1, 'A123', v_firstname); 
insert into schema_b_values (1, 'B123', v_surname); 

은의 열 이름을 제공하는 칼럼과 함께, 스키마 B에서 모든 키를 나열 스키마 A의 로컬 조회 테이블을 가지고있다 예를 들어 스키마 A의 표를 채워야합니다. 스키마 B의 키 "A123"은 스키마 A의 "firstname"열의 값으로 채워 져야합니다.

create table schema_a_lookup (
    the_key varchar2(5), 
    the_local_field_name varchar2(50) 
); 
insert into schema_a_lookup values ('A123', 'firstname'); 
insert into schema_a_lookup values ('B123', 'surname'); 

그러나 어떻게 동적으로 조회 테이블의 값을 사용하여 Oracle에 사용할 열을 사용할 수 있는지 잘 모르겠습니다.

제 질문은 모든 가능한 키 (예 : A123, B123 등)를 하드 코딩하지 않고 schema_a_employees의 데이터로 schema_b_values ​​테이블을 채우는 우아한 솔루션입니까?

건배.

+0

+! 셋업 진술서를 증명하기 위해. 이로 인해 솔루션 테스트가 훨씬 쉬워졌습니다. – APC

답변

1

스키마 B가 dreadedkey-value pair 디자인이 아니길 진심으로 바랍니다. 일부 상황에서는 일부 동적 속성 값 테이블이 유용 할 수 있지만 가장 기본적인 쿼리를 제외한 모든 쿼리는 EAV 설계에 거의 쓸 수 없다는 것을 알게 될 것입니다 ("John Smith라는 이름의 모든 직원 찾기"와 같은 간단한 쿼리조차도). 쓰기 어렵고 조정할 수 없음).

SQL> SELECT 'INSERT ALL ' sql_lines FROM dual 
    2 UNION ALL 
    3 SELECT 'INTO schema_b_values VALUES (emp_id, ''' 
    4   || dbms_assert.simple_sql_name(the_key) 
    5   || ''', ' 
    6   || dbms_assert.simple_sql_name(the_local_field_name) 
    7   ||')' 
    8 FROM schema_a_lookup 
    9 UNION ALL 
10 SELECT 'SELECT * FROM schema_a_employees' FROM dual; 

SQL_LINES 
-------------------------------------------------------------------------------- 
INSERT ALL 
INTO schema_b_values VALUES (emp_id, 'A123', firstname) 
INTO schema_b_values VALUES (emp_id, 'B123', surname) 
SELECT * FROM schema_a_employees 

그런 다음 할 수 있습니다

SQL> INSERT ALL 
    2  INTO schema_b_values VALUES (emp_id, 'A123', firstname) 
    3  INTO schema_b_values VALUES (emp_id, 'B123', surname) 
    4  SELECT emp_id, firstname, surname 
    5  FROM schema_a_employees; 

4 rows inserted 

당신은 문을 생성하려면 다음 쿼리를 사용할 수 있습니다

어쨌든, 귀하의 경우에는 다음과 같이 표시됩니다 동적 쿼리를 작성하려면 EXECUTE IMMEDIATE 또는 DBMS_SQL을 사용하여 해당 명령문을 실행하십시오.

+0

완벽한, 이건 내가 찾고 있었던 것, 감사합니다. 불행히도 스키마 B는 실제로 두려운 키 - 값 디자인이지만 레거시이며 제 제어 밖에 있습니다. 좋은 솔루션 그래, 고마워. –

1

캡슐화 된 트랜잭션을 제공하기 때문에 접근 방식으로 INSERT ALL을 좋아합니다. 모든 행이 삽입되었거나 전혀 없습니다. 데이터 이전 경험이 매우 반복적 인 경향이 있으므로 정리 및 회귀를 지원하는 것은 별개의 혜택입니다.

SQL> declare 
    2  l_src_name varchar2(30) := 'SCHEMA_A_EMPLOYEES'; 
    3  l_tgt_name varchar2(30) := 'SCHEMA_B_VALUES'; 
    4  stmt varchar2(32767); 
    5 begin 
    6  for pk_rec in (select cc.table_name, cc.column_name 
    7      from user_cons_columns cc 
    8        , user_constraints c 
    9      where c.table_name = l_src_name 
10      and c.constraint_type = 'P' 
11      and cc.table_name = l_src_name) 
12  loop 
13   stmt := 'insert all'; 
14   for col_rec in (select * from schema_a_lookup) 
15   loop 
16    stmt := stmt||' into '||l_tgt_name||' values (' 
17     ||pk_rec.column_name 
18     ||', '''||col_rec.the_key||''',' 
19     ||col_rec.the_local_field_name 
20     ||')'; 
21   end loop; 
22   stmt := stmt||' select * from '||l_src_name; 
23  end loop; 
24  execute immediate stmt; 
25 end; 
26/

PL/SQL procedure successfully completed. 

SQL> 

얼마나 많은 행이 있습니까?

SQL> select * from schema_b_values; 

    EMP_ID THE_K THE_VALUE 
---------- ----- --------------- 
     1 A123 James 
     2 A123 Fred 
     1 B123 Smith 
     2 B123 Jones 

SQL> 

추가 자동화를 향한 지침이므로 PL/SQL에서 쿼리를 래핑했습니다. SOURCE W TARGET 테이블 이름을 보유 할 테이블을 추가 할 수 있습니다. 소스 테이블에 복합 기본 키가있는 경우 분명히 범위가 있습니다.

+0

니스, 여기 데이터 사전 사용에 대해서는 생각하지 못했습니다. –

관련 문제