Dlaczego Oracle 9i traktuje pusty łańcuch jako NULL?

Wiem, że totraktuje jako NULL, ale to nie robi wiele, aby powiedzieć miDlaczego tak jest. Jak rozumiem specyfikacje SQL, '' nie jest taki sam jak NULL -- jeden jest poprawnym datum, a drugi wskazuje na brak tych samych informacji.

Nie krępuj się spekulować, ale proszę wskazać, czy tak jest. Jeśli jest ktoś z Oracle, kto może to skomentować, to byłoby fantastycznie!
Author: Cade Roux, 2008-10-15

10 answers

Myślę, że odpowiedź jest taka, że Wyrocznia jest bardzo, bardzo stara.

W dawnych czasach, zanim pojawił się standard SQL, Oracle podjęło decyzję projektową, że puste ciągi w VARCHAR/VARCHAR2 kolumny były NULL i że było tylko jedno poczucie NULL (istnieją teoretycy relacyjni, którzy rozróżnialiby dane, które nigdy nie zostały poproszone, dane, w których odpowiedź istnieje, ale nie jest znana przez użytkownika, dane, w których nie ma odpowiedzi, itp. wszystko to stanowi pewien sens NULL).

Zanim pojawił się standard SQL i zgodził się, że NULL i pusty łańcuch są odrębnymi podmiotami, byli już użytkownicy Oracle, którzy mieli kod, który zakładał, że oba są równoważne. Oracle pozostał więc z opcjami złamania istniejącego kodu, naruszenia standardu SQL lub wprowadzenia pewnego rodzaju parametru inicjalizacji, który zmieniłby funkcjonalność potencjalnie dużej liczby zapytań. Naruszenie standardu SQL (IMHO) było najmniej zakłócenie tych trzech opcji.

Oracle pozostawiło otwartą możliwość, że typ danych VARCHAR zmieni się w przyszłym wydaniu, aby był zgodny ze standardem SQL (dlatego wszyscy używają VARCHAR2 w Oracle, ponieważ zachowanie tego typu danych jest zagwarantowane w przyszłości).

 202
Author: Justin Cave,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-11 20:25:44

Tom Kyte wiceprezes Oracle:

Varchar o zerowej długości jest traktowany jako NULL.

" nie jest traktowana jako NULL.

" po przypisaniu do znaku (1) staje się ""(typy znaków są puste struny).

" przy przypisaniu do varchar2(1) staje się " co jest długością zerową ciąg i ciąg o zerowej długości jest NULL w Oracle (it is no long")

 56
Author: Brian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-15 02:38:52

Podejrzewam, że ma to o wiele większy sens, jeśli myślisz o Oracle tak, jak wcześniej prawdopodobnie robili to deweloperzy - jako gloryfikowany backend dla systemu wprowadzania danych. Każde pole w bazie danych odpowiadało polowi w postaci, którą operator wprowadzania danych widział na swoim ekranie. Jeśli operator nie wpisał niczego do pola, niezależnie od tego, czy jest to "data urodzenia", czy "adres", to dane dla tego pola są"nieznane". Nie ma sposobu, aby operator wskazywał, że czyjś adres jest naprawdę pustym ciągiem znaków, a to i tak nie ma sensu.

 18
Author: user67897,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-18 15:50:41

Dokumentacja Oracle ostrzega deweloperów o tym problemie, sięgając przynajmniej do wersji 7.

Oracle zdecydował się reprezentować null za pomocą techniki "impossible value". Na przykład NULL w numerycznej lokalizacji będzie przechowywana jako "minus zero", wartość niemożliwa. Wszelkie minus zera, które wynikają z obliczeń, zostaną przekonwertowane na dodatnie zero przed zapisaniem.

Oracle wybrał również, błędnie, rozważenie ciągu VARCHAR o długości zero (pusty łańcuch) do być wartością niemożliwą i odpowiednim wyborem do reprezentowania NULL. Okazuje się, że pusty łańcuch jest daleki od wartości niemożliwej. To nawet tożsamość pod działaniem konkatenacji łańcuchów!

Dokumentacja Oracle ostrzega projektantów i programistów baz danych, że niektóre przyszłe wersje Oracle mogą złamać ten związek pomiędzy pustym łańcuchem i NULL i złamać dowolny kod, który zależy od tego związku.

Istnieją techniki oznaczania null innymi niż wartości niemożliwe, ale Oracle ich nie użyła.

(używam słowa "lokalizacja" powyżej, aby oznaczać przecięcie wiersza i kolumny.)

 16
Author: Walter Mitty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-15 13:46:13

Pusty łańcuch jest taki sam jak NULL tylko dlatego, że jest "mniejszym złem" w porównaniu do sytuacji, gdy dwa (pusty łańcuch i null) nie są takie same.

W językach, w których NULL i empty String nie są tym samym, należy zawsze sprawdzić oba warunki.

 2
Author: Alex Kreutznaer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-05 16:33:04

Ponieważ nie traktowanie go jako NULL też nie jest szczególnie pomocne.

Jeśli popełnisz błąd w tej dziedzinie Na Oracle, Zwykle zauważysz go od razu. W SQL serverze jednak wydaje się, że działa, a problem pojawia się tylko wtedy, gdy ktoś wpisuje pusty ciąg znaków zamiast NULL (być może z biblioteki klienta. NET, gdzie null różni się od"", Ale zwykle traktujesz je tak samo).

Nie twierdzę, że Wyrocznia ma rację, ale wydaje mi się, że obie drogi są w przybliżeniu równie źle.

 0
Author: erikkallen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-11 20:27:36

Według oficjalnych dokumentów 11g

Baza danych Oracle traktuje obecnie wartość znaku o długości zero jako null. Może to jednak nie być prawdą w przyszłych wydaniach i Oracle zaleca, aby nie traktować pustych łańcuchów tak samo jak null.

Możliwe przyczyny

  1. val IS NOT NULL jest bardziej czytelny niż val != ''
  2. nie ma potrzeby sprawdzania obu warunków val != '' and val IS NOT NULL
 0
Author: Sorter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-23 11:34:49

Przykład z książki

   set serveroutput on;   
    DECLARE
    empty_varchar2 VARCHAR2(10) := '';
    empty_char CHAR(10) := '';
    BEGIN
    IF empty_varchar2 IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_varchar2 is NULL');
    END IF;


    IF '' IS NULL THEN
    DBMS_OUTPUT.PUT_LINE(''''' is NULL');
    END IF;

    IF empty_char IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_char is NULL');
    ELSIF empty_char IS NOT NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_char is NOT NULL');
    END IF;

    END;
 0
Author: zloctb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-08 15:11:37

Rzeczywiście, nie miałem nic poza trudnościami w radzeniu sobie z Oracle, włączając w to nieprawidłowe wartości datetime (nie mogą być drukowane, konwertowane lub cokolwiek innego, wystarczy spojrzeć na to za pomocą funkcji DUMP ()), które są dozwolone do wstawienia do bazy danych, najwyraźniej przez jakąś błędną wersję klienta jako binarną kolumnę! To tyle jeśli chodzi o ochronę integralności bazy danych!

Oracle obsługa null linki:

Http://digitalbush.com/2007/10/27/oracle-9i-null-behavior/

Http://jeffkemponoracle.com/2006/02/empty-string-andor-null.html

 -6
Author: Cade Roux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-11 23:09:57

Po pierwsze, null I null string nie zawsze były traktowane jako to samo przez Oracle. Null string jest z definicji ciągiem znaków, który nie zawiera żadnych znaków. To wcale nie jest to samo, co null. NULL to z definicji brak danych.

Pięć lub sześć lat temu, null string był traktowany inaczej niż null przez Oracle. Podczas gdy, podobnie jak null, NULL string był równy wszystkim i różny od wszystkiego (co moim zdaniem jest dobre dla null, ale całkowicie błędne dla null string), w najmniejsza długość (null string) zwróci 0, tak jak powinno, ponieważ null string jest ciągiem o zerowej długości.

Obecnie w Oracle length(null) zwraca null, co chyba jest O. K., ale length (null string) również zwraca null, co jest całkowicie błędne.

Nie rozumiem, dlaczego postanowili zacząć traktować te 2 różne "wartości" tak samo. Oznaczają one różne rzeczy i programista powinien mieć możliwość działania na każdy z nich w inny sposób. Fakt, że zmienili swoje metodologia mówi mi, że naprawdę nie mają pojęcia, jak te wartości powinny być traktowane.

 -6
Author: Michael T. Gunderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-11 23:43:27