Wiem, że nie uważają „” tak NULL
, ale to nie robi wiele, aby mi powiedzieć, dlaczego tak jest. Jak rozumiem specyfikacje SQL, „” nie jest tym samym, co NULL
- jeden jest prawidłowym układem odniesienia, a drugi wskazuje na brak tych samych informacji.
Możesz spekulować, ale proszę wskazać, czy tak jest. Gdyby ktoś z Oracle mógł to skomentować, byłoby fantastycznie!
Odpowiedzi:
Wierzę, że odpowiedź jest taka, że Oracle jest bardzo, bardzo stara.
W dawnych czasach, zanim istniał standard SQL, Oracle podjęło decyzję projektową, że puste ciągi w
VARCHAR
/VARCHAR2
kolumnach sąNULL
i że istnieje tylko jedno wyczucie NULL (istnieją teoretycy relacyjni, którzy rozróżniają dane, o które nigdy nie pytano, dane, na które odpowiedź istnieje, ale nie są znane użytkownikowi, dane, na które nie ma odpowiedzi itp., z których wszystkie stanowią pewien sensNULL
).Zanim pojawił się standard SQL i zgodził się na to,
NULL
a pusty ciąg znaków był odrębną jednostką, już byli użytkownicy Oracle, którzy mieli kod, który zakładał, że oba są równoważne. Tak więc Oracle zasadniczo pozostawiono z opcją złamania istniejącego kodu, naruszenia standardu SQL lub wprowadzenia pewnego rodzaju parametru inicjującego, który zmieniłby funkcjonalność potencjalnie dużej liczby zapytań. Naruszenie standardu SQL (IMHO) było najmniej zakłócające z tych trzech opcji.Oracle pozostawił otwartą możliwość
VARCHAR
zmiany typu danych w przyszłej wersji, aby dostosować się do standardu SQL (dlatego wszyscy używająVARCHAR2
w Oracle, ponieważ zachowanie tego typu danych z pewnością pozostanie takie samo w przyszłości).źródło
Tom Kyte Wiceprezes Oracle:
źródło
''
jest się domyślnie konwertowany na VARCHAR2, taki jak ten,cast('' as char(1)) is null
który jest ... zaskakująco PRAWDZIWYPodejrzewam, że ma to o wiele więcej sensu, jeśli myślisz o Oracle tak, jak to robili wcześniej programiści - jako chwalebny backend dla systemu wprowadzania danych. Każde pole w bazie danych odpowiadało polu w postaci, którą operator wprowadzania danych widział na swoim ekranie. Jeśli operator nie wpisał niczego w polu, niezależnie od tego, czy jest to „data urodzenia”, czy „adres”, dane dla tego pola są „nieznane”. Operator nie ma możliwości wskazania, że czyjś adres jest naprawdę pustym ciągiem, a to i tak nie ma większego sensu.
źródło
Dokumentacja Oracle ostrzega programistów o tym problemie, sięgając przynajmniej do wersji 7.
Oracle wybrał reprezentowanie wartości NULLS techniką „niemożliwej wartości”. Na przykład NULL w lokalizacji numerycznej zostanie zapisany jako „minus zero”, niemożliwa wartość. Wszelkie zera ujemne wynikające z obliczeń zostaną przekonwertowane na zero dodatnie przed zapisaniem.
Oracle również błędnie wybrało uznanie ciągu VARCHAR o długości zero (pusty ciąg) za wartość niemożliwą i odpowiedni wybór do reprezentowania wartości NULL. Okazuje się, że pusty ciąg jest daleki od niemożliwej wartości. To nawet tożsamość w ramach operacji łączenia łańcuchów!
Dokumentacja Oracle ostrzega projektantów i programistów baz danych, że niektóre przyszłe wersje Oracle mogą zerwać to powiązanie między pustym ciągiem znaków a wartością NULL, a także zerwać dowolny kod zależny od tego powiązania.
Istnieją techniki oznaczania wartości NULLS inne niż wartości niemożliwe, ale Oracle ich nie używała.
(Używam słowa „lokalizacja” powyżej, oznaczającego przecięcie wiersza i kolumny).
źródło
Pusty ciąg znaków jest taki sam jak NULL po prostu dlatego, że jest „mniejszym złem” w porównaniu z sytuacją, gdy dwa (pusty ciąg i zero) nie są takie same.
W językach, w których NULL i pusty ciąg znaków nie są takie same, zawsze należy sprawdzić oba warunki.
źródło
not null
ograniczenie dla kolumny i zaznacz tylko pusty ciąg.WHERE Field <> ''
zwraca wartość true tylko wtedy, gdy pole nie ma wartości NULL i nie jest puste, w bazach danych z zachowaniem ANSI dla pustych łańcuchów.Według oficjalnych dokumentów 11g
Możliwe przyczyny
val IS NOT NULL
jest bardziej czytelny niżval != ''
val != '' and val IS NOT NULL
źródło
val <> ''
już wykluczaNULL
. Być może miałeś na myślival = '' OR val IS NULL
. Ale przydatne są puste ciągi, które nie są porównywane jako NULL !Przykład z książki
źródło
Ponieważ nie traktowanie go jako NULL również nie jest szczególnie pomocne.
Jeśli popełnisz błąd w tym obszarze na Wyroczni, zwykle natychmiast zauważysz. Jednak na serwerze SQL wydaje się działać, a problem pojawia się tylko wtedy, gdy ktoś wprowadzi pusty ciąg zamiast NULL (być może z biblioteki klienta .net, gdzie null różni się od „”, ale zwykle traktuje się je tak samo ).
Nie twierdzę, że Oracle ma rację, ale wydaje mi się, że oba sposoby są w przybliżeniu jednakowo złe.
źródło
Rzeczywiście, miałem tylko trudności w radzeniu sobie z Oracle, w tym niepoprawne wartości daty / godziny (nie można ich wydrukować, przekonwertować ani nic, po prostu spojrzał na funkcję DUMP ()), które mogą być wstawiane do bazy danych, najwyraźniej przez jakiś błąd wersja klienta jako kolumna binarna! Tyle o ochronie integralności bazy danych!
Obsługa linków NULL przez Oracle:
http://digitalbush.com/2007/10/27/oracle-9i-null-behavior/
http://jeffkemponoracle.com/2006/02/empty-string-andor-null.html
źródło
Po pierwsze, ciągi zerowe i zerowe nie zawsze były traktowane tak samo przez Oracle. Ciąg zerowy jest z definicji ciągiem niezawierającym znaków. To wcale nie jest to samo, co zero. NULL to z definicji brak danych.
Pięć lub sześć lat temu łańcuch zerowy traktowany był przez Oracle inaczej niż zerowy. Podczas gdy, podobnie jak null, łańcuch zerowy był równy wszystkim i różny od wszystkiego (co myślę, że jest w porządku dla null, ale całkowicie NIEPRAWIDŁOWY dla łańcucha zerowego), przynajmniej długość (łańcuch zerowy) zwróci 0, tak jak powinno, ponieważ łańcuch zerowy jest ciąg o zerowej długości.
Obecnie w Oracle długość (null) zwraca wartość null, która, jak sądzę, jest OK, ale długość (łańcuch null) również zwraca wartość null, co jest całkowicie NIEPRAWIDŁOWE.
Nie rozumiem, dlaczego postanowili zacząć traktować te 2 odrębne „wartości” tak samo. Oznaczają różne rzeczy, a programista powinien mieć możliwość działania na każdym z nich na różne sposoby. Fakt, że zmienili swoją metodologię, mówi mi, że tak naprawdę nie mają pojęcia, jak należy traktować te wartości.
źródło
VARCHAR
pole może mieć wartość (zero lub więcej znaków) lub brak wartości (NULL), kropka.NULL
łańcuchem o wartości zerowej i takie rozróżnienie nie ma sensu. Obawiam się, że ta odpowiedź jest kompletną fantazją.