Почему NULL-поля называются равными? - PullRequest
1 голос
/ 11 октября 2011

Я пишу триггеры для обнаружения изменений в полях в базе данных, и мне кажется, что я должен делать действительно неприятные вещи, такие как

(SELECT SalesPrice FROM __old) <> (SELECT SalesPrice FROM __new)
or ((SELECT SalesPrice FROM __old) IS NULL and (SELECT SalesPrice FROM __new) IS NOT NULL)
or ((SELECT SalesPrice FROM __old) IS NOT NULL and (SELECT SalesPrice FROM __new) IS NULL)

, а не просто

(SELECT SalesPrice FROM __old) <> (SELECT SalesPrice FROM __new)

, чтобыточно определить, изменилось ли поле.

Я что-то упустил или Advantage фактически заявляет, что NULL == любое значение?Есть ли веская причина для такого поведения?Это странная вещь в определении SQL?Есть ли более лаконичный способ, который не делает 3 проверки вместо одной?

Ответы [ 2 ]

3 голосов
/ 11 октября 2011

Это, к сожалению, то, как SQL работает со значениями NULL.NULL не равно чему-либо, это НЕИЗВЕСТНО.Например, somevalue == NULL -> unknown somevalue <> NULL -> unknown

В результате он никогда не пройдет «истинную» проверку Null Values ​​- Wikipedia

Есть несколько вариантов: A) Не разрешать нулевые значения (я рекомендую комбинировать это со значением по умолчанию) B) Используйте IFNULL, чтобы установить в поле какое-либо значение, например

(SELECT IFNULL(SalesPrice, -9999) FROM __OLD) <> (SELECT IFNULL(SalesPrice, -9999) FROM __NEW)

Но я нене знаю, обязательно ли мне это нравится, поскольку должно быть выбрано значение, которое не будет действительным.

1 голос
/ 11 октября 2011

В SQL NULL не сравнивается ни с чем, кроме выражения IS [NOT] NULL.Если я правильно понимаю ваш вопрос, проблема в том, что NULL должен быть равен NULL.В этом случае проверку можно упростить до:

( SELECT CASE WHEN n.SalesPrice IS NULL and o.SalePrice IS NULL THEN TRUE
         ELSE n.SalesPrice = o.SalesPrice END
  FROM __old o, __new n )
...