Странное поведение обновления
-
21-08-2019 - |
Вопрос
В части моих хранимых процедур хранилища данных у меня есть процедура, которая сравнивает старые данные проекта с данными нового проекта (старые данные находятся в таблице, новые — во временной таблице) и обновляет старые данные.
Самое странное, что если старые данные равны нулю, то оператор обновления не работает.Если я добавляю оператор is null, обновление работает нормально.Мой вопрос: почему это не работает так, как я думал?
Один из нескольких операторов обновления:
update cube.Projects
set prServiceLine=a.ServiceLine
from @projects1 a
inner join cube.Projects
on a.WPROJ_ID=cube.Projects.pk_prID
where prServiceLine<>a.ServiceLine
Решение
where prServiceLine<>a.ServiceLine
если prServiceLine имеет значение null или a.ServiceLine имеет значение null, то результатом условия является значение null, а не логическое значение.
проверьте это:
declare @x int, @y int
if @x<>@y print 'works'
if @x=@y print 'works!'
set @x=1
if @x<>@y print 'not yet'
if @x=@y print 'not yet!'
set @y=2
if @x<>@y print 'maybe'
if @x=@y print 'maybe!'
выход:
maybe
вы никогда не увидите 'работы', 'работы!', 'еще нет' или 'еще нет!' получить выход.Только «Может быть» («может быть!», если бы они оба были равны).
вы не можете проверять нулевые значения с помощью !=, = или <>, вам нужно использовать ISNULL(), COALESCE, IS NOT NULL или IS NULL в вашем WHERE, если одно из проверяемых значений может быть NULL.
Другие советы
Статья в Википедии о SQL-нули на самом деле действительно хорош - он объясняет, что поведение часто не соответствует ожиданиям, во многих случаях возвращая «неизвестно», а не «истина» или «ложь».
Если вы введете нули, возникнет немало ошибок...
Возможно, вам нужно ЛЕВОЕ СОЕДИНЕНИЕ (или ПРАВОЕ, в зависимости от данных), а не ВНУТРЕННЕЕ СОЕДИНЕНИЕ.