2012-07-25 65 views
0

我有兩個表tab1tab2查找一個表中的行。 tab1有39000條記錄,tab2有15000條記錄。 tab1tab2都有兩個公共列,分別爲item_numbercolor_code。但是在tab1中,color_code可能爲空,但不在tab2中。 item_number在兩個表中都不爲空。在tab2我必須從tab1插入一行(基於兩列的唯一行)數據。爲此我寫了一個這樣的程序。它會比較每一行,但它花費的時間太長。有什麼方法可以提高性能嗎?第一取兩個光標:使用另一個表列數據

CURSOR CUR_tab1 IS SELECT item_number,color_code FROM 
    (SELECT item_number,color_code, SNO RID , 
     MIN(SNO) OVER(partition BY item_number,color_code) 
     MIN_RID FROM tab1 ) WHERE RID= MIN_RID; 

CURSOR CUR_tab2 IS SELECT sno_2,item_number,color_code,PRIORITY FROM tab2; 

sonsno_2tab1tab2主鍵。

要查找一個表中的記錄我使用的是for loop

SELECT NVL(MAX(SNO_2),0) INTO SNO_COUNT FROM tab2; 
FOR CUR_tab1 IN CUR_NIIN_CAGE 
LOOP 
    -- GET THE NIIN_CAGE_PART RECORDS DATA. 
    OLD_NNCGP_NIIN := CUR_tab1 .item_number; 
    OLD_NNCGP_HCC := CUR_tab1 .color_codeC; 

    IF (SNO_COUNT>0 AND OLD_NNCGP_HCC IS NOT NULL) THEN -- IF RECORDS EXISTS IN DB 
     FOR CUR_tab2 IN CUR_NIIN_HCC 
     LOOP 
      OLD_NIIN  := CUR_tab2.item_number; 
      OLD_HCC   := CUR_tab2.color_codeC; 
      NIIN_PRIORITY := CUR_tab2.PRIORITY; 

      IF (trim(OLD_NNCGP_NIIN) = trim(OLD_NIIN) 
       AND trim(OLD_NNCGP_HCC)=trim(OLD_HCC)) THEN 
       -- DO NOTHING 
       ROW_COUNT:=0; 
       PROCESSED :=FALSE; 
       EXIT; 
      ELSE 
       ROW_COUNT:=ROW_COUNT+1; 
       PROCESSED :=TRUE; 
      END IF; 
     END LOOP; 
    ELSIF (SNO_COUNT=0 AND OLD_NNCGP_HCC IS NOT NULL) THEN 
     PROCESSED :=TRUE; 
     ROW_COUNT:=ROW_COUNT+1;     
    END IF; 

    IF ( PROCESSED) THEN 
     SNO_COUNT :=SNO_COUNT+1; 
     INSERT INTO tab2("SNO2","color_code","item_number","PRIORITY") 
     values (SNO_COUNT,OLD_NNCGP_HCC,OLD_NNCGP_NIIN,NULL); 
     COMMIT; 
    END IF; 

    PROCESSED:=FALSE; 
    ROW_COUNT:=0; 
END LOOP; 

但是這需要將近7分鐘。有沒有更好的方法來比較列?

回答

0

這是不完全清楚你想要達到什麼。基於一個或多個列值確保行的唯一性的常規方法是創建唯一索引。

alter table <table> 
    add constraint <constraint_name> unique (<column1>,..,<column_n>); 

每當你嘗試插入一條記錄的字段值的組合已經存在於表中,將引發異常(DUP_VAL_ON_INDEX)。

+0

我想兩列與其他表中的一個表進行比較。如果找不到,請插入它們。如果發現更新第三列值。 – mallikarjun 2012-07-25 18:19:26

0

您的代碼通過Agonizing Row基礎在行上插入記錄。這就是爲什麼它很慢。 SQL是基於集合的語言。所以擁抱喜悅集並看看你的表現增加。

不幸的是,你還沒有通知你的整個代碼示例,所以下面很可能是錯誤的細節,但它應該表現出你的想法是正確的:

SELECT NVL(MAX(SNO_2),0) INTO SNO_COUNT FROM tab2;   

    INSERT INTO tab2("SNO2","color_code","item_number","PRIORITY") 
     select SNO_COUNT+rownum,tab1.color_codeC,tab1.item_number,NULL) 
     from 
     (select distinct tab1.color_codeC,tab1.item_number 
      from tab1 
      where not exists 
      (select null from tab2 
       where trim(tab1."color_codeC") = trim(tab2."color_codeC") 
       and trim(tab1."item_number") = trim(tab2."item_number")) 

有一對夫婦的對你的數據模型不利的事情。

  1. 使用MAX(SNO_COUNT)。這種技術不能擴展,並且不適用於多用戶環境。您應該使用Oracle序列。
  2. 使用雙引號混合大小寫標識符。這只是一系列等待發生的ORA-00904錯誤。只需使用大寫標識符並忘記雙引號。
+0

我想將一個表中的兩列與其他表進行比較。如果找不到,請插入它們。但是tab2中的2列是唯一的,並且在tab1中item_number不爲null,但color_code爲null允許的列。所以tab1有多個item_number,color_code的組合。 – mallikarjun 2012-07-25 19:13:43

+0

@mallikarjun - 在這些情況下,如果你解釋你的業務邏輯而不是展示你的代碼(或者更糟糕的是,你的代碼的一部分,就像你所做的那樣)並且期待我們弄清楚它,那就更好了。無論如何,我修改了我的猜測,所以給了它一個旋風。 – APC 2012-07-26 07:46:40

相關問題