2015-05-29 2 views
7

Я понимаю, что SQL использует три значения логики, но мне трудно понять, как использовать это на практике, особенно почему TRUE || NULL = True и FALSE && NULL = False вместо оценки null.Пример трехзначной логики в SQL Server

Вот три значных таблицы истинности, которые относятся к SQL Server:

Tri truth tables

Я нашел пару объяснений трех трехзначной логики в Интернете, но я не могу найти реальные примеры кода этого в использовании. Может ли кто-нибудь показать мне пример кода с использованием трехзначной логики, чтобы помочь мне понять это немного лучше?

+2

В этой статье есть одна ссылка, показывающая истину и неизвестность, оценивающие неизвестность. (эти ячейки http://i.stack.imgur.com/Yd7zq.png) –

+1

Ложно, а что-то ложно. Нет необходимости рассматривать последующие условия. Правда или что-то в этом роде. (NB: связанная статья имеет ошибку в таблицах истинности для false, как указано в комментариях Hugo Kornelis) –

+1

'IF 1 = 2 AND NULL = 1 PRINT 'TRUE' ELSE PRINT 'FALSE'' –

ответ

4

Пример TRUE || NULL = True будет

declare @x as int = null; 
if 1=1 or @x/1=1 
    print 'true' 

Пример FALSE && NULL = False будет

declare @x as int = null; 
if not(1=2 and @x/1=1) 
    print 'false' 
2

True && NULL не является ни истинным, ни ложным. Это всего лишь NULL.

Независимо от того, будет ли оно оцениваться как True, False или Error в булевом выражении, зависит от того, что происходит в вашей системе, когда вы оцениваете NULL как логическое. Sql Server сделает все возможное, чтобы избежать выбора, но при принуждении вы почти никогда не увидите положительного (истинного) результата.

0

Чтобы использовать переменную с нулевым значением, вам просто нужно проверить условия NULL (используя IS NULL) перед проверкой значения.

например. IF @a IS NOT NULL AND @a = 1

2

Вообще говоря, с точки зрения пользователя вы не хотите, чтобы булевское выражение оценивалось в NULL.

Написание SQL обычно включает в себя запись запросов в , явно избегая Значения NULL в булевых выражениях. IMX, разработчики будут рассматривать использование трехзначной логики намеренно считаться злоупотреблением трехзначной логикой. Правильно написанный запрос должен обрабатывать NULL и понимать их. Вы не пишете их таким образом, чтобы они работали правильно, когда что-то было NULL. Обычно это включает COALESCE() или IS NULL или IS NOT NULL где-то.

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

Например, допустим, что я работаю над таблицей учеников. В таблице указаны поля First, Middle и Last name. Я хочу знать список студентов, у которых нет среднего имени. Теперь некоторые приложения будут хранить пустую строку '', а некоторые приложения будут хранить значение NULL, а некоторые приложения могут выполнять и (и некоторые RDBMS, такие как Oracle, обрабатывают пустые строки как NULL). Если вы не были уверены, вы могли бы написать:

SELECT * 
FROM Student 
WHERE MiddleName = '' 
    OR MiddleName IS NULL; 

Другой общий сценарий, когда вы OUTER присоединения к другой таблице. Допустим, вы сравниваете зарплату учителей. У вас есть таблица для проверок и таблица для CheckDetail. Вы хотите знать, сколько учителей платят за пособия. Ваш отчет должен перечислить всех учителей, даже если они подрядчиков, которые не платят за выгоды, потому что они не получают какой-либо:

SELECT Check.Employee_Id, 
    SUM(CheckDetail.Amount) AS BenefitsDeductions 
FROM Check 
LEFT JOIN CheckDetail 
    ON Check.Id = CheckDetail.CheckId 
    AND CheckDetail.LineItemType = 'Benefits' 
GROUP BY Check.Employee_Id; 

Вы запускаете отчет, и вы заметите, что ваши учителя подрядные показать NULL for BenefitsDeductions. К сожалению.Вы должны убедиться, что это отображается как ноль:

SELECT Check.Employee_Id, 
    COALESCE(SUM(CheckDetail.Amount),0) AS BenefitsDeductions 
FROM Check 
LEFT JOIN CheckDetail 
    ON Check.Id = CheckDetail.CheckId 
    AND CheckDetail.LineItemType = 'Benefits' 
GROUP BY Check.Employee_Id; 

Итак, вы пытаетесь это сделать, и оно работает. Нет значений NULL! Но ... через несколько дней ваши пользователи сообщают, что преподаватели, которых раньше были подрядчиками, показываются с 0, даже если они платят за пособия сейчас. Вы должны COALESCE перед SUM, чтобы эти суммы:

SELECT Check.Employee_Id, 
    SUM(COALESCE(CheckDetail.Amount,0)) AS BenefitsDeductions 
FROM Check 
LEFT JOIN CheckDetail 
    ON Check.Id = CheckDetail.CheckId 
    AND CheckDetail.LineItemType = 'Benefits' 
GROUP BY Check.Employee_Id; 

Обнаружение этих видов случаев угловых и исключений, что написание SQL все о.

2

Пример кода на user4955163 является отличной визуализацией этого, но я просто хотел сделать шаг назад для ответа на первый сегмент вопроса:

... особенно почему ИСТИНА || NULL = True и ЛОЖЬ & & NULL = False вместо оценки обнулить ...

TRUE || NULL = True 

Это происходит потому, что оператор or будет короткое замыкание, если один из операндов уже известно, true. Независимо от того, что второй операнд (даже если неизвестный, т. Е. «NULL»), он не сделает выражение false, так как мы уже знаем, что другой операнд равен true. or нужен только один операнд, который должен быть true, для оценки true.

FALSE && NULL = False 

Это потому, что оператор будет and короткого замыкания, если один из операндов уже известно, что false. Независимо от того, какой второй операнд (даже если он неизвестен, т. Е. «NULL»), он не сделает выражение true, так как мы уже знаем, что другой операнд false. and нужны оба операнда: true для оценки true.

Смежные вопросы