2012-01-17 116 views
1

我在oracle中有一個表,其中的數據從某個第三方插入。我想從該表填充主表。那麼,什麼是使用集合的最佳性能表現方式。Oracle中的條件插入或更新

E.g.假設數據將從第三方填充到的表是'EMP_TMP'。

現在我想通過將從EMP_TMP表填充的過程填充'EMPLOYEE'主表。

這裏又有一個條件,如IF SAME EMPID(這不是主鍵)EXISTS那麼我們必須更新FULL TABLE,它包含相同的EMPID ELSE我們有INSERT NEW RECORD。

[注:這裏EMPID是VARCHAR2和EMPNO將是主鍵,我們將使用SEQUENCE]

我覺得這裏合併將不會執行好得多performancewise,因爲我們不能在MERGE語句中使用集合。

+2

你需要解釋爲什麼合併是行不通的好一點。它專爲這種upsert風格的場景設計。另一種方法是回到舊學校預先合併,這是2條語句,更新的內部連接和插入的左側反連接。 – Andrew 2012-01-17 16:13:32

+0

我知道合併會起作用。如果它的性能比BULK COLLECT更好,對我來說可以。這裏的數據也將以十萬盧比爲單位。 – user1017936 2012-01-17 16:16:02

+0

@ user1017936 - 與編寫模擬相同操作的循環代碼相比,單個SQL語句(無論是「INSERT」,「UPDATE」,「DELETE」還是「MERGE」)效率更高。使用'BULK COLLECT'可以使循環代碼更高效,但不會比SQL更高效。 – 2012-01-17 16:24:31

回答

0

好吧,如果性能是你的首要考慮,而你不喜歡MERGE,那麼這個怎麼樣(如運行腳本,單筆交易):

delete from EMPLOYEE where emp_id IN (
select emp_id from EMP_TMP); 

insert into EMPLOYEE 
select * from EMP_TMP; 

commit; 

顯然不是「最安全」的方法(和正如書面假設完全相同的表定義,你有回滾),但應該很快(你也可以混淆IN與EXISTS等)。如果emp_id或emp_no是這兩個表中的常見關鍵字,但我無法完全理解您的帖子,但在您的情況下使用哪個更合理。

+0

我不能使用刪除,因爲在這裏emp_id是序列生成的主鍵,它以後也會有子記錄。對於參考empid將像1,2和emp_no將VARCHAR2像'ABC','DEF' – user1017936 2012-01-17 16:45:26

+1

@ user1017936 - 你在這個評論中說的是*與你在你的問題中說的完全相反。請記住你的想法。無論如何,無論這個活動密鑰是什麼,只要你有一個。在目標表中刪除某個鍵與源表中的鍵匹配的記錄,然後將臨時記錄插入到目標表中與執行「UPDATE FULL TABLE」相同 – APC 2012-01-17 18:23:23

0

創建一個程序,你需要使用PL/SQL。 先執行更新,然後測試sql%rowcount。 如果它是0,那麼沒有更新完成,你必須做一個插入。

我認爲這是相當有效的。

僞代碼

Update table; 
if sql%rowcount = 0 then 
    //get new sequence number 
    insert into table; 
END IF; 
COMMIT; 

HTH
HARV

+0

感謝所有人提供的解決方案。你們能否澄清最後一件事?現在,哪個更新將運行得更快。無論是通過MERGE還是使用PSEUDOCODE? – user1017936 2012-01-17 19:49:12

+0

我很確定MERGE會跑得更快,但我無法確切地說出這一點。 – Harv 2012-01-17 20:39:35

+0

這需要多長時間運行一次?每次運行多少條記錄? – Harv 2012-01-17 20:41:12