2011-08-30 3 views
4

다 대일 관계가있는 두 개의 테이블이 있습니다. (Oracle)sql이 하위 및 상위 테이블에 삽입

**Table: PARENT** 
Field: A (PK) 
Field: B 
Field: C1 
Field: C2 
Field: C3 
Field: C4 
Field: C5 

**Table CHILD** 
Field: A (PK) (FK to PARENT.A) 
Field: D (PK) 
Field: E 

동시에 삽입되는 레코드와 부모 테이블이 동시에 삽입됩니다.

제가 궁금해하는 점은 이것을 수행하는 가장 효율적인 방법입니다.

현재이 전체 삽입 단계에 대해 호출 응용 프로그램에서 호출하는 저장 프로 시저가 하나 있습니다. 저장 프로 시저에는 현재 다음과 같은 서명이 있습니다.

Field: A 
Field: B 
Field: C (dilimited string) 
Field: D (dilimited string) 
Field: E (dilimited string) 

이 절차는 입력에서 C를 반복하고 각 값을 배열에 저장합니다. 그런 다음 해당 배열을 입력에서 A와 B와 함께 사용하여 PARENT 테이블에 삽입합니다.

입력에서 A를 사용하고 입력에서 D와 E를 반복하고 희석 된 문자열의 각 항목에 대해 CHILD 테이블에 삽입합니다.

이것은 하루에 최대 3 백만 번 호출됩니다. 가능한 한 효율적이어야합니다.

하나가 아닌 여러 SP 호출을 할 때 얼마나 많은 효율성이 손실됩니까?

뚜렷한 문자열을 처리하는 데 필요한 모든 루핑 작업이 많은 것처럼 보입니다!

호출 응용 프로그램이 각 항목에 대해 별도의 SP 호출을 만들 수 있다고 생각했습니다. 그러나, 어떻게 든 어린이 삽입물이 부모에게 삽입되기 전에 어떻게 될지를 어떻게 보장 할 수 있습니까? 그리고 그것은 더 많은 저장 프로 시저 호출이 될 것입니다. (가 10보다 일반적으로 더 적은있다, 그러나이 될 수있을 때 여러 번 삽입 할 자식 레코드가없는만큼 50)

나는 또한 개방 dilimted 문자열의 정보 C.

을 얻을 수있는 또 다른 방법으로

희박한 문자열에서 정보를 얻으려면 while 루프보다 더 좋은 점이 있습니까?

나는 SP를 쓰지 않았다. 나는 작은 수정을하고 가능한 한 더 효율적으로 만들 것을 요청 받았다.

아이디어가 있으십니까?

참고 :

나는 테이블을 단순화 dilitied 문자열에서 10 개 항목이 실제로있다 (C)하지 오, 테이블 부모에 삽입 얻으려면, C와 같은 두 개 더 dilited 문자열도 있습니다. 테이블에는 표시된 것보다 몇 개의 필드가 있습니다.

레코드는 30 일 후에 삭제됩니다. 비슷한 열 유사한 항목을 넣어 구분 된 문자열을 통해 반복하는 경우

+0

나중에, 나는이 모든 것을 끝내기 위해서 – kralco626

답변

1

이 ...

먼저 여기에 몇 가지가있다, 당신은 가능성이 더 정규화 할 테이블을 리팩토링 할 필요가있다. 예를 들어, C이 전화 번호의 구분 된 목록이고 C1 - C5의 열이 phone1 - phone5 인 경우 별도의 자식 phone이 있어야합니다. 이것은 유스 케이스에 달려 있지만 잠재적 인 미래의 문제 (즉, 구분 기호에 대한 지식)로서 나를 공격합니다. 구분 된 문자열에 불일치 데이터 (전화 번호, 도시, 이름 등)가있는 경우 - 각 개별 데이터 요소에 대해 별도의 항목 매개 변수를 작성하십시오. 이것은 잠재적으로 더 큰 문제입니다 (항목의 순서가 중요 할 경우 기간이 맞지 않기 때문에).

당신이 맞다면 구분 된 문자열을 반복하는 것은 많은 작업입니다. RDBMS에 내장 된 split 함수가 있거나 (또는 ​​외부 함수를 호출 할 수있는 경우가 아니면) 반드시 더 좋은 방법은 아닙니다. 만약 내가 할 수 있으면 차라리 피하겠습니다. child 저장 프로 시저를 호출하십시오. 그것은 어른이 될 것입니다. 그러나 실제로는 어쨌든 더 낫습니다. 반드시 성능을 현명하게하는 것이 아니라 개념을 개념화하고 미래의 기본 태도를 유지하는 것입니다.

행이 parent없이 삽입되지 않도록하려면 어떻게해야합니까? 외래 키 제약 조건을 사용하십시오. 제약 조건을 위반하면 호출자의 잘못이 아니라 DB의 잘못입니다.

좋아, 이들 중 일부는 SP의 주요 변경 사항이 필요하며 일부는 기본 테이블 구조에 대한 변경이 필요합니다. 처음에 올바르게 설정된 경우 이 대부분이 사용자에게 투명해야합니다. 그러나 이것은

아 ... 내가 시도한 것이 무엇이며, 피스는이 문제를 처리하는 가장 효율적인 방법

+0

을 너무 곤란하게했다. proc은 커밋을한다. 또한 롤백을 수행하는 Exception 절이 있습니다. 누군가가 문자열을 분할하고 한 단계에 모두 삽입하는 멋진 방법을 원했을 때, 나는 몇 분 전에 뭔가 멋진 것을 발견했습니다. http://www.oracle-developer.net/display.php?id= 412 – kralco626

+0

... oracle에는 분명히 액세스 권한이없는 일부 항목이 있습니다 (DB2에 있습니다). 공급 업체에 따라 테이블에 전체 배열을 삽입하는 방법도 있지만 유용성과 유용성이 다릅니다. –

0

사용자 정의 데이터를 사용하는 것입니다 ...이 모두가 확약 제어를 실행중인 말해 구분 된 문자열이 아닌 배열로 값 목록을 지나서 저장 프로 시저에 전달합니다. 다음과 같은 내용이 있습니다 :

CREATE TYPE r_child IS OBJECT 
    (a NUMBER, d VARCHAR2(20), e VARCHAR2(20)); 

CREATE TYPE nt_child AS TABLE OF r_child; 

CREATE TYPE nt_c AS TABLE OF VARCHAR2(20); 

CREATE PROCEDURE insert_data(
    p_a NUMBER, p_b VARCHAR2, p_c nt_c, 
    p_child nt_child 
) AS 
    v_parent parent%ROWTYPE; 
    i   NUMBER; 
BEGIN 
    v_parent.a := p_a; 
    v_parent.b := p_a; 

    FOR i IN p_c.FIRST .. p_c.LAST LOOP 
     CASE i 
     WHEN 1 THEN 
      v_parent.c1 := p_c(i); 
     WHEN 2 THEN 
      v_parent.c2 := p_c(i); 
     WHEN 3 THEN 
      v_parent.c3 := p_c(i); 
     WHEN 4 THEN 
      v_parent.c4 := p_c(i); 
     WHEN 5 THEN 
      v_parent.c5 := p_c(i); 
     END CASE; 
    END LOOP; 

    INSERT INTO parent(
         a, 
         b, 
         c1, 
         c2, 
         c3, 
         c4, 
         c5 
      ) 
    VALUES  v_parent; 

    FORALL i IN p_child.FIRST .. p_child.LAST 
     INSERT INTO child(
          a, d, e 
       ) 
     VALUES  (
        p_a, p_child(i).d, p_child(i).e 
       ); 
END insert_data; 

패키지를 잘 디자인하면 패키지에 삽입을 배치해도 상당한 실행 시간이 추가되지 않습니다. 여기에는 대량 삽입 (예 : forall 사용)과 데이터를 인코딩하고 디코딩하는 대신 데이터베이스가 자연스럽게 읽을 수있는 데이터 구조를 사용하는 것이 포함됩니다 (현재 구분 된 값으로 처리하고 있음).

+0

나는 생각을 좋아하지만 배열로 나를 넘겨 줄 것을 확신 할 수는 없다 ... 나는 호출 어플리케이션 코드와 SP를 쓰고 싶지만 나는 그렇지 않다. (... 나는 손이 묶여 있다고 생각한다. 그래도 좋은 생각이야. – kralco626