使用另一个表列数据

问题描述:

我有两个表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分钟。有没有更好的方法来比较列?

这是不完全清楚你想要达到什么。基于一个或多个列值确保行的唯一性的常规方法是创建唯一索引。

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

每当你尝试插入一条记录的字段值的组合已经存在于表中,将引发异常(DUP_VAL_ON_INDEX)。

+0

我想两列与其他表中的一个表进行比较。如果找不到,请插入它们。如果发现更新第三列值。 – mallikarjun 2012-07-25 18:19:26

您的代码通过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