使用另一个表列数据在一个表中查找行

时间:2012-07-25 09:44:29

标签: oracle oracle11g

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

2 个答案:

答案 0 :(得分:0)

你想要实现的目标并不完全清楚。基于一个或多个列值确保行唯一性的常规方法是创建唯一索引。

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

每当您尝试插入包含表中已存在的列值组合的记录时,都会引发异常(DUP_VAL_ON_INDEX)。

答案 1 :(得分: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 Sequence。
  2. 使用双引号混合大小写标识符。这只是一系列等待发生的ORA-00904错误。只需使用大写标识符,忘记双引号。