Обновление через подзапрос, что если подзапрос не возвращает строк? - PullRequest
5 голосов
/ 02 декабря 2009

Я использую подзапрос в ОБНОВЛЕНИИ:

UPDATE tableA 
SET x,y,z = ( (SELECT x, y, z 
               FROM tableB b
               WHERE tableA.id = b.id
                 AND (tableA.x != b.x
                      OR tableA.y != b.y
                      OR tableA.z != b.z))) );

Мой вопрос: что произойдет, если подзапрос не вернет строки? Будет ли обновление с нулями?

Во-вторых, есть ли лучший способ написать это. Я в основном обновляю три поля в таблице A из таблицы B, но обновление должно происходить только в том случае, если любое из этих трех полей отличается.

Ответы [ 2 ]

6 голосов
/ 02 декабря 2009

что произойдет, если подзапрос вернется нет строк? Будет ли это делать обновление с обнуляет?

Да - вы можете проверить это как:

update YourTable
set col1 = (select 1 where 1=0)

Это заполнит col1 пустыми значениями. Если подзапрос возвращает несколько строк, например:

update YourTable
set col1 = (select 1 union select 2)

База данных выдаст ошибку.

Во-вторых, есть ли лучший способ напиши это. Я в основном обновляю три поля в таблице A из таблицы B, но обновление должно произойти только если любое из трех полей отличается.

Интуитивно я бы не стал беспокоиться о производительности. Если вы действительно хотите избежать обновления, вы можете написать его следующим образом:

UPDATE a
SET x = b.x, y = b.y, z = b.z
FROM tableA a, tableB b 
WHERE a.id = b.id AND (a.x <> b.x OR a.y <> b.y OR a.z <> b.z)

Предложение WHERE запрещает обновления с NULL.

0 голосов
/ 02 декабря 2009

На Inforix я использовал вариант решения Andomar:

UPDATE a
SET x,y,z = ( (SELECT x, y, z 
               FROM tableB b
               WHERE tableA.id = b.id) )
WHERE tableA.id IN (SELECT fromTable.id
                    FROM tableA toTable, tableB fromTable
                    WHERE toTable.id = fromTable.id
                      AND ((toTable.x <> fromTable.x) 
                           OR (toTable.y <> fromTable.y)
                           OR (toTable.z <> fromTable.z))
...