Witaj nospor!
Wybacz za pozna odpowiedz, ale ostatnio mialem sporo pracy i nie mialem czasu odpowiedziec.
Kontynuujac bardzo ciekawa dyskusje :-)....
I. Cytat z wczesniejszego posta, w ktorym mnie zacytowales:-)
Cytat
kchrapa :
Z punktu widzenia DB nie ma to znaczenia - i tak serwer automatycznie
dokona konwersji do typu danych kolumny.
nospor :
No wlasnie, ale z punktu widzenia DB MySQL. A jak sie przesiądzie na inną:
kchrapa:
Inny system DB - np. Postgres krzyknal by Ci blad, ze podales napis tam gdzie sie
spodziewa liczby (kolumna kj to integer) -i bylo by jasne - a mysql czasami przeholowuje
z user friendly - ale to juz inna para kaloszy ;-)).
nospor:
to bedzie ból bo nabrał złych nawyków, które ty propagujesz.
Chcialbym zauwazyc, ze te dwie moje wypowiedzi dotycza innych aspektow - polaczyles je w
jedno, wyrywajac z kontekstu.
I. Pierwsza wypowiedz ("Z punktu widzenia DB..")- chodzilo o automatyczne rzutowanie
POPRAWNYCH FORMALNIE LICZB (calkowitych i rzeczywistych) przez RDBMS. Jesli poprawna liczba
bedzie w ciapkach, zaden z systemow : MySQL, PostgreSQL, Oracle, MS SQL Server czy Firebird
nie bedzie mial najmniejszych problemow. Automatycznie dokona rzutowania i nawet sie
nie zajaknie(nie jestem pewien jak z DB2 - pracowalem w nim ostatnio z 10 lat temu...i nie pamietam,
ale pewnie podobnie).
Wiec nic nie zaboli przy przejsciu aplikacji na inny rdbms... ;-)
(a jesli sie pojawi problem - bedzie to jedynie kwestia zmiany w domyslnej konfiguracji).
II. Druga wypowiedz - wstawiles ja zeby potwierdzic ostatnie Twoje zdanie moimi slowami
("to bedzie bol..") - ale ona dotyczyla innego aspektu ;-)
Tutaj chodzilo mi o sytuacje , kiedy na wejscie trafia NIEPOPRAWNA LICZBA CALKOWITA
(np. podano liczbe z czescia dziesiatna).
MySQL domyslnie wykonuje liberalna konwersje, tracac czesc informacji (ucina po
przecinku/zaokragla), dosc liberalnie w przypadku klauzuli IN zachowuje sie tez Firebird i
Oracle.
Z kolei Postgres (wraz z MS SQL Server) , jesli bedzie w ciapkach - wyrzuci blad,
jesli bez ciapkow - przemilczy sprawe dokonujac specyficznej konwersji . Czyli raczej ciapki
wplywaja pozytywnie na zachowanie systemu, jako ze wywoluja blad nie pozwalajac
serwerowi wyrzucic nieadekwatnych danych.
Oczywiscie, powyzsze zachowanie podaje dla domyslnych ustawien tych rdbms'ow.
Reasumujac - w kontekscie zapytan SQL (bo tylko o tym byla mowa) - ujecie ich w ciapki wg
mojej wiedzy nie przynosi zadnych negatywnych konsekwencji,a biorac pod uwage
postgresa i mssqlserv - wrecz przeciwnie.
Aczkolwiek - jesli sa jakies obiektywne przyczyny (nie liczac przyzwyczajenia/gustu mojego
czy Twojego), o ktorych nie wiem a z powodu ktorych nalezy z ciapkow w SQL zrezygnowac -
bede wdzieczny za informacje :-)
Ustosunkuje sie jeszcze do ostatniej Twojej wypowiedzi :
Nospor:
Cytat
Kacper:
//nasza bledna dana (zyz@cos) zamieni sie na 0 - co przestawi ilosc produktu na zero
Nospor:
Widzisz, twoja walidacja sprawdza czy jest liczbą. Jak ktoś poda 0 to Twoja walidacja to
przepusci i w efekcie dostaniesz 0 tak jak i ja robiac rzutowanie na tekscie. Widzisz jakąś
roznice w efekcie koncowym?
Kacper:
Wiec zeby uniknac powyzszego problemu, pewnie przed intval dodajesz podobna walidacje -
czyli mamy i walidacje i konwersje
Nospor:
Nie, nie robie walidacji. Ma byc liczbą wiec rzutuje na liczbe i po sprawie. Walidacja jest
tylko wowczas, jesli liczba nie moze byc zerem albo liczbą spoza jakiegoś zakresu. Ale to i
przy Twojej metodzie musialbym też dodac tę dodatkową walidacje, wiec nadal nie ma zadnego
dodatkowego narzutu.
Kacper:
Mysle - ze w tym przypadku i ciapki(u mnie) i intval( u ciebie) sa zbedne
Nospor:
Niestety nadal uwazam ze rzutowanie na liczbe jest ok a dawanie ciapkow jest złym nawykiem.
I tutaj musze Ci jednak zwrocic uwage ,ze rzutowanie bez walidacji nie jest optymalnym podejsciem i moze
spowodowac konkretne problemy. Dlaczego?
To prawda, jesli uzytkownik przy zmianie ilosci produktu wpisze zero, i moj i Twoj program
to przepusci... bo oczywiscie zerowy stan produktow jest jak najbardziej sensowny.I moim
celem nie bylo uniemozliwienie ustawienia takiej wartosci.
Stosowanie walidacji w tym przypadku jest w innym celu - przechwycenie sytuacji,jesli user
nieswiadomie poda cos,co nie jest poprawna liczba calkowita w systemie dziesietnym (a nie
znam chyba usera, ktory SWIADOMIE bedzie probowal wpisac w tym miejscu zapis szesnastkowy
lub binarny - pomijam proby atakow).
I zwroc uwage na dwa podejscia do problemu :
A. z walidacja - system odrzuci jego żądanie informujac o bledzie.Czyli user od razu dowie
sie ze jest problem i swiadomie go skoryguje.
Sedno dzialania: Walidacja nie dopusci do przeklamania danych.
Potrzebna jest tu takze walidacja, aby system RDBMS tez nie dokonal niepoprawnego
rzutowania (np. zaokraglajac liczbe zmiennoprzecinkowa).
B. bez walidacji, ale z rzutowaniem - system skonwertuje bledna dana do 0
i zaktualizuje/wstawi produkt z niepoprawna iloscia.Bez jakiejkolwiek noty dla usera.
Dla jakich danych to nastapi ? Np.:
- 0x1B
- ania'
- x3444
Zarowno intval() jak i rzutowanie (int) liczba , zmodyfikuje bledne dane - zamiast
odrzucic, zmieni "cichaczem" na zero.
Pol biedy, jesli to robi user dla pojedynczego rekordu (moze zauwazy blad) -ale jesli importuje z csv
kilkaset tysiecy rekordow,program sie nawet nie zajaknie - a doswiadczenie pokazuje,
ze w duzej czesci systemow mamy smieci ( widzialem systemy (zarowno male, jak i miedzynarodowych korporacji) gdzie w polu numer_domu bylo wpisane "zosia" )) - podobnie w plikach csv od userow czy innych zrodlach danych.
Reasumujac - na tym poziomie widac bardzo istotna roznice w efekcie koncowym miedzy naszymi
rozwiazaniami.
Walidacja jest niezbedna nie tylko wtedy, gdy nie chcesz wpuscic zera itp, bo
jesli user wpisze 'gucio' , do bazy trafia calkowicie bledne dane (choc poprawne skladniowo
z uwagi na rzutowanie).
Mysle wiec, ze powinienes jednak rozwazyc wprowadzenie walidacji tam, gdzie
robisz tylko rzutowanie.Uszczelni ona system sprawiajac,ze bedzie mniej podatny na
umieszczanie w nim nieadekwatnych informacji.
Pozdrawiam serdecznie ,
Kacper