problem z NOT NULL

0

Mam utworzoną tabelę:

CREATE TABLE test
(
id int UNIQUE,
nazwa varchar(55) NOT NULL,
rok date,
miasto varchar(55),
liczba int DEFAULT 100
)

Dlaczego gdy próbuje dodać:

INSERT INTO test(id, rok, miasto, liczba)
VALUES(1, '1995-01-01', 'Bielsko-Biala', 200)

to ten rekord zostaje dodany mimo że nie podaję nic do pola nazwa które ma ustawione NOT NULL?

1

Właśnie dlatego, że nic nie dodajesz, to "ląduje" tam NULL, które nie ma prawa tam "wylądować". Musisz albo coś tam wstawiać (NOT NULL) albo ustawić np. DEFAULT ""

Edit: albo tłumacz sobie zapis nazwa VARCHAR(55) NOT NULL - nazwa nie może przyjąć wartości pustej - NULL, musi przyjąć określoną wartość, musi zostać podana...

0

trochę nie rozumiem, to skoro nie nie podaje do tego pola gdzie jest NOT NULL to nie powinienem dostawać jakiegoś błędu?

0
lofi napisał(a)

Dlaczego gdy próbuje dodać:

INSERT INTO test(id, rok, miasto, liczba)
VALUES(1, '1995-01-01', 'Bielsko-Biala', 200)

to ten rekord zostaje dodany mimo że nie podaję nic do pola nazwa które ma ustawione NOT NULL?

not null gwarantuje, że pole nie będzie mieć takiej wartości. skoro taka wartość się dodaje i nie leci błąd, to albo pole nie ma not null, albo ma default, albo istnieje trigger lub inny mechanizm, który ustawia polu niepustą wartość. nie ma innej opcji. coś zrobiłeś źle, albo czegoś nie zauważyłeś.

i jeszcze jedno: która baza danych???

0

Ciekawe, MySQL 5.5 pozwolił na takie zapytanie...
firebird wyrzucił validation error for column NAZWA, value "*** null ***"
SQLite wyrzucił test.nazwa may not be NULL...

Po co w MySQL jest NOT NULL??? :/

0
ŁF napisał(a)

która baza danych???

MySQL 5.1.34-community, w tym polu nie ma wartości domyślnej, sprawdzałem jeszcze zawartość programem HeidiSQL i rzeczywiście rekord został dodany z pustym polem na które ustawiłem NOT NULL.

0

Znalezione na jakimś forum:

If your "not null" field is a text type (TEXT, VARCHAR, ..) then it's not null, but empty. So MySQL doesn't complain, because it cannot distinguish between empty and null.

If you define an integer (or any other number type) field "not null", then MySQL would complain, if you leave it without any value. (If set a default value for your "not null" field, then MySQL wouldn't complain either.)

wolne tłumaczenie:

Jeśli pole oznaczone jako NOT NULL jest polem typu tekstowego (TEXT, VARCHAR) MySQL nie rzuca się, bo nie potrafi rozróżnić pustego łańcucha i NULL - dla niego to jest to samo.

Jeśli pole oznaczone jako NOTT NULL jest polem liczbowym, MySQL będzie się rzucać, bo nie wstawiasz żadnej wartości - tutaj dla niego istnieje różnica pomiędzy pustą wartością a liczbą

0

czy ktoś ma jeszcze jakiekolwiek złudzenie, że mysql powinien być nazywany RDBMS???
:D :D :D :D :D :D

0
madmike napisał(a)

Jeśli pole oznaczone jako NOT NULL jest polem typu tekstowego (TEXT, VARCHAR) MySQL nie rzuca się, bo nie potrafi rozróżnić pustego łańcucha i NULL - dla niego to jest to samo.
o ku*wa! oO
i ja kiedyś tego shitu używałem...

0

Wyobraźcie sobie koledzy, że w języku JAVA porównam napisy za pomocą operatora '==', a następnie po zauważeniu, że to nie działa, zacznę najeżdżać na sam język, jego użytkowników i twórców.

Wy dokładnie to robicie tylko, że w stosunku do MySQL. Wypadałoby najpierw przekonać się jak coś działa albo zajrzeć do dokumentacji, żeby w ogóle zabierać głos...

Teraz trochę przykładów:
mysql> CREATE TABLE tab (id INT NOT NULL, name VARCHAR(40) NOT NULL);
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO tab (id, name) VALUES (1, NULL);
ERROR 1048 (23000): Column 'name' cannot be null

mysql> INSERT INTO tab (id, name) VALUES (NULL, 'napis');
ERROR 1048 (23000): Column 'id' cannot be null

mysql> INSERT INTO tab (name) VALUES ('napis');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> INSERT INTO tab(id) VALUES (1);
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> SELECT * FROM tab;

id name
0 napis
1
2 rows in set (0.00 sec)
3

i co z tego wynika?? Jedynie tyle, że mysql robi coś po swojemu i inaczej niż wszystkie znane mi SZBD. W Oracle, FB, MSSQL (te mogłem sprawdzić teraz) ŻADEN rekord nie jest dodawany! Tylko mysql jak zawsze PO SWOJEMU. Każda normalna baza traktuje wartość nieobecną w insercie jako NULL a nie "c*** wi co"

0

To samo mogę powiedzieć o języku JAVA. Operator '==' działa inaczej niż w innych językach programowania, inaczej niż się niektórzy spodziewają. Teraz powstaje pytanie czy używając operatora '==' do porównywania napisów to ja jestem ignorantem, który nie zajrzał do dokumentacji czy może to z językiem jest coś 'nie tak'?

Jak pokazałem powyżej NOT NULL działa! Przy próbie wstawienia NULL do takiego pola dostajemy błąd. Problem powstaje tylko wtedy gdy nie podamy w ogóle tego pola. Wg mnie jeżeli ktoś wcześniej zajrzał do dokumentacji albo to sprawdził to nie ma większego problemu, wie jak to działa i jest przygotowany na takie zachowanie. Niestety ignoranci mają problem, używają czegoś nie wiedząc jak to działa, a później mają pretensje...

0

czyli jednym słowem it's a feature not a bug :D :D :D :D

Co do JAVY i == to w C# jest tak samo i tutaj nie ma się co spodziewać jeśli tylko ma się świadomość, że wszystko jest obiektem. Co do mysqla to tak jest bo tak i koniec. Adam naprawdę nie ma co wymyślać tutaj jakiejś filozofii - po prostu ktoś w mysqlu wymyślił sobie, że będzie inaczej niż wszędzie i tak zostało. Myślę, że Twoje porównanie jest chybione bo o ile w przypadku javy czy c# wcale nie jest trudno dostrzec różnicę między == a equals i samemu domyśleć się dlaczego tak a nie inaczej o tyle w przypadku mysqla i inserta bez podania pola dlaczego baza nie traktuje tego jako wartość null można tylko zgadywać lub przyjąć do wiadomości, że "tak jest bo tak i koniec"

0

Wszystko jest rzeczą umowną. Przykładowo w języku Python jest taki 'kwiatek':

4 + True
5

Nie wspominając o tym, że do porównywania napisów, które są obiektami (jak wszystko w Pythonie) można użyć operatora '=='...

Z resztą w tym języku można za pomocą tego operatora porównywać również inne typy sekwencyjne:

napis1 = 'dupa'
napis2 = 'dupa'
napis1 == napis2
True
lista1 = [1,2,3]
lista2 = [1,2,3]
lista1 == lista2
True

Porównywanie tożsamości obiektów możemy przeprowadzić za to za pomocą operatora 'is'

lista1 = [1,2,3]
lista2 = [1,2,3]
lista1 is lista2
False
lista1 = lista2
lista1 is lista2
True

Dodam jeszcze, że język Python pojawił się w 1991 roku czyli 4 lata przed językiem JAVA i 10 lat przed C# (jeżeli ma jakieś znaczenie to, że operator '==' miał przed 1995 rokiem inne zastosowanie).

Podsumowując: uważam, że to sprawa umowna jak zachowa się silnik bazy danych w chwili gdy nie podamy, któregoś pola. Podobnie jak sprawą umowną jest to czy za pomocą operatora '==' porównujemy tożsamość obiektów czy też ich wartość. To, że MySQL zachowuje się inaczej niż inne bazy danych, nie oznacza, że będzie to przeszkadzało w czymkolwiek developerowi, który ma świadomość tego zachowania. Podobnie jak odmienne zachowanie się operatora '==' nie przeszkadza żadnemu developerowi języka JAVA. W końcu takie zachowanie MySQL nie wyklucza tego, że ten RDBMS jest dobrym i skutecznym wyborem w swojej klasie tj. aplikacje webowe.

1

hmm kiedyś na studiach miałem taką sytucję gdy zaczęto uczyć nas Javy, że jeden ze studentów nie potrafił zrozumieć dlaczego jego program nie działa. Był święcie przekonany że przekazując obiekt do metody wywołuje się konstruktor kopiujący i można sobie dowolnie modzić na obiekcie wewnątrz tej metody co było w dużej mierze prawdą/normalnym zachowaniem w przypadku c++.
Teraz w przypadku mysqla jest różnica w stosunku do innych baz. Powyżej dość podobny przykłąd, ale nie do końca - java jest innym językiem niż c++ i raczej nie można oczekiwać, że wszystko jest takie samo - każdy język ma swoją specyfikę, składnię logikę której należy się nauczyć. I teraz czy to Java śmierdzi czy programista się nie douczył? Ano w tym przypadku programista - nie można zakładać że c++ i java jest tym samym.

A w przypadku baz? Owszem MySql i Postrgres to dwie różne rzeczy, ale implementujące to samo. Czyli wychodząc z jednej bazy powinienem czuć się w miarę swobodnie w drugim - w końcu po to są jakieś standardy. Stwierdzenie że developerom którzy się douczą to nie przeszkadza jest dziwne - mi przekadza, chociażby dlatego że muszę poświęcić swój własny czas ($) aby dowiedzieć się tych małych króczków zapisanych w odmętach dokumentacji na temat rzeczy oczywistych.

PRzykłądy które podałeś to tak jak porównać język niemiecki i polski, natomiast zachowanie mysqla to jak porównywać wyrazy "poszedłem" oraz "poszedłem" w języku polskim - dla niektórych różne formy są bardziej poprawne :)

0

Absolutnie nie masz racji.

Istniejące obecnie i najpopularniejsze systemy baz danych (MySQL, PostgreSQL, Oracle, MSSQL, Firebird) mają wspólne to, że implementują relacyjny model danych, który bazuje na matematycznej teorii mnogości. Jednak każda z tych baz danych implementuje ten model nieco odmiennie i może nie obsługiwać niektórych elementów. Podobnie większość języków występujących w tych bazach danych jest w większym lub mniejszym stopniu zgodna ze standardami SQL, jednak żaden system nie obsługuje standardu w pełni. Posłużę się tutaj cytatem z Wikipedii:

Większość wewnętrznych języków RDBMS jest w pewnym stopniu zgodna ze standardem języka zapytań SQL. Język ten doczekał się już dwóch standardów – SQL92 i SQL99, jednak różnice pomiędzy teoretycznie SQL-owymi systemami są zbyt duże, żeby możliwe było przeniesienie nawet relatywnie prostej aplikacji z jednego systemu na drugi.

Wymienię kilka znaczących różnic w poszczególnych implementacjach baz danych:

RDBMS łączenie napisów pole autogenerowane
MySQL niezgodne ze standardem AUTO_INCREMENT niezgodne ze standardem
MSSQL zgodne ze standardem IDENTITY zgodne ze standardem
Oracle zgodne ze standardem SEQUENCE lub TRIGGER niezgodne ze standardem
PostgreSQL zgodne ze standardem SERIAL niezgodne ze standardem
RDBMS Natural join Full join kolejność NULL po użyciu ORDER BY Widoki
MySQL obsługuje nie obsługuje NULL jest przed NOT NULL zgodne ze standardem
MSSQL nie obsługuje obsługuje NULL jest przed NOT NULL zgodne ze standardem
Oracle obsługuje obsługuje NULL jest po NOT NULL zgodne ze standardem
PostgreSQL obsługuje obsługuje NULL jest po NOT NULL niezgodne ze standardem
RDBMS insert wielu rekordów boolean funkcja substring funkcja trim
MySQL obsługuje nie obsługuje, można użyć BIT zgodna ze standardem zgodna ze standardem
MSSQL od wersji 2008 nie obsługuje, można użyć BIT niezgodna ze standardem niezgodna ze standardem
Oracle obsługuje obsługuje niezgodna ze standardem niezgodna ze standardem
PostgreSQL od wersji 8.2 obsługuje zgodna ze standardem zgodna ze standardem
0
AdamPL napisał(a)

Podsumowując: uważam, że to sprawa umowna jak zachowa się silnik bazy danych w chwili gdy nie podamy, któregoś pola. Podobnie jak sprawą umowną jest to czy za pomocą operatora '==' porównujemy tożsamość obiektów czy też ich wartość. To, że MySQL zachowuje się inaczej niż inne bazy danych, nie oznacza, że będzie to przeszkadzało w czymkolwiek developerowi, który ma świadomość tego zachowania. Podobnie jak odmienne zachowanie się operatora '==' nie przeszkadza żadnemu developerowi języka JAVA. W końcu takie zachowanie MySQL nie wyklucza tego, że ten RDBMS jest dobrym i skutecznym wyborem w swojej klasie tj. aplikacje webowe.

Zgadzam się z tym - każdy produkt bazodanowy może zachowywać się tak jak mu wygodnie o ile jest to opisane w jego (na pewno obszernej ;-) ) dokumentacji - dopóki produkt nie używa w nazwie hasła SQL lub wprost określany jest hasłem "NoSQL".

Praca z MySQL jest wg mnie ciekawsza niż innymi bazami danych. Przy każdej okazji (jak widać powyżej) jest szansa na zrobienie "o!". Oczywiście o ile się wcześniej pracowało z innymi RDBMS.

Co do języków to w C++ operatory "*" i "&" (wraz z ==) też mogą działać alternatywnie - w zależności od widzi-misię programisty.
Patrz inteligentne wskaźniki i:
http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Operator_Overloading

0
vpiotr napisał(a)

Zgadzam się z tym - każdy produkt bazodanowy może zachowywać się tak jak mu wygodnie o ile jest to opisane w jego (na pewno obszernej ;-) ) dokumentacji - dopóki produkt nie używa w nazwie hasła SQL lub wprost określany jest hasłem "NoSQL".

W takim wypadku żaden RDBMS nie powinien używać w nazwie SQL, ponieważ żaden RDBMS nie jest zgodny z żadnym standardem poza swoim własnym (patrz poprzedni post).

vpiotr napisał(a)

Co do języków to w C++ operatory "*" i "&" (wraz z ==) też mogą działać alternatywnie - w zależności od widzi-misię programisty.

Chodziło mi o domyślne zastosowanie operatorów. To o czym piszesz to insza inszość.

1

Ja bym się natomiast przyczepił że not null działa różnie w zależności od typu danych co jest dość dziwne, to tak jakby == w javie inaczej działało dla String i Integer(jako obiekt).

1 użytkowników online, w tym zalogowanych: 0, gości: 1