Avatar billede backupmand Nybegynder
19. september 2003 - 14:58 Der er 22 kommentarer og
1 løsning

PreparedStatement returnerer ikke ResultSet alligevel?

I en eller anden skør sammenhæng er jeg ramt ind i en sjov problemstilling med at mit forberedte statement ikke returnerer noget ResultSet

ResultSet res=mitStatement.executeQuery(sqlStreng);

executeQuery skal jo returnere et ResultSet....

Jeg har foreberedt statementet med prepareStatement fra
Connection før det, så det skulle ikke være det.
Query'en er bare en "SELECT * FROM ?"

Kan man ikke sætte strengen når man skal bruge statementet med setString(1,tabelnavn); ??? Det er da skørt.

Nogle ideer?
Avatar billede arne_v Ekspert
19. september 2003 - 15:00 #1
Øh.

Du angiver da SQL strengen i prepareStatement og ikke i executeQuery med
PrepatedStatement ??
Avatar billede backupmand Nybegynder
19. september 2003 - 15:02 #2
ups executeQuery() fra PreparedStatement kan jo ikke tage en streng
Avatar billede arne_v Ekspert
19. september 2003 - 15:03 #3
PreparedStatement pstmt = con.preparedStatement(sqlStreng);
pstmt.setString(1,tabelnavn);
ResultSet rs = pstmt.executeQuery();
Avatar billede backupmand Nybegynder
19. september 2003 - 15:03 #4
ja præcis, det var mig der skrev forkert men der returneres stadig ikke noget resultset ... nogle ideer?
Avatar billede arne_v Ekspert
19. september 2003 - 15:06 #5
Forsøger du at angive tabel navn med ? altså:

"SELECT * FROM ?"

?

Det tvivler jeg nemlig på vil virke.
Avatar billede backupmand Nybegynder
19. september 2003 - 15:09 #6
ja det gør jeg
Avatar billede arne_v Ekspert
19. september 2003 - 15:14 #7
Tabel og felt navne ville jeg lave i selve sqlStreng.

Altså:

String sqlStreng = "SELECT * FROM " + tabel + " WHERE " + felt + "=?";
Avatar billede arne_v Ekspert
19. september 2003 - 15:15 #8
Fordelene ved prepared statement er:

* man har ikke problemer med ' og " i tekst strenge
* man har ikke problemer med dato formater
* bedre performance da det er billigt at skifte indholdet af et ? ud

Ingen af delene kan vidt finde anvendelse på tabelnavne.
Avatar billede erikjacobsen Ekspert
19. september 2003 - 15:18 #9
Og yderligere: hvis du har brug for at parametrisere dine tabelnavne, så
er det formenligt fordi din tabelstruktur ikke er optimal.
Avatar billede backupmand Nybegynder
19. september 2003 - 16:31 #10
Det kan være det er min database der ikke er optimal ... he det kigger jeg dog lige på senere. Jeg vil dog nok forsøge at løse problemet uden brug af PreparedStatements (altså lige i dette tilfælde)...
Avatar billede soelvpil Nybegynder
19. september 2003 - 18:17 #11
Du har ikke skrevet hvad der sker.

Får du null tilbage?
Får du en exception (og hvad siger den)?

Og jeg mener heller ikke man kan lave dynamisk tabeller eller felter i en preparedstatement.

Ideen er, at man siger noget i retningen af

SELECT * FROM USERS WHERE USERNAME = ? AND PASSWORD = ?

Og senere sætter den præcise værdi for navn og passwordet. Tabelnavne og feltnavne kan man imidlertid ikke sætte ind i ?.

Årsagen er, at databasen modtager dit sql, skal den faktisk kompilere det (til databasends eget interne format), hver gang den modtager en sql-streng den ikke har set før.

Bruger du en PreparedStatement, er det den samme sql-streng, uanset hvilket password der sættes ind, og skal derfor kun kompileres første gang, den kaldes.

Bruger du alm Statement, bliver den forskellig, hver gang den kaldes, og skal derfor kompileres hver gang.

Dette er gevinsten ved PreparedStatements, men de kan altså ikke alt!
Avatar billede arne_v Ekspert
19. september 2003 - 19:55 #12
Ja det var der enig om allerede for flere timer siden.
Avatar billede arne_v Ekspert
19. september 2003 - 19:55 #13
Og et svar.
Avatar billede backupmand Nybegynder
20. september 2003 - 16:46 #14
Hvordan kan man afgøre om en tabelstruktur ikke er optimal, hvis jeg har brug for at parametrisere tabelnavne? Jeg forstår det ikke og vil gerne have det at vide.
Avatar billede backupmand Nybegynder
20. september 2003 - 16:52 #15
Ja jeg får selvfølgelig en nullpointerexception der hvor der bliver hentet noget ud fra resultsettet fordi det forberedte statement ikke returnerede noget, fordi jeg havde skrevet SELECT * FROM ? i mit preparedStatement. Jeg har løst det på en sådan måde at jeg ikke benytter forberedte statements. Det var sikkert et spørgsmål om tid før jeg havde fundet ud af at det ikke kunne lade sig gøre i forberedte statements. Det er nogle gange nemmere at spørge herinde, da der findes højt kompetente mennesker som er hurtige til at svare!
Avatar billede arne_v Ekspert
20. september 2003 - 16:59 #16
Det kan man heller ikke.

Men det er lidt usædvaneligt at have det behov.

Og du kan bruge mit 19/09-2003 15:14:27 forslag til at bruge prepared statement
med alligevel.
Avatar billede backupmand Nybegynder
20. september 2003 - 17:10 #17
Tak tak
Avatar billede backupmand Nybegynder
20. september 2003 - 17:12 #18
Men er det fordi det er dårligt database design, at det er et usædvanligt behov?
Avatar billede soelvpil Nybegynder
20. september 2003 - 20:17 #19
Det er ikke nødvendigvis et dårligt design, men måske...

I langt de fleste situationer, er der ikke noget vundet ved at parameterisere tabellerne. Man har nogle få tabeller, der alligevel er meget forskellige. Koden bliver også lidt sværere at læse.

Man kan jo spørge sig selv, i hvilke situationer der vil være en gevinst ved at parameterisere. Og det vil der sandsynligvis være, hvis man har mange tabeller, der er meget ens, men med små forskelle. En sådan databse er ikke særligt normaliseret, og jeg tror, det er det, der ligger bag Erik's lidt kryptiske kommentar.
Avatar billede backupmand Nybegynder
20. september 2003 - 22:05 #20
Jeg kan oplyse om, at min database overhovedet ikke følger nogle normalformer og på ingen måde er optimeret. Som det ser ud i øjeblikket skal der bare være mulighed for lagring af permanent data og hentning af data, der netop er
gemt i database. Så hvorfor bekymre sig om normalformer tihi.
Avatar billede arne_v Ekspert
20. september 2003 - 22:34 #21
En ofte set konstruktion er:

afdelingA
---------
id    navn
1    X
2    Y

afdelingB
---------
id    navn
3    Z
4    W

som i de fleste tilfælde mere hensigtsmæssigt kunne laves som:

medarbejdere
------------
id    navn    afdeling
1      X        A
2      Y        A
3      Z        B
4      W        B

Generelt kan det godt betale sig at lave en pæn tabel struktur. Men vi
ved jo ikke noget om kravene til din applikation.
Avatar billede erikjacobsen Ekspert
21. september 2003 - 07:20 #22
Var der tale om horisontal fragmentering i en distribueret database, kunne
den først opdeling  komme på tale.

;) Men jeg mangler endnu at se et spørgsmål om det på eksperten.dk...
Avatar billede backupmand Nybegynder
21. september 2003 - 11:00 #23
Jeg ville tilføje at grunden til at databasen er som den ser ud nu her hos mig (hvor der gøres brug af parametrisering af tabelnavne) er en kombination af min manglende viden på dette område og så arbejdsgiverens ide .. hvad kan man gøre.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester