2013-04-15 2 views
1

비정규 화 된 데이터를 포함하는 테이블을 새로 고치는 Oracle에 저장 프로 시저를 작성하고 있습니다. 절차 개요는 다음과 같습니다.오라클 원자 저장 프로 시저

CREATE OR REPLACE PROCEDURE loadDenormalizedTable IS 
BEGIN 

DELETE FROM denormalizedTable; 

INSERT INTO 
    denormalizedTable 
    (
     data 
    ) 
SELECT DISTINCT 
    data 
FROM 
    normalizedTables; 

END; 
/

이 모든 것이 트랜잭션에서 발생하기 때문에 항상 테이블에 데이터가 있어야합니다. 지금은 삭제가 실행되고 삽입이 완료 될 때까지 몇 분 동안 테이블이 비어 있습니다. 어떤 유형의 다운 타임없이이 유형의 테이블 새로 고침을 처리하는 가장 좋은 방법은 무엇입니까?

+1

커밋 할 때까지 삭제가 다른 세션에 표시되지 않습니다. 프로 시저 내에서 수행하면 안됩니다. 그래서 빈 테이블이 보일 것입니다. 그러나 아무도 그 테이블을 보지 않을 것입니다. 이것은 실제 절차의 상당히 축소 된 버전입니까? 또한 ... [materialized views] (http://docs.oracle.com/cd/E11882_01/server.112/e25789/schemaob.htm#CFAIGHFC)를 재발 명하고 있습니까? –

+0

감사! 세션 문제가 나를 트 랩핑했습니다. 이제 테이블을 새로 고치는 동안 데이터가 응용 프로그램에서 계속 볼 수 있습니다. 그것은 실제 테이블과 컬럼을 모두 제거하고 자리 표시자를 넣는 점에서 잘립니다. 구조는 동일합니다. 예, 이것이 구체화 된 뷰를 재창조하고 있으며, 데이터 아키텍트는 MV의 팬이 아닙니다. – wshato

+0

매트보기에 문제가 있습니까? 원자 적으로 또는 비 원자 적으로 새로 고칠 수 있습니다. 일단 생성되면이 모든 작업을 단일 새로 고침 문으로 줄일 수 있습니다. 나는 당신의 데이터 "건축가"에 대해 어떻게 생각하는지 말하지 않을 것입니다. – tbone

답변

1

기본적으로 프로 시저는 세션이 소유 한 더 큰 트랜잭션의 일부로 실행됩니다. documentation 언급으로 :

참고 : 트랜잭션은 여러 블록에 걸쳐 수 있으며, 블록은 여러 개의 트랜잭션을 포함 할 수 있습니다. 프로 시저를 호출 한 후 커밋 될 때까지 설명 된대로 코드와

, 다른 세션은 삭제 또는 삽입을 볼 수 없습니다. 당신은 단지는 SQL *에서 실행 플러스 예를 들어 메시지를 표시하는 경우 :

SQL> exec loadDenormalizedTable; 

PL/SQL procedure successfully completed. 

SQL> 

은 ... 여전히 심지어 삭제 및 삽입 모두 후, 이전 데이터를 볼 수 테이블을보고 또 다음 사람이 완료되었습니다. (다른 사람이 프로 시저를 실행하거나 denormalizedTable에 데이터를 삽입하거나 삭제하면 차단되지만 다른 사람들이 쿼리를 수행 할 것으로 예상 할 수 있습니다). 일단 commit을 발행하면 모든 사람이 같은 것을 볼 수 있습니다.

수동 프로 시저 내에서 트랜잭션을 종료하는 것입니다 설명하는 동작을 얻을 수있는 유일한 방법 :

CREATE OR REPLACE PROCEDURE loadDenormalizedTable IS 
BEGIN 

DELETE FROM denormalizedTable; 

COMMIT WORK; -- makes the delete visible elsewhere 

INSERT INTO 
    denormalizedTable 
    (
     data 
    ) 
SELECT DISTINCT 
    data 
FROM 
    normalizedTables;  
END; 
/

당신은 절차의 중간에 commit을 필요로하지 않는, 그리고 당신이 매우 드문 원 자성을 깨뜨리는 것처럼 그렇게하기를 원하거나해야할 것입니다.

당신이 그것을 깨닫지 않고 암시 적 커밋을하는 일은 가능할 수 있습니다. 어쩌면 자신의 커밋을 수행하는 다른 프로 시저 또는 함수를 호출 할 수도 있습니다 (그렇게하지 않는 이유 중 하나 - 예기치 않은 부작용이있을 수 있습니다!) 또는 DDL 문 - 항상 암시 적으로 커밋을 수행하지만, 동적 SQL을 사용하여 그렇게해야합니다.

다른 가능성은 delete을 실제로 수행하지 않고 있지만 truncate을 수행하고 있다는 것입니다. 이는 다른 사람들이 즉시 확인할 수 있습니다. 명시 적 커밋 없이는 in the documentation을 암시합니다. 그것은 또한 당신이 제공 한 윤곽에서 뜻 깊은 출발 일 것입니다.

+0

저는 Oracle에서 세션이 작동하는 방식에 익숙해졌습니다. 당신이 묘사 한대로 정확하게 작동합니다. 감사. – wshato

1

Oracle 파티셔닝 옵션을 사용할 수있는 경우 파티션 스와핑 작업을 사용하는 것이 가장 효과적이고 효율적인 방법입니다. 이것은 많은 대규모 데이터웨어 하우스에서 수행되는 매우 일반적인 작업입니다. 예를 들어 당신이 denormalizedTable과 똑같은 구조의 두 번째 테이블을 상상할 수

http://www.akadia.com/services/ora_exchange_partition.html http://gerardnico.com/wiki/database/oracle/partition_exchange_loading

:

은 몇 가지 예를 참조하십시오. 당신의로드 작업을 구현하려면 :

  • 는 denormalizedTable2
  • 교환을 denormalizeTable2에 테이블 denormalizedTable 및 denormalizedTable2
  • 의 파티션

그것은 일반적으로 실행중인 응용 프로그램에 미치는 영향을 최소화 보장을 데이터를 삽입 자릅니다.

+0

감사합니다. DBAs가 잘라 내기와 삭제를 선호한다면이 점을 명심하십시오. – wshato