[Java/SQL] wildcard voor numerieke waarde

Pagina: 1
Acties:
  • 104 views sinds 30-01-2008
  • Reageer

  • Boegel
  • Registratie: Maart 2002
  • Laatst online: 07-01-2018

Boegel

just boegel

Topicstarter
Ik hoop dat ik mijn probleem duidelijk kan uitleggen, here we go...

Ik heb een 'applicatie' waarbij verschillende tekstveldjes moeten (kunnen) ingevuld worden, en er daarna op de 'Zoeken' knop geramd kan worden. Bedoeling is dat die veldjes de ontbrekende delen in een SQL-query gaan invullen, die dan uitgevoerd wordt op een databank, en waarvan de resultaten weergegeven worden.
Het probleem ligt nu bij het feit dat niet alle velden ingevuld moeten worden. Voor 'string' velden is dit geen probleem, dat kan ik detecteren, en gebruik maken van wildcards in de PreparedStatement, waar enkel de ?'s moeten ingevuld worden. Maar hoe moet ik dit doen bij numerieke waarden ? Daar bestaat, voor zover ik weet, geen wildcard voor.
Bvb.

code:
1
2
PreparedStatement stat = conn.createStatement("SELECT * FROM Tabel 
WHERE string = ? AND nummer = ?);


Als het 'string' tekstveld leeg is bij het klikken op de 'zoeken' knop, kan ik gewoon dit doen:

code:
1
stat.setString(1,"%");


Dit levert geen problemen. Als het numeriek veld echter leeg is, dan kan ik dit niet. Ik ben verplicht van de setInt methode te gebruiken, want de waarde van 'nummer' is gedefinieerd als een numerieke waarde in de DDL code van de databank.

Weet er iemand een oplossing, zodat ik nog steeds van PreparedStatement kan gebruiken ? Ik kan natuurlijk de SQL-query 'opbouwen' mbv een string, die dan al dan niet een 'AND nummer = waarde' bevat, als het tekstveld leeg is of niet, maar dit is (volgens mij) veel minder efficiënt...

[ Voor 5% gewijzigd door Boegel op 26-02-2004 22:51 . Reden: layout effe fixen ]

boegel - er zijn maar 10 soorten mensen in de wereld: diegene die het binaire stelsel kennen en diegene die het niet kennen


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 29-04 14:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik snap je probleem niet helemaal, dus wellicht begrijp ik je verkeerd, maar je wilt dus evt. kunnen zoeken op alleen een string, en ook nog op string en nummer mits het nummer-veld ingevuld is?

Ik denk dat je dan het beste gewoon 2 verschillende queries aan kunt maken. Het is wel op te lossen met 1 query hoor, maar of het ook een mooie oplossing is...
Je zoekt op "WHERE string = ? AND nummer = ?". De AND is een booleaanse expressie die alleen true geeft als beide delen waar zijn. Nu wil je dus eigenlijk dat het nummer=? gedeelte altijd waar is als je niet zoekt op nummer. Dit is wel voor elkaar te krijgen door een derde parameter, een boolean, toe te voegen die aangeeft of nummer wel gecontroleerd moet worden of niet. Hier kun je de OR voor gebruiken, aangezien die altijd waar is als één van de 2 delen waar is

Je query wordt dus:
WHERE string=? AND (? OR nummer=?)

Op de plaats van de 2e ? geef je dus simpelweg TRUE als je niet wilt zoeken op nummer (en voor de 3e kun je dan gewoon een willekeurig getal invullen), en anders geef je FALSE

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.


  • Boegel
  • Registratie: Maart 2002
  • Laatst online: 07-01-2018

Boegel

just boegel

Topicstarter
.oisyn schreef op 26 februari 2004 @ 23:06:
Ik snap je probleem niet helemaal, dus wellicht begrijp ik je verkeerd, maar je wilt dus evt. kunnen zoeken op alleen een string, en ook nog op string en nummer mits het nummer-veld ingevuld is?
Het is ook mogelijk dat enkel het nummer veld ingevuld is, maar dat is geen probleem, dat kan ik opvangen door een wildcard te gebruiken voor de 'string' waarde...
.oisyn schreef op 26 februari 2004 @ 23:06:
Ik denk dat je dan het beste gewoon 2 verschillende queries aan kunt maken. Het is wel op te lossen met 1 query hoor, maar of het ook een mooie oplossing is...
Je zoekt op "WHERE string = ? AND nummer = ?". De AND is een booleaanse expressie die alleen true geeft als beide delen waar zijn. Nu wil je dus eigenlijk dat het nummer=? gedeelte altijd waar is als je niet zoekt op nummer. Dit is wel voor elkaar te krijgen door een derde parameter, een boolean, toe te voegen die aangeeft of nummer wel gecontroleerd moet worden of niet. Hier kun je de OR voor gebruiken, aangezien die altijd waar is als één van de 2 delen waar is

Je query wordt dus:
WHERE string=? AND (? OR nummer=?)

Op de plaats van de 2e ? geef je dus simpelweg TRUE als je niet wilt zoeken op nummer (en voor de 3e kun je dan gewoon een willekeurig getal invullen), en anders geef je FALSE
En waarom zou dit geen mooie oplossing zijn ? :+

Het probleem is dat ik geen 2 aparte PreparedStatements kan maken, want eigenlijk zijn er 2 numerieke waarde-velden (dit voorbeeld was gewoon iets simpels, om mijn probleem uit te leggen). Dat zou betekenen dat ik 4 aparte queries zou moeten voorzien (een statement zonder numerieke waarden ingevuld, 2 statements waar 1 numerieke waarde kan ingevuld worden, en dan nog een waar beide numerieke waarden ingevuld kunnen worden).
Als er dan nog één veld zou bijkomen, zou dat een explosie van statements teweegbrengen, en das ook niet echt de bedoeling...

Maar jouw oplossing vind ik vrij elegant eigenlijk :) Op die manier kan ik alles in 1 PreparedStatement steken, wat de boel volgens mij direct een stuk performanter maakt (omdat de compiler beetje kan spelen met die query, ipv die telkens opnieuw te moeten optimaliseren)...

Zeer bedankt !

boegel - er zijn maar 10 soorten mensen in de wereld: diegene die het binaire stelsel kennen en diegene die het niet kennen


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 29-04 14:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Je kunt er ook gewoon voor kiezen om geen PreparedStatement te gebruiken en je query dynamisch op te bouwen. Met een goede database erachter zal het niet eens zoveel uitmaken omdat die sowieso wel queries optimized

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.


  • Boegel
  • Registratie: Maart 2002
  • Laatst online: 07-01-2018

Boegel

just boegel

Topicstarter
.oisyn schreef op 26 februari 2004 @ 23:38:
Je kunt er ook gewoon voor kiezen om geen PreparedStatement te gebruiken en je query dynamisch op te bouwen. Met een goede database erachter zal het niet eens zoveel uitmaken omdat die sowieso wel queries optimized
Gezien die query waarschijnlijk in verschillende methodes zal gebruikt worden, is het makkelijker om PreparedStatement te gebruiken, en bovendien vergt het minder code...

boegel - er zijn maar 10 soorten mensen in de wereld: diegene die het binaire stelsel kennen en diegene die het niet kennen


  • momania
  • Registratie: Mei 2000
  • Laatst online: 10:04

momania

iPhone 30! Bam!

Boegel schreef op 26 februari 2004 @ 23:45:
[...]


Gezien die query waarschijnlijk in verschillende methodes zal gebruikt worden, is het makkelijker om PreparedStatement te gebruiken, en bovendien vergt het minder code...
Tja, als je een steeds varierende input hebt qua aantal attributen dan is het toch verstandiger om je query dynamisch op te bouwen.
Prepared statments moet je eigenlijk alleen maar gebruiken als je iedere keer alle parameters kan vullen en op jouw manier zou je dus een hele smerige prepared statment nodig hebben die qua snelheid misschien dan nog langzamer wordt dan een normale dynamisch opgebouwde query.

En ja, het kost je iets meer code in je java stuk, maar zoveel kan het nou ook weer niet zijn lijkt me. Kwestie van een paar if else'jes en met een StringBuffer je query opbouwen.

Neem je whisky mee, is het te weinig... *zucht*


Acties:
  • 0 Henk 'm!

  • Boegel
  • Registratie: Maart 2002
  • Laatst online: 07-01-2018

Boegel

just boegel

Topicstarter
Nouja, het zou echt smerig worden als het om tientallen tekstvelden zou gaan, maar hier het er maar 6, en ik vind het een beetje stom...
Mijn PreparedStatement-code bevat nu 2 mal een (? OR nummer = ?), en dat vindt ik veel eleganter dan een hoop if-else'jes die de query dynamisch gaan opbouwen...

Ik heb trouwens nog een gelijkaardige vraag...

code:
1
2
PreparedStatement stat = conn.prepareStatement("DELETE FROM Tabel 
WHERE nummer IN (?,?)");


Dit is een ander probleempje... Als een aantal rijen in een tabel geselecteerd zijn, en er wordt op de 'Verwijderen' knop gekllikt, dan worden die verwijderd (uiteraard)... Het probleem is nu, opnieuw, dat ik gebruik wil maken van PreparedStatement, maar ik op voorhand niet weet hoeveel rijen er zullen geselecteerd zijn, en ik dus niet weet hoeveel ? er moeten staan in mijn prepared statement... Heb effe wat zitten zoeken, en er bestaat een methode setArray, maar die blijkt enkel te werken voor Oracle databanken, en die van mij is een andere... En dan nog, Array heeft geen constructor, en er bestaat voor zover ik weet geen Factory klasse die er een kan maken...

Iemand enig idee hoe ik dit kan oplossen ? (hoewel ik denk dat ik dit niet anders zal kunnen oplossen dan dynamisch gaan opbouwen adhv het aantal geselecteerde rijen) (dus telkens nummer = x OR nummer = y OR ...)

boegel - er zijn maar 10 soorten mensen in de wereld: diegene die het binaire stelsel kennen en diegene die het niet kennen


Acties:
  • 0 Henk 'm!

  • Boegel
  • Registratie: Maart 2002
  • Laatst online: 07-01-2018

Boegel

just boegel

Topicstarter
*Kickje*

Niemand die hier een idee over heeft ? Kzou het vrij bizar vinden moest het niet mogelijk zijn eigenlijk...

boegel - er zijn maar 10 soorten mensen in de wereld: diegene die het binaire stelsel kennen en diegene die het niet kennen


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 29-04 14:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Waarom blijf je steeds zo krampachtig gebruik maken van prepared statements?

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.


Acties:
  • 0 Henk 'm!

  • Boegel
  • Registratie: Maart 2002
  • Laatst online: 07-01-2018

Boegel

just boegel

Topicstarter
Omdat ik altijd geweten heb dat die performanter zijn dan het dynamisch opbouwen van query's... Ben ik daar zo fout mee dan ?

Kheb dat laatste 'probleem' nu opgelost met dynamisch opbouwen, dus erg is het niet, en de snelheid zal je wsl ook niet merken, maar het lijkt me een stuk 'eleganter'...

boegel - er zijn maar 10 soorten mensen in de wereld: diegene die het binaire stelsel kennen en diegene die het niet kennen


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Waarom definieer je dan niet 2 prepared statements ?
Een met en een zonder nummer.

En zelfs een int[] is van klasse Array toch, dus wellicht dat je wat moet experimenteren daarmee?
Pagina: 1