Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[PHP/mySQL] real_escape_string niet voldoende?

Pagina: 1
Acties:

  • DeadMetal
  • Registratie: Mei 2002
  • Laatst online: 23-11 10:14
Ik ben bezig met het maken van een site en heb de veiligheid laten testen door het programma Netsparker, dat de site infeite bestookt met zoveel mogelijk onzin in POST-data, op alle knoppen gaat drukken, en bekende aanvallen uitvoert.

Ik heb op een pagina een query die infeite als volgt werkt:
code:
1
2
3
4
5
6
7
8
<?php
$variabele1 = $mysqli->real_escape_string($_POST["variabele1"]);
$variabele2 = $mysqli->real_escape_string($_POST["variabele2"]);
$variabele3 = $mysqli->real_escape_string($_POST["variabele3"]);

$query = "INSERT INTO tabelnaam (variabele1, variabele2, variabele3) VALUES ('$variabele1', '$variabele2', '$variabele3')";
$mysqli->query($query);
?>


Ondanks dat ik 100% zeker weet dat alle variabelen die deze query ingaan eerst door de functie real_escape_string onderhanden genomen worden, is het het programma toch gelukt om een SQL error te genereren (you have an error in your syntax).

Hoe is dit mogelijk? Ik kom er niet uit...

Ik weet dat prepared statements beter zijn en onthou dit voor de toekomst, maar wil me nu eerst even richten op de huidige programmatuur.

  • Andre-85
  • Registratie: April 2003
  • Niet online

Andre-85

Sid

Heb je al bekeken wat voor data precies gepost word? Dan moet je toch kunnen bepalen hoe je gegenereerde query eruit ziet? Of print je query op het moment dat je een sql error krijgt...

Lorem
Whenever we feel the need to comment something, we write a method instead. - Martin Fowler
People who think they know everything really annoy those of us who know we don't - Bjarne Stroustrup


  • DeadMetal
  • Registratie: Mei 2002
  • Laatst online: 23-11 10:14
Die log ik inderdaad. Dit is wat het programma voor elkaar heeft gekregen:

code:
1
INSERT INTO tabelnaam (var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20, var21, var22, var23) VALUES (NULL, '4', NULL, '-1\' or 1=1+(select 1 and row(1,1)>(select count(*),concat(CONCAT(CHAR(95),CHAR(33),CHAR(64),CHAR(52),CHAR(100),CHAR(105),CHAR(108),CHAR(101),CHAR(109),CHAR(109),CHAR(97)),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1))+\NULL, NULL, NULL, NULL, NULL, '3', '3', 'test', NULL, NULL, 'test', NULL, '3', '3', '1', '1', '3', 'nl', 'pending', '1354294900')


Ik heb de kolomnamen even vervangen door 'var1' etc zodat we kunnen spreken over bij welk variabelenummer het nou mis gaat.

Is het nou 'var4' die gemanipuleerd wordt?

Het klopt overigens dat je NULL zonder quotes eromheen ziet . Ik doe voordat de query de database in gaat een str_replace op de $query om '' door NULL te vervangen (om geen lege string in de DB te zetten maar NULL).

Ik realiseer me ineens dat dat natuurlijk niet veilig is, bijv als de invoer van een gebruiker op een single quote eindigt. Dan heb je in de querystring twee single quotes op rij, die dan door NULL vervangen worden.

Dat lijkt hier echter niet de oorzaak van dit probleem te zijn.

[ Voor 20% gewijzigd door DeadMetal op 03-12-2012 09:23 ]


  • xh3adshotx
  • Registratie: Oktober 2011
  • Laatst online: 28-02-2023
Staan magic_quotes toevallig aan op je server? (Controleren door "echo phpinfo();")

  • DeadMetal
  • Registratie: Mei 2002
  • Laatst online: 23-11 10:14
Nee, staan uit (gedubbelcheckt).

  • DeadMetal
  • Registratie: Mei 2002
  • Laatst online: 23-11 10:14
Ah, mijn code str_replace("''", "NULL", $query); bleek toch wel het probleem te zijn. mysql_real_escape_string zorgde netjes voor de veiligheid.

Echter, mijn str_replace om twee single quotes op rij naast elkaar te vervangen door NULL haalde deze veiligheid weer onderuit. Het laatste karater van de input van var4 was een single quote. Hierna volgde de single quote van de querysting zelf. Dat werd vervangen door NULL, waardoor de query niet meer geldig was.

[ Voor 15% gewijzigd door DeadMetal op 03-12-2012 09:41 ]


  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
DeadMetal schreef op maandag 03 december 2012 @ 09:09:
Ik realiseer me ineens dat dat natuurlijk niet veilig is, bijv als de invoer van een gebruiker op een single quote eindigt. Dan heb je in de querystring twee single quotes op rij, die dan door NULL vervangen worden.

Dat lijkt hier echter niet de oorzaak van dit probleem te zijn.
Jawel. var4 is namelijk in je string
code:
1
'-1\' or <lang verhaal>+\NULL


terwijl dat oorspronkelijk
code:
1
'-1\' or <lang verhaal>+\''


was.

  • DeadMetal
  • Registratie: Mei 2002
  • Laatst online: 23-11 10:14
Bedankt voor het meedenken. Ik heb het programma nog een keer laten runnen zonder dat statement die de query bewerkt, en nu treden er geen errors meer op!

Nu dus een betere manier zien te vinden om in plaats van een lege string de waarde NULL in de database te krijgen in dit geval.

[ Voor 29% gewijzigd door DeadMetal op 03-12-2012 09:41 ]


  • HuHu
  • Registratie: Maart 2005
  • Niet online
DeadMetal schreef op maandag 03 december 2012 @ 09:38:
Ah, mijn code str_replace("''", "NULL", $query); bleek toch wel het probleem te zijn. mysql_real_escape_string zorgde netjes voor de veiligheid.

Echter, mijn str_replace om twee single quotes op rij naast elkaar te vervangen door NULL haalde deze veiligheid weer onderuit. Het laatste karater van de input van var4 was een single quote. Hierna volgde de single quote van de querysting zelf. Dat werd vervangen door NULL, waardoor de query niet meer geldig was.
Waarom doe je die str_replace() dan? Die is nergens voor nodig en maakt het inderdaad stuk.

Het code-voorbeeld in je OP is in feite dus niet wat je daadwerkelijk hebt geïmplementeerd. Dat is ook niet handig.

edit:
DeadMetal schreef op maandag 03 december 2012 @ 09:40:

Nu dus een betere manier zien te vinden om in plaats van een lege string de waarde NULL in de database te krijgen in dit geval.
PHP:
1
$variabele3 = strlen($_POST["variabele3"])==0 ? "NULL" : "'". $mysqli->real_escape_string($_POST["variabele3"]) . "'";

[ Voor 18% gewijzigd door HuHu op 03-12-2012 11:12 ]


  • DukeBox
  • Registratie: April 2000
  • Laatst online: 00:02

DukeBox

loves wheat smoothies

DeadMetal schreef op maandag 03 december 2012 @ 09:40:
Nu dus een betere manier zien te vinden om in plaats van een lege string de waarde NULL in de database te krijgen in dit geval.
Default value van je tabel zo instellen.

Duct tape can't fix stupid, but it can muffle the sound.


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Waarom wil je überhaupt null hebben? Als er een lege string gepost wordt is het een lege string, geen null. Null gebruik je voor ongedefinieerd.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Afgezien van alles hierboven is real_escape_string hoe dan ook niet genoeg om SQL injection te voorkomen. Je wil in ieder geval gebruik maken van prepared statements:

http://php.net/manual/en/intro.pdo.php

https://niels.nu


  • DeadMetal
  • Registratie: Mei 2002
  • Laatst online: 23-11 10:14
@Huhu: klopt, excuus, het voorbeeld was een versimpeling van de werkelijkheid, met enkel datgene waarvan ik dacht dat het relevant was voor het probleem.

@Dukebox, de default value wordt alleen gebruikt als je de kolomnaam helemaal niet meegeeft in je query. Echter, als je aangeeft dat de waarde een lege string moet zijn, dan wordt er ook een lege string opgeslagen in plaats van NULL

@Roblll: ik heb altijd geleerd dat het beter is om NULL te gebruiken in paas van lege strings. Ik weet niet wat daar van waar is, kan ook prima leven met lege strings. Maar wat te denken van als de gebruiker optioneel een getal mag invoeren? Als je dan een lege string in de query voegt (omdat er niks ingevuld wordt), wordt het vertaald naar een 0. Dat is niet de bedoeling. Het alternatief, geen quotes in een query om getallen heen zetten, ik weet niet of ik daar zo'n fan van ben.

[ Voor 45% gewijzigd door DeadMetal op 03-12-2012 12:13 ]


  • Gtoniser
  • Registratie: Januari 2008
  • Laatst online: 02:47
Hydra schreef op maandag 03 december 2012 @ 12:00:
Afgezien van alles hierboven is real_escape_string hoe dan ook niet genoeg om SQL injection te voorkomen. Je wil in ieder geval gebruik maken van prepared statements:

http://php.net/manual/en/intro.pdo.php
Heb je hier ook een beargumentatie voor?
"hoe dan ook niet genoeg" zonder enkele onderbouwing klnkt mij nogal kort door de bocht.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
DeadMetal schreef op maandag 03 december 2012 @ 12:06:
Maar wat te denken van als de gebruiker optioneel een getal mag invoeren?
Dan pass je null als er geen getal is ingevoerd :? Dat is nou nét waar null (lees: ongedefinieerd) voor bedoeld is.
DeadMetal schreef op maandag 03 december 2012 @ 12:06:
Als je dan een lege string in de query voegt (omdat er niks ingevuld wordt), wordt het vertaald naar een 0.
Dan pass je null :? Waarom zou je überhaupt een lege string passen voor iets wat een getal moet zijn?
DeadMetal schreef op maandag 03 december 2012 @ 12:06:
Het alternatief, geen quotes in een query om getallen heen zetten, ik weet niet of ik daar zo'n fan van ben.
Om een getal horen geen quotes; ik weet niet waar je die wijsheid vandaan hebt :? En als je een getal door iets als intval() oid heen haalt hoef je ook niet met mysql_really_really_forrealz_escape_please() te klooien.

[ Voor 16% gewijzigd door RobIII op 03-12-2012 12:58 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:38

.oisyn

Moderator Devschuur®

Demotivational Speaker

Hydra schreef op maandag 03 december 2012 @ 12:00:
Afgezien van alles hierboven is real_escape_string hoe dan ook niet genoeg om SQL injection te voorkomen. Je wil in ieder geval gebruik maken van prepared statements:

http://php.net/manual/en/intro.pdo.php
En om precies dezelfde achterliggende reden die je niet in je post hebt gezet is het gebruik van perpared statements ook niet hoe dan ook genoeg om SQL injection te voorkomen. Die achterliggende reden is namelijk: verkeerd gebruik van de API. Als je eerst iets gaat escapen en daarna het resultaat gaat aanpassen, dan is het niet mogelijk veilig meer. Als je prepared statements gebruikt maar ondertussen wel dynamisch de query string opbouwt en daar onvoorzichtig mee omgaat, dan is het mogelijk niet veilig meer.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • DeadMetal
  • Registratie: Mei 2002
  • Laatst online: 23-11 10:14
RobIII schreef op maandag 03 december 2012 @ 12:48:
[...]
Om een getal horen geen quotes; ik weet niet waar je die wijsheid vandaan hebt :? En als je een getal door iets als intval() oid heen haalt hoef je ook niet met mysql_really_really_forrealz_escape_please() te klooien.
Duidelijk. Kan je dan een dergelijke constructie toepassen om te voorkomen dat het leeglaten van het invoerveld door intval() in een 0 omgetoverd wordt? Want dan wil ik dat de waarde NULL wordt.
code:
1
2
3
4
5
6
7
$nummer = $_POST["nummer"];
if(empty($nummer))
    $nummer = "NULL";
else
    $nummer = intval($nummer);

$query = "UPDATE tabel SET nummer = $nummer";

Weet niet of dat zo netjes is want in het ene geval is $nummer een sting, in het andere geval een nummer. Maar of dat uitmaakt? Het codevoorbeeld van HuHu is ook een optie, maar ik vind dat lastig leesbare code, waardoor ik eventuele bugs waarschijnlijk minder snel zal vinden in de toekomst.

[ Voor 65% gewijzigd door DeadMetal op 03-12-2012 13:22 ]


  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
.oisyn schreef op maandag 03 december 2012 @ 13:02:
[...]

En om precies dezelfde achterliggende reden die je niet in je post hebt gezet is het gebruik van perpared statements ook niet hoe dan ook genoeg om SQL injection te voorkomen. Die achterliggende reden is namelijk: verkeerd gebruik van de API. Als je eerst iets gaat escapen en daarna het resultaat gaat aanpassen, dan is het niet mogelijk veilig meer. Als je prepared statements gebruikt maar ondertussen wel dynamisch de query string opbouwt en daar onvoorzichtig mee omgaat, dan is het mogelijk niet veilig meer.
Eigenlijk is het toch in en in triest dat we deze discussies anno 2012 nog steeds moeten voeren. |:(

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
DeadMetal schreef op maandag 03 december 2012 @ 13:12:
Weet niet of dat zo netjes is want in het ene geval is $nummer een sting, in het andere geval een nummer.
Helemaal niet? null is géén string maar een 'speciale waarde'. 'null' is een string, maar daar had ook 'appelflap' kunnen staan.
[edit]
Oh, je doelt op de PHP variabele $nummer; ja, dat is een string zoals je 't in je voorbeeld doet, maar ook daar had je prima $nummer = null; kunnen gebruiken. Had je prepared statements gebruikt dan was 't daarmee klaar geweest. Nu mag je inderdaad nog logica gaan inbouwen om die querystring goed te krijgen. Mijn initiële reactie ging over de querystring waar je set foo = null moet doen i.p.v. set foo = 'null'.

Verder zou ik dat hele intval/null/if/else gebeuren gewoon in een functie mikken.

[ Voor 43% gewijzigd door RobIII op 03-12-2012 13:44 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:38

.oisyn

Moderator Devschuur®

Demotivational Speaker

Grijze Vos schreef op maandag 03 december 2012 @ 13:12:
[...]

Eigenlijk is het toch in en in triest dat we deze discussies anno 2012 nog steeds moeten voeren. |:(
Klopt, straks komt Firesphere hier nog zeggen dat ie nooit prepared statements gebruikt omdat computers niet te vertrouwen zijn :P

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • !null
  • Registratie: Maart 2008
  • Laatst online: 22:19
Hydra schreef op maandag 03 december 2012 @ 12:00:
Afgezien van alles hierboven is real_escape_string hoe dan ook niet genoeg om SQL injection te voorkomen. Je wil in ieder geval gebruik maken van prepared statements:

http://php.net/manual/en/intro.pdo.php
Want? Ik ben toch eigenlijk wel in de veronderstelling dat zoiets als mysql_real_escape_string() genoeg moet zijn.
Ja je kunt de boel veel netter implementeren met prepared statements etc., tuurlijk. Maar als iets gewoon veilig ge-escaped wordt en er verder niet meer mee gerommeld wordt zou het genoeg moeten zijn.

Ampera-e (60kWh) -> (66kWh)


  • DeadMetal
  • Registratie: Mei 2002
  • Laatst online: 23-11 10:14
Bedankt allemaal, ik ga in het vervolg:
- mysql_real_escape_string blijven gebruiken, maar dan enkel voor strings
- waarden waarbij ik een getal verwacht zonder quotes in de query zetten. Die waarden wel altijd casten naar int etc om zeker te weten dat er geen string in de query terecht komt op die plek. En de waarde NULL geven indien leeglaten toegestaan is.
- geen str_replace meer gebruiken om een lege string om te zetten in NULL

Ik lees overigens uitgebreide discussies op internet of je nou beter (int) of intval() kunt gebruiken.
http://stackoverflow.com/...ce-between-intval-and-int

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Het verschil tussen (int) of intval() boeit niet, tenzij je van base wilt wisselen.

  • lauwsa
  • Registratie: Juli 2010
  • Laatst online: 21-11 06:47
Dus (int) gebruiken, zal iets sneller zijn. Niet dat je het merkt. Maar goed.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:38

.oisyn

Moderator Devschuur®

Demotivational Speaker

Hoezo "dus"?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • lauwsa
  • Registratie: Juli 2010
  • Laatst online: 21-11 06:47
Waarom zou je een typecast functie aanroepen als je zelf ook het object kan typecasten? Lijkt me dat een functie daar voor aanroepen meer CPU power kost. Het is meer een best practice onderwerp. In het echt zal je het verschil niet merken ookal doe je het 100x anders.

[ Voor 8% gewijzigd door lauwsa op 03-12-2012 14:20 ]


  • !null
  • Registratie: Maart 2008
  • Laatst online: 22:19
intval() doet wel iets meer dan een simpele typecast. En een string typecasten met (int) gaat ook alleen maar goed omdat het PHP is :)

Ampera-e (60kWh) -> (66kWh)


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
!null schreef op maandag 03 december 2012 @ 13:49:
Want? Ik ben toch eigenlijk wel in de veronderstelling dat zoiets als mysql_real_escape_string() genoeg moet zijn.
Ik was in de war met addslashes(), sorry. Hoe dan ook is het wel netter om prepared statements te gebruiken, puur vanuit onderhoudbaarheidsoogpunt. Je maakt minder makkelijk een fout in een query.

https://niels.nu


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:38

.oisyn

Moderator Devschuur®

Demotivational Speaker

lauwsa schreef op maandag 03 december 2012 @ 14:19:
Waarom zou je een typecast functie aanroepen als je zelf ook het object kan typecasten?
Daar ging het me niet zozeer om. Het ging me hierom:
Lijkt me dat een functie daar voor aanroepen meer CPU power kost.
Waarom dan?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Je CPU denkt "Hey een functie, whaaaarghwarbleblurp" en raakt daardoor compleet van de leg natuurlijk. Jeweettoch.

https://niels.nu


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:38

.oisyn

Moderator Devschuur®

Demotivational Speaker

:P

Nou blijkt lauwsa op mijn specifieke implementatie wel gelijk te hebben (de cast is ongeveer 2x zo snel als intval()), maar er is geen enkele kant-en-klare reden voor. Intern roepen ze waarschijnlijk gewoon dezelfde functie aan. En dan zit je alleen nog met het verschil tussen een taalconstructie en een generieke functieaanroep, die beide geen runtime overhead hoeven te hebben.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • lauwsa
  • Registratie: Juli 2010
  • Laatst online: 21-11 06:47
Haha. Nou, een normalen functie, Bvb in C++, word een functie"eigenlijk" inline gekopieerd. Doe je alleen wat je moet doen dan kan je van boven naar onder alles afwerken. Zit er een functie in die in dit geval een extra optie heeft, dan zal hij over deze code moeten springen.

Ben alleen aan het twijfelen over deze extra optie, aangezien (int) ook naar een base 10 getal moet converteren, want dat is ook gewoon een setting. Dus... Ik denk dat de beide methodes reversed moeten worden voordat je echt kan weten wat het verschil is. Of gewoon leuk een benchmark runnen om te kijken wat het snelste is.
.oisyn schreef op maandag 03 december 2012 @ 15:01:
:P

Nou blijkt lauwsa op mijn specifieke implementatie wel gelijk te hebben (de cast is ongeveer 2x zo snel als intval()), maar er is geen enkele kant-en-klare reden voor. Intern roepen ze waarschijnlijk gewoon dezelfde functie aan. En dan zit je alleen nog met het verschil tussen een taalconstructie en een generieke functieaanroep, die beide geen runtime overhead hoeven te hebben.
Dat was ik me idd ook net aan het bedenken, je was alleen iets eerder met plaatsen ;).

[ Voor 33% gewijzigd door lauwsa op 03-12-2012 15:03 ]


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
lauwsa schreef op maandag 03 december 2012 @ 15:02:
Haha. Nou, een normalen functie, Bvb in C++, word een functie"eigenlijk" inline gekopieerd.
Euh nee. Een private functie kan inline geplaatst worden maar het punt was meer dat een CPU gewoon geen functies kent, alleen maar jumps. En aangezien code sowieso niet linair is (je zit wel echt te microoptimaliseren als je op cache-misses gaat letten) boeit dat in princiepe weinig.
.oisyn schreef op maandag 03 december 2012 @ 15:01:
:P

Nou blijkt lauwsa op mijn specifieke implementatie wel gelijk te hebben (de cast is ongeveer 2x zo snel als intval()), maar er is geen enkele kant-en-klare reden voor. Intern roepen ze waarschijnlijk gewoon dezelfde functie aan. En dan zit je alleen nog met het verschil tussen een taalconstructie en een generieke functieaanroep, die beide geen runtime overhead hoeven te hebben.
Voor zover ik weet is een cast in PHP geen cast (logisch) maar een soort halfgare stringparse die van "1blaat" ook gewoon 1 maakt. Als invtval het wel 'netjes' doet zou het verschil daar in kunnen zitten. Maargoed, PHP is 10 jaar terug voor mij dus wat er allemaal veranderd is weet ik niet.

[ Voor 44% gewijzigd door Hydra op 03-12-2012 15:18 ]

https://niels.nu


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:38

.oisyn

Moderator Devschuur®

Demotivational Speaker

lauwsa schreef op maandag 03 december 2012 @ 15:02:
Haha. Nou, een normalen functie, Bvb in C++, word een functie"eigenlijk" inline gekopieerd.
Het punt is meer dat een cast zich in C++ ook gewoon naar een functieaanroep vertaalt die al dan niet geinlined wordt.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • lauwsa
  • Registratie: Juli 2010
  • Laatst online: 21-11 06:47
Ahh, oke. Thanks. Maar goed, de conculsie is dus dat er geen merkbaar verschil zal zijn.

[ Voor 4% gewijzigd door lauwsa op 03-12-2012 15:55 ]


  • P.O. Box
  • Registratie: Augustus 2005
  • Niet online
even terugkomen op de NULL discussie...
als je dan toch NULL in een veld wilt hebben als het veld leeg is, waarom gebruik je dan niet gewoon de functie NULLIF van MySQL?

http://dev.mysql.com/doc/...ions.html#function_nullif

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
P.O. Box schreef op maandag 03 december 2012 @ 16:03:
even terugkomen op de NULL discussie...
als je dan toch NULL in een veld wilt hebben als het veld leeg is, waarom gebruik je dan niet gewoon de functie NULLIF van MySQL?

http://dev.mysql.com/doc/...ions.html#function_nullif
Hoe ga je dat doen voor een variabele (int, string) die door de gebruiker niet ingevuld is/wordt? Ik zie even niet hoe dat hier nuttig is? Laat eens een voorbeeldje zien?

[ Voor 3% gewijzigd door RobIII op 03-12-2012 17:21 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • P.O. Box
  • Registratie: Augustus 2005
  • Niet online
RobIII schreef op maandag 03 december 2012 @ 17:21:
[...]

Hoe ga je dat doen voor een variabele (int, string) die door de gebruiker niet ingevuld is/wordt? Ik zie even niet hoe dat hier nuttig is? Laat eens een voorbeeldje zien?
ik dacht zoiets:
MySQL:
1
2
insert into mytable 
set var1 = NULLIF('$var1', '')


maak je wel gebruik van mysql's interne typecasting... is dat je probleem?

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Mijn probleem is a) dat je dan wel een lege string moet binnenkrijgen; een POST die een bepaald veld mist bevat geen lege string, het veld niet eens geset; daar heb je dus alsnog een isset/empty/weet-ik-veel voor nodig en b) hoe ga je dit doen voor integers?

Een POST die een veld mist wil je dan ook als null opslaan, een POST die 't veld wél bevat maar leeg is wil je als lege string opslaan. (Even los van validaties die je natuurlijk uitvoert voordat je überhaupt aan 't opslaan gaat). En voor integers is 't, afhankelijk van je eisen en/of validaties wederom, wellicht weer een ander verhaal.

En dan hebben we 't alleen nog maar over strings/integers. Andere types zijn, mogelijk en afhankelijk van je eisen, mogelijk weer anders. Kortom; ik zie niet hoe NULLIF een "magic bullet" is :Y)

[ Voor 41% gewijzigd door RobIII op 03-12-2012 19:05 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
P.O. Box schreef op maandag 03 december 2012 @ 17:48:
[...]
ik dacht zoiets:
MySQL:
1
2
insert into mytable 
set var1 = NULLIF('$var1', '')


maak je wel gebruik van mysql's interne typecasting... is dat je probleem?
Veel plezier met grotere query's denk ik dan als je dit soort dingen standaard hiervoor gaat gebruiken.
Het ziet er leuk uit als het over 1 variabele gaat, maar ik zie dit niet als echt onderhoudbaar.

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10 08:18
RobIII schreef op maandag 03 december 2012 @ 11:54:
Waarom wil je überhaupt null hebben? Als er een lege string gepost wordt is het een lege string, geen null. Null gebruik je voor ongedefinieerd.
jij gebruikt zeker geen oracle :|
(en dat neem ik jou niet kwalijk, oracle wel)

This message was sent on 100% recyclable electrons.


  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
BasieP schreef op maandag 03 december 2012 @ 21:23:
[...]

jij gebruikt zeker geen oracle :|
(en dat neem ik jou niet kwalijk, oracle wel)
Explain please?

Deze ken ik nog helemaal niet (maar gebruik ook geen oracle)

Enige wat ik zo snel kan vinden is dat oracle geen NULLS meeneemt in de indexen en dus altijd tablescans gaat doen als je naar NULL zoekt.

  • joppybt
  • Registratie: December 2002
  • Laatst online: 23:29
Oracle maakt geen onderscheid tussen een lege string en NULL.

[ Voor 52% gewijzigd door joppybt op 03-12-2012 21:51 ]


  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
joppybt schreef op maandag 03 december 2012 @ 21:50:
[...]

Oracle maakt geen onderscheid tussen een lege string en NULL.
Yikes, nasty...

http://asktom.oracle.com/...QUESTION_ID:5984520277372

Ik geloof niet dat ik wil weten wat er uit een query als :
SQL:
1
select pk from table where varchar='';

komt.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Srsly? :X Did NOT know that :X Maar google lijkt 't wel te bevestigen... Sjeesj :X
Ik vind dit overigens wel een logische verklaring, maar zeker een gotcha...

[ Voor 30% gewijzigd door RobIII op 03-12-2012 22:15 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Persoonlijk vind ik het iets meer als een gotcha, eerder een gigagroot waarschuwingsbord erbij.

Gecombineerd met mijn eerdere gevonden puntje dat null blijkbaar altijd een tablescan forceert bij oracle kan dit nog wel eens een performance-puntje worden als je gaat zoeken naar lege varchar velden (die dan wellicht wel / niet gevonden worden net naargelang NULL=NULL of NULL!=NULL)
Pagina: 1