Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> dziwne naruszenie integralności bazy - jak uniknąć omijania NOT NULL
jolam
post
Post #1





Grupa: Zarejestrowani
Postów: 259
Pomógł: 0
Dołączył: 12.07.2009

Ostrzeżenie: (10%)
X----


Mam taki problem. Podczas dodawania rekordów do tabeli w formularzu przypadkiem nie wypełniłam wszystkich pól. Tabela ma zdefiniowana każda kolumnę jako NOT NULL. I okazało się, że dodanie wiersza z pustymi łańcuchami (wydaje mi się, że puste pole przekazane przez formularz to właśnie taki pusty łańcuch) przeszło przez zabezpieczenie bazy o tych niezerowych kolumnach.
Jak tego uniknąć?

pozdrawiam serdecznie Jola
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 14)
phpion
post
Post #2





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Wartość NULL to nie jest pusty string! Pusty string jest każdy inny string; tyle tylko, że jest pusty (IMG:style_emoticons/default/smile.gif) Jako ciekawostkę powiem Ci jeszcze, że porównanie NULL = NULL zawsze zwróci fałsz. Dlaczego? Bo NULL to wartość, której nie można określić, takie nic. W związku z tym, skoro nie można określi wartości NULL, to nie można jej porównać z inną wartością NULL.
Go to the top of the page
+Quote Post
and_woj
post
Post #3





Grupa: Zarejestrowani
Postów: 4
Pomógł: 0
Dołączył: 22.10.2009

Ostrzeżenie: (0%)
-----


Użytkownik phpion już wyjaśnił, że NULL nie oznacza pustego (niewypełnionego) pola, a wartość "nic". Analogicznie NOT NULL nie zapewni, że do pola tabeli nie da się zapisać pustego łańcucha znaków. W opisanym problemie najlepiej programowo sprawdzić w procedurze zapisującej rekord, czy wypełnione są wszystkie wymagane pola i w zależności od tego utworzyć (lub nie) rekord w tabeli. Nie przychodzi mi do głowy żaden sposób, aby załatwić problem samym SQLem.
Go to the top of the page
+Quote Post
jolam
post
Post #4





Grupa: Zarejestrowani
Postów: 259
Pomógł: 0
Dołączył: 12.07.2009

Ostrzeżenie: (10%)
X----


Jeśli nie w SQL to w PHP. Jak Wy to rozwiązujecie, żeby Wam nie psuły takie przypadki bazy?

Pozdrawiam Jola
Go to the top of the page
+Quote Post
maly_swd
post
Post #5





Grupa: Zarejestrowani
Postów: 744
Pomógł: 118
Dołączył: 14.02.2009
Skąd: poziome

Ostrzeżenie: (0%)
-----


w php:

  1. if($_POST['pole_z_formularza_ktore_nie_moze_byc_puste']) {
  2. //oczywiscie spacja to juz nie jest puste pole
  3.  
  4. tu wykonujesz wstawienie do bazy danych
  5.  
  6. } else {
  7.  
  8. echo "pole z formularza jest puste, nic nie rob";
  9.  
  10. }
Go to the top of the page
+Quote Post
vokiel
post
Post #6





Grupa: Zarejestrowani
Postów: 2 592
Pomógł: 445
Dołączył: 12.03.2007

Ostrzeżenie: (0%)
-----


  1. if (!empty($_POST['pole'])){
  2. // ok
  3. }
  4.  
  5. if (isset($_POST['pole'])){
  6. // ok
  7. }


Ten post edytował vokiel 22.10.2009, 17:38:58
Go to the top of the page
+Quote Post
jolam
post
Post #7





Grupa: Zarejestrowani
Postów: 259
Pomógł: 0
Dołączył: 12.07.2009

Ostrzeżenie: (10%)
X----


To jak lepiej zrobić? Powinnam użyć isset czy !empty?

Pozdrawiam Jola
Go to the top of the page
+Quote Post
piotrooo89
post
Post #8


Newsman


Grupa: Moderatorzy
Postów: 4 005
Pomógł: 548
Dołączył: 7.04.2008
Skąd: Trzebinia/Kraków




ja w 90% przypadkach używam empty. tylko w 10% używam isset, jest to sporadyczne i podyktowane rożnymi specjalnymi okolicznościami.
Go to the top of the page
+Quote Post
phpion
post
Post #9





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Używanie empty() może czasem prowadzić do dziwnych sytuacji. Przykładowo: jeżeli w formularzu wpisujesz wielkość rabatu (wartość <0, 100>) to nie będzie można podać wartości 0, gdyż będzie ona traktowana przez empty() jako pusta. Listę wartości, jakie są uważane za puste znajdziesz w dokumentacji empty w sekcji Return Values.
Go to the top of the page
+Quote Post
piotrooo89
post
Post #10


Newsman


Grupa: Moderatorzy
Postów: 4 005
Pomógł: 548
Dołączył: 7.04.2008
Skąd: Trzebinia/Kraków




i to jest właśnie to 10% przypadków w których używam isset. dzięki ~phpion że o tym wspomniałeś. ważna sprawa.
Go to the top of the page
+Quote Post
thek
post
Post #11





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




To może ja dorzucę Joli dlaczego stało się tak jak mówi. W momencie gdy przesłałaś zawartość formularza na serwer nie wiedziałaś, że niewypełnione pola tekstowe także zwracają pewną wartość, o której nie wiesz. To tak zwany znak końca łańcucha. To jeden z niedrukowalnych znaków o jakim wielu początkujących z programowaniem nie wie, ale bardzo szybko się dowiaduje (IMG:style_emoticons/default/winksmiley.jpg) Zwłaszcza gdy się w C i C++ operuje na ciągach znakowych char*, bo mają one wtedy ogromne znaczenie i zapomnienie o nich potrafi mieć nieprzyjemne konsekwencje. W notacjach jest on zapisywany jako zero poprzedzone ukośnikiem, czyli \0, ale w formularzu podczas przesyłu nieco inaczej -> 0\' i możesz to zobaczyć podglądając zmienne POST. Jak więc widzisz, nie ma tam pustki tak naprawdę, i dlatego baza zapisuje go. To, że nic nie widzisz, nie znaczy, że nic tam nie ma (IMG:style_emoticons/default/winksmiley.jpg) Dlatego jeśli chcesz mieć pewność, że takie coś Ci nie przejdzie to użyj sprawdzenia używając empty() (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
wlatanowicz
post
Post #12





Grupa: Zarejestrowani
Postów: 4
Pomógł: 0
Dołączył: 22.10.2009

Ostrzeżenie: (0%)
-----


Nie za bardzo rozumiem, dlaczego za spójność danych w bazie ma odpowiadać PHP.
Może warto zainteresować się więzami integralności? W tym przypadku należy zadbać o integralność krotki.
Służy do tego CHECK http://www.w3schools.com/Sql/sql_check.asp
Czyli oprócz NOT NULL należy dodać CHECK ( LENGTH( atrybut ) > 0 ) - przy założeniu, że funkcja LENGTH() zwraca długość ciągu znaków
Go to the top of the page
+Quote Post
thek
post
Post #13





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Dlaczego php? Bo skoro dane idą z formularza do bazy, to lepiej już na poziomie obróbki tych danych wyłapać problem niż pozwolić by poszło do bazy i czekać czy baza zwróci problem. Błędy powinno się eliminować w jak najwcześniejszym stadium.

EDIT: Nie dopisałem dlaczego tak uważam... Czasem połączenie z bazą jest wykonywane dla innego serwera niż ten, na którym jest cała strona (rzadkie przypadki, ale jednak). A podejście polegające na zrzucaniu check na bazę zamiast do skryptu wydłuży generowanie całości o czas łączenia z innym serwerem i czas na zwrócenie informacji.

Ten post edytował thek 25.10.2009, 22:28:51
Go to the top of the page
+Quote Post
vokiel
post
Post #14





Grupa: Zarejestrowani
Postów: 2 592
Pomógł: 445
Dołączył: 12.03.2007

Ostrzeżenie: (0%)
-----


Cytat(jolam @ 23.10.2009, 07:30:36 ) *
To jak lepiej zrobić? Powinnam użyć isset czy !empty?

Pozdrawiam Jola


isset sprawdza, czy zmienna została zadeklarowana, empty sprawdza jej wartość. Jak już pisali poprzednicy dla 0 pomimo, że jest jakąś wartością empty zwróci false.

isset jest dobre w celu zorientowania się, czy pola w ogóle zostały wypełnione, albo jakie pola zostały przesłane. Empty może czasem napsuć nerwów, zwykle, gdy używa się go do sprawdzenia czy formularz został wysłany, sprawdzając $_POST z nazwą pola formularza (samego formularza), które nie ma przypisanego value. Niby formularz wysłany, var_dump pokazuje, że jest, a if'a nie przechodzi (IMG:style_emoticons/default/biggrin.gif)
Go to the top of the page
+Quote Post
jolam
post
Post #15





Grupa: Zarejestrowani
Postów: 259
Pomógł: 0
Dołączył: 12.07.2009

Ostrzeżenie: (10%)
X----


Bardzo wam wszystkim dziękuję za odpowiedź!
Szczególnie możliwość stosowania check w definicji bazy danych bardzo mi się podoba (IMG:style_emoticons/default/smile.gif)

Pozdrawiam serdecznie Jola
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 23.12.2025 - 14:25