|
|
|
Условие Where - у меня уже крыша едет, помогите!
|
|||
|---|---|---|---|
|
#18+
В табличке есть поле Int, которое может иметь значение Null Нужно выбрать из таблички по условию, которое передается в переменной, которая может быть тоже NULL Пишу следующий код: Select * From tbl_GoodsNames Where (ParentID = @ParentID) Or (ParentID Is Null And @ParentID Is Null) Все прекрасно! Теперь надобно написать условие, чтобы вернулись все записи, которые не попали в первое условие. Пишу код (все тоже самое, что и перед этим, только ставлю Not на все выражение): Select * From tbl_GoodsNames Where NOT((ParentID = @ParentID) Or (ParentID Is Null And @ParentID Is Null)) Все работает на ура, пока в переменной @ParentID не предадут NULL... - в этом случае первый Select отрабатывает правильно, а второй возвращает пустой набор. Я уже попинал по-всякому, и сложилось такое впечатление, что скобка (ParentID = @ParentID) в случае @ParentID = NULL всегда возвращает True, хотя этого не дожно быть!!! Стоит MSSQL2000 Sp2 Помогите, кто может! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2002, 21:13:58 |
|
||
|
Условие Where - у меня уже крыша едет, помогите!
|
|||
|---|---|---|---|
|
#18+
Ха! Последнее условие переписал вот так и все заработало! Код: plaintext 1. 2. 3. 4. 5. 6. Народ, чего я не понимаю!? Ведь условия по сути своей аналогичные! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2002, 21:24:47 |
|
||
|
Условие Where - у меня уже крыша едет, помогите!
|
|||
|---|---|---|---|
|
#18+
привет собственно ко второму замечанию, насколько я помню всегда было так Код: plaintext 1. насчет (ParentID = @ParentID), в случае @ParentID = NULL, думаю проще проверить взяв Код: plaintext 1. где @ParentID is NULL ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2002, 23:44:03 |
|
||
|
Условие Where - у меня уже крыша едет, помогите!
|
|||
|---|---|---|---|
|
#18+
Может так? Код: plaintext 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.06.2002, 04:00:52 |
|
||
|
Условие Where - у меня уже крыша едет, помогите!
|
|||
|---|---|---|---|
|
#18+
Все дело тут в том, что сравнение с NULL - это особенная логика. Сравнение любого значения с NULL всегда будет давать NULL. даже NULL c NULL будет NULL, а не true или false. Вернее он будет преобразовываться в false при любой операции. Я бы переписал выражения таким образом: Код: plaintext 1. 2. 3. 4. 5. а второе как: Код: plaintext 1. 2. 3. 4. 5. -- Слон ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.06.2002, 04:29:19 |
|
||
|
Условие Where - у меня уже крыша едет, помогите!
|
|||
|---|---|---|---|
|
#18+
Прошу прощение. Второе надо было переписывать так: Код: plaintext 1. 2. 3. 4. 5. -- Слон ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.06.2002, 04:33:44 |
|
||
|
Условие Where - у меня уже крыша едет, помогите!
|
|||
|---|---|---|---|
|
#18+
Я поступаю в таких случаях примерно так: IF @ParentID IS NULL SELECT * FROM table1 WHERE ParentID IS NULL ELSE SELECT * FROM table1 WHERE ParentID = @ParentID Если не проще, то по крайней мере наглядно. Если такое ветвление не подходит, пробуй функцию ISNULL, подменяющее значение своего аргумента, имеющего значение NULL, на некоторую, устраивающую разработчика величину - например, на 0: SELECT * FROM table1 WHERE ISNULL(ParentID,0) = ISNULL(@ParentID,0) Что-то я посмотрел следующие за первым постинги и не совсем понял, какую задачу тебе решить-то требуется? Попытаюсь проговорить, что я увидел: "Найти записи, соответствующие заданному значению, при этом значение NULL рассматривается как самостоятельное значение". - это по первому постингу, на его я и ответил примером. А вот по второму... "Найти записи, несовпадающие с заданным значением, либо одновременно с заданным значением имеющих значение NULL". Что ж, модифицируем мой пример (условие WHERE в ветке ELSE): IF @ParentID IS NULL SELECT * FROM table1 WHERE ParentID IS NULL ELSE SELECT * FROM table1 WHERE ParentID != @ParentID ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.06.2002, 06:05:00 |
|
||
|
Условие Where - у меня уже крыша едет, помогите!
|
|||
|---|---|---|---|
|
#18+
Проблема с ISNULL в WHERE clause только лишь та, что при этом SQL server будет преобразовывать все значения в указанном столбце, а потом уже сравнивать. В том числе это не позволяет использование индекса на полную катушку. Что касается примера второго запроса (SELECT * FROM table1 WHERE ParentID != @ParentID), то опять же из-за того, что логика сравнения с NULL была попросту игнорирована, то результат вернет все значения, кроме тех, где ParentID IS NULL, опять же потому, что при любом сравнении значения NULL из столбца ParentID с NOT NULL значением @ParentID в результате будет NULL (aka UNKNOWN), которое будет преобразовано в данном случае в FALSE -- Слон ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.06.2002, 06:34:07 |
|
||
|
Условие Where - у меня уже крыша едет, помогите!
|
|||
|---|---|---|---|
|
#18+
Сравнение любого значения с NULL всегда будет давать NULL. даже NULL c NULL будет NULL, а не true или false. Вернее он будет преобразовываться в false при любой операции. Именно этим правилом я и пользовался, когда писал: Код: plaintext если разобрать по-косточкам, то первая скобка при @ParentID = NULL всегда дает False, вторая дает True только если ParentID Is Null. Отсюда следует, что должны выбраться все записи, у которых @ParentID <> NULL, что мне и надо было. Но данное условие вообще никогда не возвращает ни одной записи!!! Что меня и смущает. Конечно, вот так все работает(Спасибо Слону): Код: plaintext 1. 2. 3. я в конце концов и сам пришел к этому, но это метод тыка, который меня уже давно не устраивает. Я так и не понял ПОЧЕМУ изначальный вариант не работает :-(( Что-то я посмотрел следующие за первым постинги и не совсем понял, какую задачу тебе решить-то требуется? мне нужно сформировать два набора, сформированных по определенному условию из исходного набора, эти два набора должны взаимно дополнять друг друга, тоесть в сумме они должны составить исходный набор. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.06.2002, 11:23:46 |
|
||
|
Условие Where - у меня уже крыша едет, помогите!
|
|||
|---|---|---|---|
|
#18+
>Именно этим правилом я и пользовался, когда писал: >Where NOT((ParentID = @ParentID) Or (ParentID Is Null And @ParentID Is Null)) >если разобрать по-косточкам, то первая скобка при @ParentID = NULL всегда дает False Первое выражение при @ParentID равное NULL будет не false, а NULL. Соответственно NULL Or (ParentID Is Null And @ParentID Is Null) тоже будет NULL. С помощью SET ANSI_NULLS ON OFF можно включить вычисление NULL-ов при операциях сравнения как false. Тогда ваш первоначальный запрос будет работать правильно ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.06.2002, 11:38:20 |
|
||
|
Условие Where - у меня уже крыша едет, помогите!
|
|||
|---|---|---|---|
|
#18+
С "постановкой задачи" все стало ясно. Хорошо, что найден вариант, устраивающий разработчика. Насчет "ПОЧЕМУ изначальный вариант не работает" - да потому, что если хотя бы одно значение в выражении обращается в NULL, все выражение без дополнительного анализа обращается в NULL, а не какая-то его часть в false. И все же я бы порекомендовал вариант с IF...ELSE как наглядный (отдельно обрабатывается ситуация, когда @ParentID NULL, и когда нет). Представьте, что с этим будет разбираться кто-то другой. С уважением, Dominic ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.06.2002, 11:45:54 |
|
||
|
Условие Where - у меня уже крыша едет, помогите!
|
|||
|---|---|---|---|
|
#18+
Первое выражение при @ParentID равное NULL будет не false, а NULL. Соответственно NULL Or (ParentID Is Null And @ParentID Is Null) тоже будет NULL. и соответственно Not NULL дает тоже NULL.... и все сыплется мелким прахом... Ну теперечи вроде уяснил! Спасибо всем!!! И все же я бы порекомендовал вариант с IF...ELSE как наглядный (отдельно обрабатывается ситуация, когда @ParentID NULL, и когда нет). Представьте, что с этим будет разбираться кто-то другой. совет дельный, спасибо, но в данном случае хотелось докопаться до того что-же я все-таки не понимаю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.06.2002, 16:26:17 |
|
||
|
Условие Where - у меня уже крыша едет, помогите!
|
|||
|---|---|---|---|
|
#18+
>Первое выражение при @ParentID равное NULL будет не >false, а NULL. Соответственно NULL Or (ParentID Is Null And >@ParentID Is Null) тоже будет NULL. Не всегда. Если ParentID is null, то вторая скобка TRUE. А NULL OR TRUE, как известно, равно TRUE... (А NULL AND FALSE = FALSE) Вообще, имхо, стоит посмотреть таблицу значений фунций в трехзначной логике и все станет ясно.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.06.2002, 10:45:56 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=32032980&tid=1822224]: |
0ms |
get settings: |
9ms |
get forum list: |
22ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
56ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
70ms |
get tp. blocked users: |
2ms |
| others: | 254ms |
| total: | 434ms |

| 0 / 0 |
