简体   繁体   English

更新MERGE语句ORACLE中的多个列

[英]Update multiple columns in MERGE statement ORACLE

I want to update multiple columns in MERGE statement,but for each column the conditions are different.How can I achieve it. 我想更新MERGE语句中的多个列,但是对于每个列,条件都不同。如何实现它。

I have more than 1 million rows in both the tables.All columns are number.Except Id all 3 columns have number with precision around 18 digits eg: 1.34255353433230675 我在两个表中都有超过一百万行。所有列都是数字。除了ID以外,所有3列的数字精度都在18位左右,例如:1.34255353433230675

Is there a better way to Update.Around 50,000 rows might update daily So I have to merge the updates values to target table. 有没有更好的更新方法。每天大约有50,000行可能会更新,所以我必须将更新值合并到目标表中。 I tried UPDATE and FORALL but its slow. 我尝试了UPDATE和FORALL,但是速度很慢。

I basically want to merge the difference based on common ID column.Any other approach is better? 我基本上想基于公共ID列合并差异,还有其他方法更好吗?

DECLARE
TYPE test1_t IS TABLE OF test.score%TYPE INDEX BY PLS_INTEGER;
TYPE test2_t IS TABLE OF test.id%TYPE INDEX BY PLS_INTEGER;
TYPE test3_t IS TABLE OF test.Crank%TYPE INDEX BY PLS_INTEGER;
TYPE test4_t IS TABLE OF test.urank%TYPE INDEX BY PLS_INTEGER;

vscore    test1_t;
vid       test2_t;
vcrank    test3_t;
vurank    test4_t;
BEGIN
 SELECT id,score,crank,urank
 BULK   COLLECT INTO vid,vscore,vcrank,vurank
 FROM   test;

 FORALL i IN 1 .. vid.COUNT
  MERGE INTO final T
  USING      (SELECT vid (i) AS o_id,
                     vcrank (i) AS o_crank,
                     vurank (i) AS o_urank
                     vscore (i) AS o_score
              FROM   DUAL) S
  ON         (S.o_id = T.id)
  WHEN MATCHED THEN
  UPDATE SET T.crank = S.o_crank
  WHERE  T.crank <> S.o_crank;

  UPDATE SET T.crank = S.o_crank
  WHERE  T.crank <> S.o_crank;

  UPDATE SET T.crank = S.o_crank
  WHERE  T.crank <> S.o_crank;

  UPDATE SET T.score = S.score
  WHERE  T.score <> S.score;

 -- I tried the below case its not working either...
--   UPDATE SET T.crank = (CASE WHEN T.crank <> S.o_crank
--                        THEN S.o_crank
--                        END),
--           T.urank = (CASE WHEN T.urank <> S.o_urank
--                        THEN S.o_urank
--                        END);  

 COMMIT;
END;

/ /

I don't think you need the loop. 我认为您不需要循环。 I'm assuming your id's are primary keys and you didn't mean to repeat crank several times in your example. 我假设您的ID是主键,并且您并不是要在示例中重复几次曲柄操作。

Would something like this work? 这样的事情行吗?

Edit per Raj A's comment. 根据Raj A的评论进行编辑。 This will only update rows where one of the other fields has changed. 这只会更新其他字段之一已更改的行。 Note that this will not update rows where one is NULL and the other is not NULL. 请注意,这不会更新其中一个为NULL而另一个为非NULL的行。

MERGE INTO final T 
USING ( SELECT id, score, crank, urank FROM test ) S
   ON ( S.vid = T.id AND 
        ( S.crank != T.crank OR S.score != T.score OR S.urank != T.urank ))
 WHEN MATCHED SET crank = S.crank, score = S.score, 
      crank = S.crank, urank = S.urank 
 WHEN NOT MATCHED THEN INSERT
      [... not sure what you want to do in this case ...]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM