【问题标题】:Find the row in one table using another table column data使用另一个表的列数据查找一个表中的行
【发布时间】:2012-07-26 15:38:27
【问题描述】:

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

【问题讨论】:

    标签: oracle oracle11g


    【解决方案1】:

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

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

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

    【讨论】:

    • 我想将一张表中的两列与另一张表进行比较。如果没有找到插入它们。如果找到更新第三列值。
    【解决方案2】:

    您的代码会逐行插入记录。这就是为什么它很慢。 SQL 是一种基于集合的语言。因此,拥抱 Joy Of Sets 并见证您的绩效提升。

    很遗憾,您还没有发布您的整个代码示例,因此以下内容可能在细节上是错误的,但它应该表明您的想法是正确的:

        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 错误。只需使用大写标识符并忘记双引号。

    【讨论】:

    • 我想将一张表中的两列与另一张表进行比较。如果没有找到插入它们。但是 tab2 中的 2 列是唯一的,并且 tab1 中的 item_number 不为空,但 color_code 为空允许列。所以 tab1 有多个 item_number , color_code 的组合。
    • @mallikarjun - 在这些情况下,如果您解释您的业务逻辑而不是展示您的代码(或者更糟糕的是,您的代码的一部分,就像您所做的那样)并期望我们弄清楚它会更好.无论如何,我已经修改了我的猜测,所以试了一下。
    猜你喜欢
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-21
    • 2021-05-22
    • 1970-01-01
    • 2018-12-05
    • 2022-07-30
    相关资源
    最近更新 更多