Всякий раз, когда вы используете NULL, вы действительно имеете дело с трехзначной логикой.
Ваш первый запрос возвращает результаты, поскольку предложение WHERE оценивается как:
3 = 1 or 3 = 2 or 3 = 3 or 3 = null
which is:
FALSE or FALSE or TRUE or UNKNOWN
which evaluates to
TRUE
Второй :
3 <> 1 and 3 <> 2 and 3 <> null
which evaluates to:
TRUE and TRUE and UNKNOWN
which evaluates to:
UNKNOWN
UNKNOWN не совпадает с FALSE, вы можете легко проверить его, вызвав:
select 'true' where 3 <> null
select 'true' where not (3 <> null)
Оба запроса не дадут вам результатов
Если UNKNOWN был таким же, как FALSE, то, предполагая, что первый запрос даст вам FALSE, второй должен был бы оценивать значение TRUE, поскольку он был бы таким же, как NOT (FALSE). Это не так.
В SqlServerCentral есть очень хорошая статья .
Вся проблема NULL и трехзначной логики может сначала немного сбив с толку, но для того, чтобы писать правильные запросы в TSQL
, необходимо понимать другую статью, которую я бы рекомендовал: SQL Aggregate Functions и NULL .
<глоток> Примечание редактора :
- >(…)
замена процесса , который является нестандартная функция оболочки из [1 121] [приблизительно 1 121] совместимые с POSIX оболочки: bash
, ksh
, zsh
.
- Этот ответ случайно отправляет, вывод обрабатывают вывод замены через конвейер также : echo 123 | tee >(tr 1 a) | tr 1 b
.
- Вывод от замен процесса будет непредсказуемо чередован, и, кроме zsh
, конвейер может завершиться, прежде чем команды в >(…)
делают.
В Unix (или на Mac), используйте tee
команда :
$ echo 123 | tee >(tr 1 a) >(tr 1 b) >/dev/null
b23
a23
Обычно Вы использовали бы tee
для перенаправления вывода в несколько файлов, но использующий> (...) можно перенаправить к другому процессу. Так, в целом,
$ proc1 | tee >(proc2) ... >(procN-1) >(procN) >/dev/null
сделает то, что Вы хотите.
окна Under, я не думаю, что встроенная оболочка имеет эквивалент. Microsoft Windows PowerShell имеет tee
команда все же.
Как сказанный dF, bash
позволяет использовать >(…)
конструкция, выполняющая команду вместо имени файла. (Существует также эти <(…)
, конструкция для замены произвела из другой команды вместо имени файла, но это не важно теперь, я упоминаю его только для полноты).
, Если у Вас нет удара или работы системы с более старой версией удара, можно сделать вручную, что удар делает путем использования файлов FIFO.
универсальный способ достигнуть, что Вы хотите:
subprocesses="a b c d" mypid=$ for i in $subprocesses # this way we are compatible with all sh-derived shells do mkfifo /tmp/pipe.$mypid.$i done
for i in $subprocesses do tr 1 $i </tmp/pipe.$mypid.$i & # background! done
proc1 | tee $(for i in $subprocesses; do echo /tmp/pipe.$mypid.$i; done)
for i in $subprocesses; do rm /tmp/pipe.$mypid.$i; done
ПРИМЕЧАНИЕ: по причинам совместимости я сделал бы $(…)
с одинарными левыми кавычками, но я не мог сделать этого, пишущий этот ответ (одинарная левая кавычка используется в ТАК). Обычно, эти $(…)
является достаточно взрослым для работы даже в старых версиях ksh, но если он не делает, включите …
часть в одинарных левых кавычках.
С тех пор @dF: упомянутый, что PowerShell имеет мишень, я думал, что покажу способ сделать это в PowerShell.
PS > "123" | % {
$_.Replace( "1", "a"),
$_.Replace( "2", "b" )
}
a23
1b3
Обратите внимание, что каждый объект, выходящий из первой команды, обрабатывается, прежде чем следующий объект создается. Это может позволить масштабироваться к очень большим исходным данным.