Оптимизируйте этот оператор UPDATE, чтобы не использовать курсоры - PullRequest
1 голос
/ 07 мая 2011
FOR v2 AS
    c2 CURSOR FOR
        SELECT he.MyPrimary, he.SomeCode, he.SomeName, pe.MyPrimary
        FROM SomeTable he
            INNER JOIN AnotherTable pe
                ON (he.ColOne = pe.FooOne
                    AND he.ColTwo = pe.ColTwo
                    AND he.ColThree = pe.FooOne
                    AND he.SomeCode = pe.SomeCode)
        WHERE he.relevancy = 1 AND he.ColThree = '2011-01-05' AND he.ColFive = 9
DO
    UPDATE AnotherTable SET match = he.MyPrimary, FooTwo = he.SomeCode, SomeName = he.SomeName WHERE MyPrimary = pe.MyPrimary;  

END FOR;

У меня есть код выше, и я пытаюсь сделать это без использования курсоров, но я не уверен, как сделать оператор UPDATE с INNER JOIN.По сути, я хотел бы объединить две таблицы SomeTable и AnotherTable, затем, основываясь на значениях некоторых столбцов из SomeTable, скопировать значение в аналогичный столбец в AnotherTable.Я использую DB2.

РЕДАКТИРОВАТЬ: Я просто смотрел на это: INNER JOIN в UPDATE sql для DB2

Будет ли это иметь смыслвместо этого сделать что-то вроде этого:

UPDATE
  SomeTable pe
SET
  match = (SELECT he.MyPrimary FROM SomeTable he WHERE he.ColOne = pe.FooOne
                            AND he.ColTwo = pe.ColTwo
                            AND he.ColThree = pe.FooOne
                            AND he.SomeCode = pe.SomeCode ),

  FooTwo = (SELECT he.SomeCode FROM SomeTable he WHERE he.ColOne = pe.FooOne
                            AND he.ColTwo = pe.ColTwo
                            AND he.ColThree = pe.FooOne
                            AND he.SomeCode = pe.SomeCode )
WHERE
  he.relevancy = 1 AND he.ColThree = '2011-01-05' AND he.ColFive = 9

Ответы [ 2 ]

1 голос
/ 07 мая 2011

Как упоминалось в вашей ссылке, стандарт ISO / ANSI не допускает объединения в операторе Update за пределами его использования в подзапросе.Таким образом, вы должны сделать несколько операторов Update или подзапрос для каждого столбца.

Update AnotherTable 
Set match = (
                Select he.MyPrimary
                From SomeTable he
                Where he.ColOne = AnotherTable.FooOne
                    And he.ColTwo = AnotherTable.ColTwo
                    And he.ColThree = AnotherTable.FooOne
                    And he.SomeCode = AnotherTable.SomeCode
                    And he.relevancy = 1 
                    And he.ColThree = '2011-01-05' 
                    And he.ColFive = 9
                )
    , FooTwo =  (
                Select he.SomeCode
                From SomeTable he
                Where he.ColOne = AnotherTable.FooOne
                    And he.ColTwo = AnotherTable.ColTwo
                    And he.ColThree = AnotherTable.FooOne
                    And he.SomeCode = AnotherTable.SomeCode
                    And he.relevancy = 1 
                    And he.ColThree = '2011-01-05' 
                    And he.ColFive = 9
                )
    , SomeName =    (
                    Select he.SomeName
                    From SomeTable he
                    Where he.ColOne = AnotherTable.FooOne
                        And he.ColTwo = AnotherTable.ColTwo
                        And he.ColThree = AnotherTable.FooOne
                        And he.SomeCode = AnotherTable.SomeCode
                        And he.relevancy = 1 
                        And he.ColThree = '2011-01-05' 
                        And he.ColFive = 9
                    )
Where Exists    (
                Select 1
                From SomeTable he
                Where he.ColOne = AnotherTable.FooOne
                    And he.ColTwo = AnotherTable.ColTwo
                    And he.ColThree = AnotherTable.FooOne
                    And he.SomeCode = AnotherTable.SomeCode
                    And he.relevancy = 1 
                    And he.ColThree = '2011-01-05' 
                    And he.ColFive = 9
                )
0 голосов
/ 24 июня 2011

Есть немного лучший способ сделать это;

UPDATE SomeTable pe SET (match, FooTwo, SomeName) = (SELECT he.MyPrimary, he.SomeCode, he.SomeName
                                                     FROM AnotherTable he 
                                                     WHERE he.ColOne = pe.FooOne
                                                     AND he.ColTwo = pe.ColTwo
                                                     AND he.ColThree = pe.FooOne
                                                     AND he.SomeCode = pe.SomeCode)
WHERE he.relevancy = 1 
AND he.ColThree = '2011-01-05' 
AND he.ColFive = 9

Это очень хорошо работает в версии DB2 для iSeries.
Если вам нужно беспокоиться о NULL строках, не забывайте свое предложение о существовании:

AND EXISTS (SELECT '1'
            FROM AnotherTable he
            WHERE he.ColOne = pe.FooOne
            AND he.ColTwo = pe.ColTwo
            AND he.ColThree = pr.FooOne
            AND he.SomeCode = pe.SomeCode)  

Добавьте это после существующего предложения WHERE в основном операторе UPDATE.

...