Обновление через подзапрос, что, если подзапрос не возвращает строк?

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

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, но обновление должно происходить только в том случае, если какое-либо из трех полей отличается.


person rouble    schedule 01.12.2009    source источник
comment
Должно ли это обновление основываться на параметре соединения с таблицей B или это декартово обновление?   -  person adamcodes    schedule 02.12.2009
comment
the update should only happen if any of the three fields are different. звучит как предложение where для меня...   -  person OMG Ponies    schedule 02.12.2009


Ответы (2)


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

Да, вы можете проверить это следующим образом:

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

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

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.

person Andomar    schedule 01.12.2009
comment
Это выглядит блестяще, за исключением того, что я забыл упомянуть, что использую informix IDS 11.5, и я не верю, что informix поддерживает FROM в UPDATE или присоединяется к UPDATE. - person rouble; 02.12.2009
comment
@prmatta: Informix действительно поддерживает FROM в UPDATE, я думаю; Я удалил ВНУТРЕННЕЕ СОЕДИНЕНИЕ. - person Andomar; 02.12.2009
comment
@ Андомар, я так не думаю, по крайней мере, не мой. В документации сказано, что это так, но я продолжал получать синтаксическую ошибку. Я обновил sql до чего-то без froms и соединений и вставил его в качестве ответа, дайте мне знать, если он вам подходит. - person rouble; 02.12.2009
comment
@prmatta: Ваше решение выглядит как хороший обход ограничения Informix! - person Andomar; 02.12.2009

На informix, который я использовал, вариант решения 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))
person Community    schedule 02.12.2009