Sql 如何在Oracle中组合多个update语句?

Sql 如何在Oracle中组合多个update语句?,sql,oracle,Sql,Oracle,我一直在努力提高存储过程的性能,但由于必须运行四个非常类似的更新,因此速度大大减慢 我在MySql中找到了类似问题的信息,这很有帮助,但我无法实现我学到的东西,也许Oracle的操作方式不同 我尝试过的事情包括:;通过merge进行批插入,创建一个辅助temp_表,并且不使用任何temp表,但没有任何改进 作为甲骨文的新手,我完全有可能只是走错了方向 任何建议、答案或对答案的指导都将受到极大的赞赏,因为我已经没有想法了,现在除了野蛮的暴力和无知,什么都没有了 UPDATE TEMP_TABLE

我一直在努力提高存储过程的性能,但由于必须运行四个非常类似的更新,因此速度大大减慢

我在MySql中找到了类似问题的信息,这很有帮助,但我无法实现我学到的东西,也许Oracle的操作方式不同

我尝试过的事情包括:;通过merge进行批插入,创建一个辅助temp_表,并且不使用任何temp表,但没有任何改进

作为甲骨文的新手,我完全有可能只是走错了方向

任何建议、答案或对答案的指导都将受到极大的赞赏,因为我已经没有想法了,现在除了野蛮的暴力和无知,什么都没有了

UPDATE TEMP_TABLE TI SET T.ItemPrice_One =
        (
         SELECT ItemPrice
         FROM   Temp.View_Items V
         WHERE  V.Item_Name                    =          'Item_Name_One'
         AND    V.ID                           =          T.ID
         AND    V.Date                         =          T.Date
        );

UPDATE TEMP_TABLE TI SET T.ItemPrice_Two =
        (
         SELECT ItemPrice
         FROM   Temp.View_Items V
         WHERE  V.Item_Name                    =          'Item_Name_Two'
         AND    V.ID                           =          T.ID
         AND    V.Date                         =          T.Date
        );

UPDATE TEMP_TABLE TI SET T.ItemPrice_Three =
        (
         SELECT ItemPrice
         FROM   Temp.View_Items V
         WHERE  V.Item_Name                    =          'Item_Name_Three'
         AND    V.ID                           =          T.ID
         AND    V.Date                         =          T.Date
        );

也许您可以尝试探索MERGE语句的用法。这样可以避免对视图表进行三次扫描。我没有一个实例可供实验,但这里是对这个想法的粗略猜测:

MERGE INTO TEMP_TABLE t
   USING (SELECT Item_name, ItemPrice
            FROM Temp.View_Items V
            WHERE V.Item_Name IN ('Item_Name_One', 'Item_Name_Two', 'Item_Name_Three')
              AND V.ID = T.ID
              AND V.Date = T.Date) s
   ON (...join condition here... t.item_name = v.item_name??)
   WHEN MATCHED THEN
     UPDATE SET t.ItemPrice_One = DECODE(s.ItemPrice, 'Item_Name_One', v.ItemPrice, t.ItemPrice_One)
               ,t.ItemPrice_Two = DECODE(s.ItemPrice, 'Item_Name_Two', v.ItemPrice, t.ItemPrice_Two)
               ,t.ItemPrice_Three = DECODE(s.ItemPrice, 'Item_Name_Three', v.ItemPrice, t.ItemPrice_Three);

您试图做的基本上是一个透视操作——在一行中将多个行值转换为多个列值。下面是一种使用Oracle中的常用技术进行pivot查询的方法(未经测试,但我认为它应该按原样工作)。在版本11g中,有一个内置的PIVOT操作,但我还没有真正研究过它——它可能是一种更直接的方法,可以满足您的需要

UPDATE TEMP_TABLE TI SET ( T.ItemPrice_One, T.ItemPrice_Two,T.ItemPrice_Three )  =
    (
     SELECT
       MAX( CASE WHEN V.Item_Name='Item_Name_One' THEN ItemPrice ELSE NULL END ) Item_Price_One,
       MAX( CASE WHEN V.Item_Name='Item_Name_Two' THEN ItemPrice ELSE NULL END ) Item_Price_Two,
       MAX( CASE WHEN V.Item_Name='Item_Name_Three' THEN ItemPrice ELSE NULL END ) Item_Price_Three
     FROM   Temp.View_Items V
     WHERE  V.ID                           =          T.ID
     AND    V.Date                         =          T.Date
    );

在这种情况下,合并是最好的选择。

您真的要为每个update语句更新TEMP_表的每一行吗?(因为你的每个更新都会这样做)。我有点困惑,你想更新的主表是什么?你可以很容易地将这三个更新组合成一个更新。这就是问题所在吗?谢谢大家快速的回答。我会尽量澄清它的目的。Temp_表通常很小,范围从2行到200行。如果id和日期与更大的视图匹配,则该行中的相应列将被更新。谢谢,就像我刚才说的我正在尝试合并一样,我将根据我在此处看到的内容进行另一次尝试。谢谢回答,此版本真的会提高性能吗?我会试一试,看看会发生什么。我试过这个,虽然它确实更干净,但我没有注意到任何明显的改善。我还是很感激你抽出时间。谢谢Hanks Dave,我今天早上试过这个,它大大提高了性能。稍后我将介绍11G pivot,我将尝试为感兴趣的任何其他人更新它。再次感谢所有花时间回复的人。
UPDATE TEMP_TABLE TI SET ( T.ItemPrice_One, T.ItemPrice_Two,T.ItemPrice_Three )  =
    (
     SELECT
       MAX( CASE WHEN V.Item_Name='Item_Name_One' THEN ItemPrice ELSE NULL END ) Item_Price_One,
       MAX( CASE WHEN V.Item_Name='Item_Name_Two' THEN ItemPrice ELSE NULL END ) Item_Price_Two,
       MAX( CASE WHEN V.Item_Name='Item_Name_Three' THEN ItemPrice ELSE NULL END ) Item_Price_Three
     FROM   Temp.View_Items V
     WHERE  V.ID                           =          T.ID
     AND    V.Date                         =          T.Date
    );