Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2008.08.24;
Скачать: [xml.tar.bz2];

Вниз

Отождествление пустой строки и NULL   Найти похожие ветки 

 
pasha_golub ©   (2008-07-01 15:07) [0]

Помню была такая тема. Почти что "святая война". Но тут столкнулся с проблемой, что пользователь упорно мне доказывает целесообразность данного момента в моих компонентах-наследниках TDataset.

Я стою на своем, что это разные сущности абсолютно. А он предлагает компромисс - ввести флаг и по желанию программиста, чтобы работало то так, а то эдак.

Самое плохое, что привел примеры програм, которые так и поступают. Например, pgAdminIII, DOA для Oracle, IBX для Interbase/Firebird...

Каковы мысли? Я понимаю, что это супротив стандарта. Но если рынок требует, может стоит?


 
Ega23 ©   (2008-07-01 15:10) [1]

Если сильно настаивает и готов за это дело заплатить - то пуркуа бы и не па?


 
pasha_golub ©   (2008-07-01 15:12) [2]


> Ega23 ©   (01.07.08 15:10) [1]

А совесть куда деть? :)) Меня от одной мысли коробит. У меня ж отец военный. Не положено по уставу.


 
McSimm ©   (2008-07-01 15:13) [3]


> А совесть куда деть?

отдельной строкой в смете :)


 
pasha_golub ©   (2008-07-01 15:18) [4]

Тут ведь еще какой момент NULL <> NULL, а "" = "". Ну и прочие вкусности. В том же запросе WHERE .. IS NULL супротив WHERE ... = ""

Опять же, если это так востребовано почему это не реализовано в серверной логике? Даже параметра такого нету.


 
Игорь Шевченко ©   (2008-07-01 15:19) [5]


> Отождествление пустой строки и NULL


У меня к тебе вопрос - а как ты их визуально различишь ?


 
Ega23 ©   (2008-07-01 15:20) [6]

Подожди. Речь о том, чтобы НА СЕРВЕРЕ подменить Null на ""? Или всё-таки на клиенте?


 
Правильный-Вася   (2008-07-01 15:29) [7]


>  а как ты их визуально различишь ?

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


 
Ega23 ©   (2008-07-01 15:32) [8]

Я не вижу ничего дурного в том, что если у тебя ftString - то при Null-значении показывать "", если ftInteger - то 0 и т.п.
На крайняк - ввести макроподстановку в свойство филда, типа при Null-значении писать "" или "Пусто" или "NULL".
Но - только для отображения.


 
Игорь Шевченко ©   (2008-07-01 15:34) [9]

Мало того, что я не понимаю, каков фактический смысл отличия "" от NULL с точки зрения предметной области, я еще и не понимаю, как их визуально отличать. Например, как отличать 0 от NULL я знаю, а вот со строками - тупик.


 
Плохиш ©   (2008-07-01 15:34) [10]


> pasha_golub ©   (01.07.08 15:07)  
> Помню была такая тема. Почти что "святая война". Но тут
> столкнулся с проблемой, что пользователь упорно мне доказывает
> целесообразность данного момента в моих компонентах-наследниках
> TDataset.

Хм, а свойству asString как-то пофигу, что там null или строка нулевой длины...


 
pasha_golub ©   (2008-07-01 15:39) [11]


> Игорь Шевченко ©   (01.07.08 15:34) [9]


> Мало того, что я не понимаю, каков фактический смысл отличия
> "" от NULL с точки зрения предметной области, я еще и не
> понимаю, как их визуально отличать.

Визуальность - дело последнее. Например, пустая строка это нейтральный элемент относительно операции конкатенации, как и 0 в случае сложения. Однако, если сделать "string" || NULL, то получаем NULL.

Визуально, конечно, да. Пользователю один черт что пустое место, что надпись NULL


 
Ega23 ©   (2008-07-01 15:40) [12]


> Хм, а свойству asString как-то пофигу, что там null или
> строка нулевой длины...
>


И чё? TField.GetAsString : string; virtual;
Как хошь перекрыть можно.


 
pasha_golub ©   (2008-07-01 15:41) [13]


> Я не вижу ничего дурного в том, что если у тебя ftString
> - то при Null-значении показывать "", если ftInteger - то
> 0 и т.п.

Со строками еще куда ни шло, а вот с числами... Поле Зарплата, например, то ли NULL - неизвестно или не начислено, или 0. :-)


 
Игорь Шевченко ©   (2008-07-01 15:42) [14]

pasha_golub ©   (01.07.08 15:39) [11]


> Визуальность - дело последнее. Например, пустая строка это
> нейтральный элемент относительно операции конкатенации,
> как и 0 в случае сложения. Однако, если сделать "string"
> || NULL, то получаем NULL.


я@ora10> select "Foo"||NULL from dual;

"FO
---
Foo

я@ora10>

Мне не верить своим глазам ?


 
Игорь Шевченко ©   (2008-07-01 15:43) [15]


> Поле Зарплата, например, то ли NULL - неизвестно или не
> начислено,


не определено.


 
Ega23 ©   (2008-07-01 15:44) [16]

Павель, вот никогда бы полю, отвечающему за деньги NULL бы не поставил. Ибо - Sum чему равно будет?  :)


 
oldman ©   (2008-07-01 15:46) [17]


> пользователь упорно мне доказывает целесообразность данного
> момента


КЛИЕНТ ВСЕГДА ПРАВ!!!


 
McSimm ©   (2008-07-01 15:47) [18]


> Ибо - Sum чему равно будет?

Все правильно - пока все слагаемы не известны, суммировать опасно.
А то получится 10 конфет каждому по 8 :)


 
Ega23 ©   (2008-07-01 15:47) [19]


> Мне не верить своим глазам ?


MSSQL 2000

Declare @x varchar(10), @y varchar(10)
Set @x=null; Set @y="foo"
Select @x + @y


                   
--------------------
NULL

(1 row(s) affected)


 
Ega23 ©   (2008-07-01 15:48) [20]


> Все правильно - пока все слагаемы не известны, суммировать
> опасно.


Ну тот же MSSQL :


create table xxx(A int null)

insert into xxx(A) Values (default)
insert into xxx(A) Values (1)
insert into xxx(A) Values (2)
insert into xxx(A) Values (3)
insert into xxx(A) Values (4)

Select Sum(A) from xxx

drop table xxx



-----------
10

(1 row(s) affected)

Warning: Null value is eliminated by an aggregate or other SET operation.


 
Игорь Шевченко ©   (2008-07-01 15:48) [21]

Ega23 ©   (01.07.08 15:47) [19]

Я сильно извиняюсь, а в MSSQL пустая строка и NULL это одно и тоже, как и в Oracle ?


 
Ega23 ©   (2008-07-01 15:50) [22]


> Я сильно извиняюсь, а в MSSQL пустая строка и NULL это одно
> и тоже, как и в Oracle ?
>


Нет. Пустая строка <> NULL. И NULL<> пустому НД (IsEmpty).


 
Игорь Шевченко ©   (2008-07-01 15:53) [23]

Кстати, в oracle
я@ora10> create table xxx(A int null);

Table created.

я@ora10> insert into xxx(A) Values (null);

1 row created.

я@ora10> insert into xxx(A) Values (1);

1 row created.

я@ora10> insert into xxx(A) Values (2);

1 row created.

я@ora10> insert into xxx(A) Values (3);

1 row created.

я@ora10> insert into xxx(A) Values (4);

1 row created.

я@ora10> Select Sum(A) from xxx;

   SUM(A)
----------
       10

Но:

я@ora10> Select Sum(A+10) from xxx;

SUM(A+10)
----------
       50

то есть, в случае A is NULL, A + 10 тоже NULL


 
Игорь Шевченко ©   (2008-07-01 15:54) [24]


> Нет. Пустая строка <> NULL. И NULL<> пустому НД (IsEmpty).


тогда пример ничего не показывает


 
McSimm ©   (2008-07-01 15:55) [25]


> Select Sum(A) from xxx

Ну, спасибо хоть Warning выдал...


 
Ega23 ©   (2008-07-01 15:57) [26]


> тогда пример ничего не показывает


Почему? При конкатенации строк если один из операндов NULL - то и результат NULL. порядок операндов не важен.
В случае с числами - посложнее. по крайней мере, Warning выдаст.

ИМХО: сам использую null только в двух случаях:
1. Иерархические структуры (для определения корневого элемента)
2. При хранении метаданных (BLOB). И то не всегда.


 
McSimm ©   (2008-07-01 15:59) [27]

Да, я напутал, агрегатные функции действительно обычно просто пропускают значения NULL, а в операциях приводят к NULL результат


 
Игорь Шевченко ©   (2008-07-01 16:01) [28]


> При конкатенации строк если один из операндов NULL - то
> и результат NULL. порядок операндов не важен.


а в оракле нет, именно пример с конкатенацией я и привел в [14]
в oracle пустая строка и NULL - это одно и то же. При конкатенации NULL себя ведет, как пустая строка. Вполне разумно. Мне представляется, что в Oracle тоже не понимали до конца, какое отличие с точки зрения предметной области имеют NULL и "", а главное - как их визуально отличать :)


 
pasha_golub ©   (2008-07-01 16:08) [29]


> в oracle пустая строка и NULL - это одно и то же.

Однако. Не знал, что Оракловцы настолько смелы. Обычно это в стиле МС класть прибор на стандарты.


 
Ega23 ©   (2008-07-01 16:09) [30]


> Мне представляется, что в Oracle тоже не понимали до конца,
>  какое отличие с точки зрения предметной области имеют NULL
> и "", а главное - как их визуально отличать :)


Да также, как и с PChar. p=nil и p^="".
Т.е. в одном случае - вааще хзч. В другом - всё-таки пустая строка. :)


 
McSimm ©   (2008-07-01 16:09) [31]


> Игорь Шевченко ©   (01.07.08 16:01) [28]

Никогда не сталкивался, просто интересно - а как в Оракл unique key отнесётся к нескольким пустым строкам ?


 
pasha_golub ©   (2008-07-01 16:10) [32]


> McSimm ©   (01.07.08 16:09) [31]


> а как в Оракл unique key отнесётся к нескольким пустым строкам
> ?

Во, кстати, классный вопрос!


 
Игорь Шевченко ©   (2008-07-01 16:13) [33]

McSimm ©   (01.07.08 16:09) [31]


> а как в Оракл unique key отнесётся к нескольким пустым строкам
> ?


Проигнорирует. Значения NULL в UNIQUE (именно в UNIQUE) не попадают, на чем основано немало остроумных решений проблем.
Но, если ключ состоит из нескольких полей  и одно может принимать значение NULL, то два набора с одинаковым значением одного поля и NULL другого поля вызовут нарушение уникальности.

pasha_golub ©   (01.07.08 16:08) [29]


> Однако. Не знал, что Оракловцы настолько смелы. Обычно это
> в стиле МС класть прибор на стандарты.


Оракл появился немного раньше стандартов.


 
Поросенок Винни-Пух ©   (2008-07-01 16:13) [34]

никак. форинкеи допускают нулы, а юник нет


 
Ega23 ©   (2008-07-01 16:14) [35]


> Никогда не сталкивался, просто интересно - а как в Оракл
> unique key отнесётся к нескольким пустым строкам ?
>


ИМХО, также, как и везде - обматерит.
ЕМНИП, для MSSQL индекс допускается только в том случае, если есть только одно значение Null. Для первичного ключа - вообще не допускается. Для вторичного - можно много null (но он и не является индексом, только "кандидатом" на индекс).


 
atruhin1   (2008-07-01 16:15) [36]

> Например, pgAdminIII, DOA для Oracle, IBX для Interbase/Firebird...

Ну про pgAdminIII не знаю, а про IBX для Interbase/Firebird ты не прав, в IB/FB  и соответственно,
в компонентах это абсолютно разные вещи. Так же как и в MS SQL, т.е. по стандарту.
Oracle поступает по своему, там NULL = "", по моему, обсуждалось много раз, на всех сайтах.
Иногда удобно, иногда нет. Для остальных типов данных (кроме строк) Oracle работает по стандарту.


 
Поросенок Винни-Пух ©   (2008-07-01 16:15) [37]

Однако. Не знал, что Оракловцы настолько смелы. Обычно это в стиле МС класть прибор на стандарты.

Общий подход это использовать либо спец значения типов если они есть, или флаги нулов.
Пустая строка это как раз то спец значение строкового типа, которое позволяет обойтись без флагов.


 
Ega23 ©   (2008-07-01 16:16) [38]


> ЕМНИП, для MSSQL индекс допускается только в том случае,
>  если есть только одно значение Null.


Был неправ:


UNIQUE constraints can be defined on columns that allow null values, whereas PRIMARY KEY constraints can be defined only on columns that do not allow null values.



 
atruhin1   (2008-07-01 16:17) [39]

Нда, опоздал немного с ответом.


 
Игорь Шевченко ©   (2008-07-01 16:20) [40]

Если пример [23] дополнить:

я@ora10> create unique index yyy on xxx(a);

Index created.

я@ora10> select * from xxx order by a;

        A
----------
        1
        2
        3
        4

я@ora10> insert into xxx values(NULL);

1 row created.

я@ora10> select * from xxx order by a;

        A
----------
        1
        2
        3
        4

6 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 4016984797

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     6 |    78 |     4  (25)| 00:00:01 |
|   1 |  SORT ORDER BY     |      |     6 |    78 |     4  (25)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| XXX  |     6 |    78 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------


Видно, что индекс игнорируется, потому что есть значения NULL, а запрошены все записи.

но:

я@ora10>select * from xxx where a is not null order by a

        A
----------
        1
        2
        3
        4

Execution Plan
----------------------------------------------------------
Plan hash value: 2441963755

-------------------------------------------------------------------------
| Id  | Operation        | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------
|   0 | SELECT STATEMENT |      |     4 |    52 |     1   (0)| 00:00:01 |
|*  1 |  INDEX FULL SCAN | YYY  |     4 |    52 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------



Страницы: 1 2 3 4 5 6 вся ветка

Форум: "Прочее";
Текущий архив: 2008.08.24;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.044 c
2-1216624011
TRSteep
2008-07-21 11:06
2008.08.24
INI файл или XML


15-1215461152
maxon
2008-07-08 00:05
2008.08.24
Никто не хочет написать НОВУЮ статью про оптимизацию?


10-1148989839
Andrey_Gor
2006-05-30 15:50
2008.08.24
Error: "Интерфейс не поддерживается"


2-1216215791
savyhinst
2008-07-16 17:43
2008.08.24
TComponentName = type string;


15-1215350457
JohnKorsh
2008-07-06 17:20
2008.08.24
Восстановление реестра в XP.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский