如何在Oracle中组合多个更新语句?

时间:2012-02-06 18:32:42

标签: sql oracle

我一直致力于提高存储过程的性能,并且由于必须运行四个非常相似的更新而导致速度大幅下降。

我在MySql中找到了类似问题的相关信息,这些信息很有帮助,但我无法实现我所学到的知识,也许Oracle的运作方式不同。

我尝试过的事情之一;通过合并批量插入,创建辅助temp_table并且根本没有临时表,但是没有任何改进。

成为Oracle的新手,我完全有可能以错误的方式解决问题。

任何建议或答案或对答案的指示都会大大减少,因为我已经没有想法,现在除了蛮力和无知之外什么都没有。

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
        );

4 个答案:

答案 0 :(得分:2)

您要做的主要是一个数据透视操作 - 将多行值转换为单行中的多个列值。下面是在Oracle中使用常用技术进行数据透视查询的一种方法(未经测试但我认为它应该按原样运行)。从版本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
    );

答案 1 :(得分:1)

也许您可以尝试探索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);

答案 2 :(得分:0)

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
        )
,       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
        )
,       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
        );

答案 3 :(得分:0)

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