Newsgroup: it.comp.java
Titolo: Query maledetta!!!!!!

Sto letteralmente impazzendo....
Ho questa query :
ResultSet rs1 = stmt.executeQuery("SELECT url FROM Dischi WHERE url="+
"'urlo'" );
        boolean presente = rs1.next();
        if(presente)
            rs1.getString("url");
        else
            ur += "AAA";
in urlo c'è la stringa presente all'inteno del campo del db......in
pratica non mi trova nulla di nulla....la variabile presente è sempre
false.... se invece faccio
ResultSet rs1 = stmt.executeQuery("SELECT url FROM Dischi WHERE url="+
'C:/Documents and Settings/Fabio/Desktop/Heroes.mp3' );
        boolean presente = rs1.next();
        if(presente)
            rs1.getString("url");
        else
            ur += "AAA";
ovvero la stringa direttamente nella query allora mi funziona e la
stringa viene trovata.......qualcuno ha idea del perché?

 qualcuno ha idea del perché?
non hai idea di quello che stai facendo.
dove sta scritto che se tu nella query string metti "'urlo'" allora
questo valore viene sostituito col contenuto della variabile "urlo"?
forse in qualche altro linguaggio a te noto, in java no.
di fatto stai cercando "'urlo'" nel database


sono un novello del java.....cmq quello che vedi sopra è un tentativo
a capocchia....
la mia query è :
ResultSet rs1 = stmt.executeQuery("SELECT url FROM Dischi WHERE
url=urlo" );
che cmq non mi funziona ugualamente....

 ha scritto nel messaggio 
news:a7f46e30-452a-4425...@j20g2000hsi.googlegroups.com...



Sinceramente, prima di buttarti su cose avanzate come JDBC, dovresti almeno 
dare un'occhiata ad un manuale sul linguaggio Java.
Ma andrebbe bene anche un linguaggio qualsiasi eh..

 >la mia query � :


 > Ma andrebbe bene anche un linguaggio qualsiasi eh..
cmq vi ringrazio ma ho risolto......mi son ricordato dal php che ci
voleva & var & (l'avevo scritto nel post prima e ho detto
cacchio!!!) .....url='" + urlo + "'".....ed adesso funziona......

 delle stringhe tra apici singoli che spesso uno sbaglia con
La query in questo caso e' la stringa contenuta tra i doppi apici. Tu
vuoi invece concatenare la stringa "SELECT .... WHERE URL=" con il
contenuto della variabile stringa urlo. Non con la stringa "urlo".
Per concatenare due stringhe puoi usare l'operatore + tra di esse.
Esempi:
String s1, s2, s12;
s1 = "ciao";
s2 = " mondo";
s12 = s1+s2;
...
oppure un altro esempio: s1 = "ciao" + s2.
Ora, per farci vedere che hai capito, riscrivi correttamente la query.
r.


forse non hai letto che ho risolto e funziona.....
ResultSet rs1 = stmt.executeQuery("SELECT url FROM Dischi WHERE url='"
+ urlo + "'" );
ciao


cmq giusto per curiosità non è che in tutti i linguaggi uno usa + per
concatenare le stringhe ( assembler, actionscript.....)ed infatti
pensavo che il java fosse uno di quelli che non l'usava....meglio così
grazie cmq

 url=urlo" ); 
ResultSet rs1 = stmt.executeQuery("SELECT url FROM Dischi WHERE 
url='"+urlo+"'" );

 + urlo + "'" );
Bravo.
Sei riuscito a concatenare una stringa con una variabile contenente una
stringa.
Solo che il "funziona" non e' una giustificazione accettabile.
Le cose non basta che funzionino, devono funzionare bene, ed essere pure
efficienti.
Ad usare le natiche, per programmare, sono capaci tutti (purtroppo...)
Devi preparare la query, con un parametro, e passare il parametro al
metodo di esecuzione.
  PreparedStatement sSQL = myConn.prepareStatement(
    "SELECT url FROM Dischi WHERE url=?"
  );
  sSQL.SetString(1, urlo);
  ResultSet url = sSQL.executeQuery();
  url.next();
 
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

   url.next();
qual'e' il metodo piu' efficiente? (non mi interessa se questo e' il
migliore)
Ciao Jack
-- 
Yoda of Borg am I! Assimilated shall you be! Futile resistance is, hmm?

 
Dipende dalla situazione.
Per una query secca il piu' efficiente *non* dovrebbe essere il 
PreparedStatement, in quanto la query va preparata prima di essere eseguita.
Per query ripetute, variando i parametri, il PreparedStatement dovrebbe 
essere piu' efficiente.
Poi credo che molto dipenda dal driver JDBC e dal database.
Per quanto riguarda la mantenibilita' e leggibilita' io prediligo 
decisamente il PreparedStatement, ed e' per questo che lo uso sempre 
(nelle mie applicazioni non necessito di otimizzare allo spasimo..).


perchč mai scusa ?
cioč, la mia č proprio una domanda :
perchč mai dovrei scrivere quelle 4 istruzioni che hai scritto tu quando
posso cavarmela con
Statement stmt = myConn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT url FROM Dischi WHERE
url='"+urlo+"'" );
rs.next();
che sono 3 istruzioni e mi sembrano piů leggibili ?
per lo meno su mysql non cambia assolutamente nulla ne come risultato
ottenuto, ne a livello prestazionale , perchč alla fine al DB sempre quella
č la query che arriva.
se vuoi dire che ti sembra piů chiara come l'hai scritta te, rispetto la tua
opinione , pur non condividendola , se dici che il mio codice č fatto con il
sedere (perchč anch'io scrivo codice cosě) mi piacerebbe capire perchč. non
basta dire "si fa cosě e punto".
quando programmavo in cobol (si parla di 20 anni fa almeno) litigavo sempre
con i teorici della programmazione strutturata. io qualche goto ce lo
mettevo , e alla fine i miei programmi funzionavano, (al contrario dei loro
spesso), erano piů snelli e pure piů leggibili (anche qui comunque dipende
dalla testa che uno ha)
ciao
ps
non sto polemizzando, sia ben chiaro

 non sto polemizzando, sia ben chiaro
Per carita', non l'ho pensato neanche per un attimo.

+ urlo + "'" );
Prova a valorizzare urlo con una stringa contenente un apice e ne
riparliamo. Si usano i parametri, non si concatena in questo modo.

 (nelle mie applicazioni non necessito di otimizzare allo spasimo..).
Ok grazie.
Ho letto anche l'altro tuo post e ora ho le idee un po' piu' chiare.


Andrea Laforgia ha scritto:

C'e' chi, leggitimamente, tratta la variabile urlo prima di concatenarla:
ResultSet rs1 = stmt.executeQuery("SELECT url FROM Dischi WHERE url=" + 
trattaStringaSQL(urlo));
considerandolo piu' leggibile. In effetti ha i suoi vantaggi:
-non hai i punti di domanda (se avessimo parametri nominali sarebbe 
molto meglio),
-e' meno verboso,
-e soprattutto puoi loggare la query con i valori reali.
Per le prestazioni c'e' un discorso da fare. Chi di noi in realta' fa il 
caching dello statement preparato? Io credo nessuno, in quanto cosi' si 
procede di solito:
public User getUserById(Long id) {
    PreparedStatement ps = ..;
    ps.executeQuery...;
    ...
}
il ps e' ottenuto ogni volta. In teoria quindi potrebbe non essere 
preparato. Credo che molto dipenda dal driver e dal database.
Detto questo, io uso il preparedstatement praticamente sempre.

 caching dello statement preparato? Io credo nessuno
Beh mi correggo, intendevo in web application interattive.
Chiaro che in ambito batch lo si fa.

caching dello statement preparato?
Ora come ora, io sto invocando sempre e solo funzioni e stored
procedure Oracle, quindi il vantaggio c'è sempre e comunque.

 passi.
In effetti io utilizzo una classe che decora un prepared statement 
consentendo il logging dei parametri, e lo fa inline con la query cosi' 
che possiamo copiarla direttamente nel TOAD ecc.



Oltre ai problemi prestazionali citati da Roberto aggiungo altri due buoni
motivi per usare i prepared statement:
- si evitano la quasi totalità di SQL injection (comuni in PHP)
- non si devono trattare preelaborare i par. che contengono caratteri
paricolari (apici)
Ciao
F.


intanto ti ringrazio per la spiegazione, sinceramente non sapevo che il
preparedstatement avesse una funzione del genere, pensavo servisse
principalmente per evitere il parse dei caratteri speciali, come dice
Rockerduck. come dicevi giustamente c'è sempre da imparare.
comunque la questione mi ha incuriosito e ho fatto la prova che mi dicevi,
usando o meno la preparedstatement  con una select basata su una variabile
che va da 1 a 21, ripetendo il ciclo 20 volte il che fa 420 cicli..
la differenza è minima , anzi con la prepared ci mette 139 secondi, senza
133.
io uso mysql5.0.27 e il connector è il 5.1.5, quindi DB e driver abbastanza
recenti, su tomcat6.0.14
può darsi che come dici tu il mysql che ho installato non abbia attivata la
funzione di preparazione preventiva delle query, adesso ci do un'occhiata ma
non ne ho ma sentito parlare prima.
potrei fare una prova su oracle (che non amo per nulla) , ma se ne parla
settimana prossima a lavoro.
posto il codice
senza prepared
<%@ page language = "java" import="java.sql.*" %>
<html>
<head>
<title>template</title>
<meta content="text/html; charset=windows-1252" http-equiv="Content-Type">
</head>
<body>
<%
Connection con=null;
try {
    Class.forName("com.mysql.jdbc.Driver");
    con=DriverManager.getConnection("jdbc:mysql://localhost:3306/pippo?&user
=pluto&password=paperino");
    long inizio = System.currentTimeMillis();
    long step = System.currentTimeMillis();
    out.println("crea lo Statement<br>");
    Statement statement=con.createStatement();
    ResultSet rs = null;
    for (int k=1; k<=20; k++)
    for (int i=1; i<=21; i++) {
         rs=statement.executeQuery("SELECT `codice_comune`,
sum(if(28_sesso=1,`conta`,0)) as maschi, sum(if(28_sesso=2,`conta`,0)) as
femmine from `cenpop2001` where eta1 = '"+String.valueOf(i)+"' group by
`codice_comune`");
         int j=0; while (rs.next()) { j++; }
         out.println("step : "+((double)(System.currentTimeMillis() -
inizio))/1000+"  _  crescente : "+((double)(System.currentTimeMillis() -
step))/1000+"  _  nrec : "+j+"<br>");
         inizio= System.currentTimeMillis();
         }
    rs.close();
    statement.close();
}
catch (Exception e) { out.println("4"+e.getMessage()); }
finally {
        try { if (con != null) con.close(); }
        catch (SQLException sqle) { out.println("5"+sqle.getMessage()); }
        }
%>
</body>
</html>
*********************************************************
con prepared
<%@ page language = "java" import="java.sql.*" %>
<html>
<head>
<title>template</title>
<meta content="text/html; charset=windows-1252" http-equiv="Content-Type">
</head>
<body>
<%
Connection con=null;
try {
    Class.forName("com.mysql.jdbc.Driver");
    con=DriverManager.getConnection("jdbc:mysql://localhost:3306/pippo?&user
=pluto&password=paperino");
    long inizio = System.currentTimeMillis();
    long step = System.currentTimeMillis();
    out.println("crea lo Statement<br>");
    PreparedStatement statement=con.prepareStatement("SELECT
`codice_comune`, sum(if(28_sesso=1,`conta`,0)) as maschi,
sum(if(28_sesso=2,`conta`,0)) as femmine from `cenpop2001` where eta1 = ?
group by `codice_comune`");
    ResultSet rs = null;
    for (int k=1; k<=20; k++)
    for (int i=1; i<=21; i++) {
         statement.setString(1,String.valueOf(i));
         rs=statement.executeQuery();
         int j=0; while (rs.next()) { j++; }
         out.println("step : "+((double)(System.currentTimeMillis() -
inizio))/1000+"  _  crescente : "+((double)(System.currentTimeMillis() -
step))/1000+"  _  nrec : "+j+"<br>");
         inizio= System.currentTimeMillis();
         }
    rs.close();
    statement.close();
}
catch (Exception e) { out.println("4"+e.getMessage()); }
finally {
        try { if (con != null) con.close(); }
        catch (SQLException sqle) { out.println("5"+sqle.getMessage()); }
        }
%>
</body>
</html>

 
ResultSet rs1 = stmt.executeQuery("SELECT url FROM Dischi WHERE 
url='urlo'" );
se naturalmente la colonna url è di tipo char o similari.
In po di SQL ti serve...