2013-04-15 90 views
1

我正在編寫一個Oracle存儲過程,它將刷新一個包含非規格化數據的表。該過程的要點是:Oracle原子存儲過程

CREATE OR REPLACE PROCEDURE loadDenormalizedTable IS 
BEGIN 

DELETE FROM denormalizedTable; 

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

END; 
/

我想所有這一切都在交易發生,這樣總會有表中的數據。現在刪除運行並且表格在幾分鐘內是空的,直到插入完成。什麼是處理這種類型的表刷新沒有任何停機時間的最佳方式?

+1

的刪除不會對其他會話可見。所以你會看到空桌子,但沒有人會。這是你真實程序的一個明顯縮減版嗎?此外...你重塑[物化視圖(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分區選項可用,則最好,也是最有效的方法是使用分區交換操作。這是在許多海量數據倉庫中完成的一項非常常見的操作。

看一些例子在:

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

例如,你可以想像具有完全相同的結構denormalizedTable第二個表。爲了實現你的負荷運轉:

  • 截斷denormalizedTable2
  • 將您的數據轉換成denormalizeTable2
  • 交換表denormalizedTable和denormalizedTable2
  • 的分區

它通常保證上運行的應用程序影響最小。

+0

謝謝。如果DBA更喜歡截斷與刪除,我會記住這一點。 – wshato