2012-09-18 6 views
0

항목 그룹화를 나타내는 테이블 (table1)과 항목 자체를 나타내는 다른 테이블 (table2)이 있습니다.
table1.id는 table2의 외래 키이며 table1의 모든 레코드에서 해당 레코드와 관련된 테이블 2의 총 레코드 수 및 다양한 필드의 합계와 같은 정보를 수집하여 그룹화 및 요약을 표시 할 수 있습니다. table2를 질의 할 필요없이 그 안에 들어있는 것들.
일반적으로 table2의 항목은 한 번에 하나씩 추가/제거되므로 table2의 변경 사항을 반영하도록 table1을 업데이트합니다.하위 쿼리로 ORACLE의 조건부 업데이트

새로운 요구 사항이 발생하여 그룹의 항목을 선택하면 새 그룹으로 이동해야합니다. 나는 3 단계 작업으로 생각 :

  1. 이 표에 새 그룹을 만들 표 2
  2. 갱신 선택이 끝난 기록이 표에서 새로 만든 녹화를 가리 키도록

세 번째 단계는 것 그룹의 레코드 수를 뺍니다. 필요한 다른 필드의 합계를 표시하고 새 그룹에 추가합니다. 데이터는 새 그룹과 연관된 항목에 대해 table2를 쿼리하는 것으로 쉽게 찾을 수 있습니다.

나는 다음과 같은 내용의 문장을 만들었습니다.

update table1 t1 set 
countitems = ( 
    case t1.id 
     when 1 then t1.countitems - (select count(t2.id) from table2 t2 where t2.id = 2) 
     when 2 then (select count(t2.id) from table2 t2 where t2.id = 2) 
    end 
), 
sumitems = (
    case t1.id 
     when 1 then t1.sumitems - (select sum(t2.num) from table2 t2 where t2.id = 2) 
     when 2 then (select sum(t2.num) from table2 t2 where t2.id = 2) 
    end 
) 
where t1.id in(1, 2); 

언제든지 하위 쿼리를 반복하지 않아도 명령문을 다시 작성할 수 있습니까?

감사
피에로

답변

0

당신은 커서를 사용할 수 있으며, 대량는 ROWID에 UPDATE 문을 수집합니다. 그렇게하면 원하는 결과로 조인 쿼리를 작성하고 해당 값으로 테이블을 업데이트 할 수 있습니다. 저는 항상이 기능을 사용하고 매회 약간의 조정을합니다.

declare 
    cursor cur_cur 
    IS 
    select ti.rowid  row_id 
    ,  count(t2.id) countitems 
    ,  sum(t2.num) numitems 
    from table t1 
    join table t2 on t1.id = t2.t1_id 
    order by row_id 
    ; 

    type type_rowid_array is table of rowid index by binary_integer; 
    type type_countitems_array is table of table1.countitems%type; 
    type type_numitems_array is table of table1.numitems%type; 

    arr_rowid type_rowid_array; 
    arr_countitems type_countitems_array; 
    arr_numitems type_numitems_array; 

    v_commit_size number := 10000; 

begin 
    open cur_cur; 

    loop 
     fetch cur_cur bulk collect into arr_rowid, arr_countitems, arr_numitems limit v_commit_size; 

     forall i in arr_rowid.first .. arr_rowid.last 
      update table1 tab 
      SET tab.countitems = arr_countitems(i) 
      ,  tab.numitems = arr_numitems(i) 
      where tab.rowid = arr_rowid(i) 
      ; 

     commit; 
     exit when cur_cur%notfound; 

    end loop; 

    close cur_cur; 
    commit; 

exception 
    when others 
    then rollback; 
     raise_application_error(-20000, 'ERROR updating table1(countitems,numitems) - '||sqlerrm); 

end;