PDA

View Full Version : [JAVA] Query & String


joeykiske
29-04-2010, 01:45
Salve,
devo salvare il risultato di una query in una stringa ma utilizzando il metodo standard mi cattura un'eccezione e non prosegue,ovviamente,la continuazione del programma..SQLException..

Metodo utilizzato!

String query = "SELECT Persona FROM Utenti WHERE Identificativo='JoeyKis'";
Statement s = con.createStatement();
s.executeQuery();
ResultSet rset = s.getResultSet();

String user; //variabile dove devo inserire il risultato

while(rset.next())
{

System.out.println("Persona"); //It Works!
user = rset.getString("Persona"); //SQLException.... :mad:

}


Se eseguo un SOPLN (System.out.pr....) non ci son problemi ma,se provo a memorizzarlo java.sql.SQLException: No data found ..:cry:
Ho provato anche utilizzando un Array..nel caso in cui il problema fosse che getString è un array di dati,come da guida ufficiale,ma nemmeno così funge.. :mad:

Whats Happened?????? :mad:

Grazie Anticipatamente

franksisca
29-04-2010, 09:15
ora non vorrei dire castronerie, ma mi sembra che rset sia un vettore(o matrice) che contiene per ogjni elemento una riga del db....ma non sono sicuro X_X


P.S.: SOPLN non lo avevo mai sentito......


posta quello che stampa che vediamo cmq

shinya
29-04-2010, 09:19
Non ti aspettare molto dai driver jdbc.
Se fai rset.getString(1) funziona?

Sbrizzolo86
29-04-2010, 09:57
Che io sappia i driver JDBC funzionano perfettamente, bisogna solo saperli usare :)

Chiarisco alcuni punti che spero ti permetteranno di risolvere

1) La primissima cosa che salta all'occhio è che tu non esegui alcuna query. Devi passarla come argomento di executeQuery(). Il fatto che ti abbia "permesso" di non passare alcun argomento per quello che ricordo è perchè la query si può passare anche al metodo prepareStatement(), alternativo al createStatement() per usare i preparedStatement.

2) Non c'è bisogno di richiamare getResultSet(), in quanto il metodo executeQuery() ritorna direttamente un ResultSet

3) Il ResultSet è un array (mi pare, ma non ha importanza) NAVIGABILE di n-ple risultato della query. Tramite il metodo .next() accedi alla prossima n-pla. Ogni n-pla è un insieme di valori (uno per ogni colonna della tabella risultato della query) ai quali accedi come hai fatto tu, con il metodo .getString(arg) dove arg = nome o numero della colonna. Non escludo tuttavia l'esistenza di altri metodi, io usavo sempre questo.

4) In che senso il SOPLN (:D ) funziona? E' logico, stai stampando la stringa "Persona", non una variabile o un risultato di un metodo come, appunto, è rset.getString("Persona").


Ricapitolando, ecco come dovrebbe funzionare il tuo codice:


String query = "SELECT Persona FROM Utenti WHERE Identificativo='JoeyKis'";

//ammesso che 'con' sia una Connection aperta e funzionante
Statement s = con.createStatement();
ResultSet rset = s.executeQuery(query);

String user; //variabile dove devo inserire il risultato

//il ciclo è corretto, in genere si prelevano più di una n-pla. In questo caso sei sicuro che la n-pla è una e solo una, puoi ometterlo e fare semplicemente rset.next()
while(rset.next())
user = rset.getString("Persona");



Un codice alternativo che usa i più comodi PreparedStatement (dacci un'occhiata in rete perchè sono molto comodi):


PreparedStatement pst = con.prepareStatement("SELECT Persona FROM Utenti WHERE Identificativo = ?");
pst.setString(1,"JoeyKis");
ResultSet rset = pst.executeQuery();

String user; //variabile dove devo inserire il risultato
while(rset.next())
user = rset.getString("Persona");




Facci sapere.

Alessandro

shinya
29-04-2010, 10:07
Che io sappia i driver JDBC funzionano perfettamente, bisogna solo saperli usare :)
LOL. Prova a passare un parametro BLOB ad una stored procedure su oracle 8i, poi riparliamo della bontà dei driver jdbc dei vari vendor.


Ricapitolando, ecco come dovrebbe funzionare il tuo codice:


String query = "SELECT Persona FROM Utenti WHERE Identificativo='JoeyKis'";

//ammesso che 'con' sia una Connection aperta e funzionante
Statement s = con.createStatement();
ResultSet rset = s.executeQuery(query);

String user; //variabile dove devo inserire il risultato

//il ciclo è corretto, in genere si prelevano più di una n-pla. In questo caso sei sicuro che la n-pla è una sola, puoi dunque ometterlo e fare semplicemente rset.next()

rset.next();
user = rset.getString("Persona");


Però hai ragione, avevo glissato la prima parte del codice. L'errore è che non passa la query a executeQuery.

Sbrizzolo86
29-04-2010, 10:16
Sara' perche' usavo i jdbc per mysql (con utilizzo pesante di blob tra l'altro) ma io non ho mai avuto problemi.

E comunque, per quello che sembra debba fare joeykiske, vanno più che bene, a meno che non debba passare blob a stored procedures su Oracle 8i...

joeykiske
29-04-2010, 23:41
per prima cosa devo ricordarvi che vi AMO :D funziona tutto! :p

secondo..in executeQuery(query) c'era la query ma ho riscritto il codice e ho dimenticato di metterlo..sorrysorry..:(

terzo..il problema si presentava ugualmente se prima del sopln il getString già restituisce un valore identico a quello che sarà assunto dalla variabile..:confused: ero abituato con il c# dove potevo utilizzare il tutto quante volte volevo :D :D

quarto..è possibile creare una classe DB,in Java,con i metodi Query(String nomedb,String user) e Close() che non catturi un'eccezione SQLException quando viene richiamata Close? :mbe: :mbe: appena posso vi posto il codice xkè ora non sono con il portatile connesso..

Grazie ancora..!! :mano: :ubriachi:

Sbrizzolo86
30-04-2010, 10:50
Non so se ho capito bene, comunque se ti dà "fastidio" il lancio dell'eccezione SQLException puoi benissimo mettere il tutto dentro un try{}catch(SQLException e) e nel blocco catch non fare niente, in tal modo il lancio di questa eccezione avverrà in maniera completamente trasparente e non te ne accorgerai.

Certo non è il massimo della programmazione.

Per quanto riguarda una classe "DB", io te ne posto una che feci "a suo tempo", magari ti può essere di aiuto. Non mi assumo alcuna responsabilità sulla qualità del codice, ma credo che non sia poi così male :)


/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package database;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.*;
import java.util.Vector;

public class DConnessione
{
private String nomeDB; // Nome del Database a cui connettersi
private String nomeUtente; // Nome utente utilizzato per la connessione al Database
private String pwdUtente; // Password usata per la connessione al Database
private String errore; // Raccoglie informazioni riguardo l'ultima eccezione sollevata
private Connection db; // La connessione col Database
private boolean connesso; // Flag che indica se la connessione è attiva o meno
private static DConnessione unicaIstanza = null; // attributo di classe, ovvero l'unica istanza della classe (Singleton)

public DConnessione(String nomeDB, String nomeUtente, String pwdUtente)
{
this.nomeDB = nomeDB;
this.nomeUtente = nomeUtente;
this.pwdUtente = pwdUtente;
connesso = false;
errore = "";
}

//metodo di classe che si occupa di recuperare il puntatore all'unica istanza della classe
public static DConnessione istanza()
{
if (unicaIstanza == null) unicaIstanza = new DConnessione("botteghino", "root", "stargate");
return unicaIstanza;
}

// Apre la connessione con il Database
public boolean connetti()
{
connesso = false;
try
{
// Carico il driver JDBC per la connessione con il database MySQL
Class.forName("com.mysql.jdbc.Driver");
db = DriverManager. getConnection("jdbc:mysql://localhost/"+nomeDB,nomeUtente,pwdUtente);

// La connessione è avvenuta con successo
connesso = true;
} catch (Exception e) { errore = e.getMessage();}
return connesso;
}


// Esegue una query di selezione dati sul Database
// ritorna un Vector contenente tutte le tuple del risultato
public Vector eseguiQuery(String query)
{
//inizializzo le variabili "v" (dove metto tutto), record (dove inserirà l'i-esima tupla) e colonne (della tupla)
Vector v = null;
String [] record;
int colonne = 0;

try
{
// Creo lo Statement ed il ResultSet per l'esecuzione della query
Statement stmt = db.createStatement();
ResultSet rs = stmt.executeQuery(query);

//istianzio il vector v, lo faccio solo ora che sono sicuro che la query è andata a buon fine
v = new Vector();

//estraggo i metadati dal ResultSet, per poterne ricavare il numero di colonne
ResultSetMetaData rsmd = rs.getMetaData();
colonne = rsmd.getColumnCount();

//scorro tutto il ResultSet, tupla per tupla
while(rs.next())
{
//inizializzo la variabile di supporto "record" dove inserire la tupla corrente (le colonne le ho ricavate prima)
record = new String[colonne];

//copio la tupla corrente nel record corrente
for (int i=0; i<colonne; i++) record[i] = rs.getString(i+1);

//inserisco il contenuto del record corrente in coda al vector
v.add( (String[]) record.clone() );
}

//chiudo il ResultSet e lo Statement
rs.close();
stmt.close();
} catch (Exception e) { e.printStackTrace(); errore = e.getMessage(); }

return v;
}

//restituisce un vector con un solo elemento per ogni record (è come array di stringhe)
public Vector eseguiQuery2(String query)
{
//inizializzo le variabili "v" (dove metto tutto), record (dove inserirà l'i-esima tupla) e colonne (della tupla)
Vector v = null;

try
{
// Creo lo Statement ed il ResultSet per l'esecuzione della query
Statement stmt = db.createStatement();

ResultSet rs = stmt.executeQuery(query);

//istianzio il vector v, lo faccio solo ora che sono sicuro che la query è andata a buon fine
v = new Vector();

//scorro tutto il ResultSet, tupla per tupla
while(rs.next())
{
v.add( (String) rs.getString(1));
}

//chiudo il ResultSet e lo Statement
rs.close();
stmt.close();
} catch (Exception e) { e.printStackTrace(); errore = e.getMessage(); }

return v;
}

// Esegue una query di aggiornamento sul Database
// ritorna TRUE se l'esecuzione è adata a buon fine, FALSE se c'è stata un'eccezione
public boolean eseguiAggiornamento(String query)
{
//inizializzo le variabili numero e risultato
int numero = 0;
boolean risultato = false;

try
{
Statement stmt = db.createStatement();
numero = stmt.executeUpdate(query);
risultato = true;
stmt.close();
}
catch (Exception e)
{
e.printStackTrace();
errore = e.getMessage();
risultato = false;
}
return risultato;
}

//Esegue una query sul database di selezione di un SINGOLO file
//il formato restituito è di tipo binario (array di byte)
public byte[] estraiFileByte(String query) throws SQLException, IOException
{
// Creo lo Statement ed il ResultSet per l'esecuzione della query
PreparedStatement pstmt = db.prepareStatement(query);
ResultSet rs = pstmt.executeQuery();

//inizializzo a null l'array di byte
byte[] b = null;

//sposto in avanti il puntatore del ResultSet (la posizione di default è "0", mentre la prima riga del risultato è in posizione "1"
rs.next();

//prelevo i dati binari dalla prima colonna (supponendo di avere fatto una SELECT selezionando direttamente la colonna desiderata)
b = rs.getBytes(1);

//chiudo il ResultSet e lo Statement
rs.close();
pstmt.close();

return b;
}

//Esegue una query sul database di selezione di un SINGOLO file
//il formato restituito è di tipo InputStream
public InputStream estraiFileInput(String query) throws SQLException, IOException
{
// Creo lo Statement ed il ResultSet per l'esecuzione della query
PreparedStatement pstmt = db.prepareStatement(query);
ResultSet rs = pstmt.executeQuery();

//inizializzo a null l'InputStream
InputStream fin = null;

//sposto in avanti il puntatore del ResultSet (la posizione di default è "0", mentre la prima riga del risultato è in posizione "1"
rs.next();

//prelevo i dati binari dalla prima colonna (supponendo di avere fatto una SELECT selezionando direttamente la colonna desiderata)
fin = rs.getBinaryStream(1);

//chiudo il ResultSet e lo Statement
rs.close();
pstmt.close();
fin.close();
return fin;
}

//Esegue una query sul database di selezione di un SINGOLO file
//il file viene copiato in locale (utile per il caricamento di trailers)
public void estraiFileCopia(String query) throws SQLException, IOException
{
// Creo lo Statement ed il ResultSet per l'esecuzione della query
PreparedStatement pstmt = db.prepareStatement(query);
ResultSet rs = pstmt.executeQuery();

//inizializzo a null l'array di byte
byte[] b = null;

//sposto in avanti il puntatore del ResultSet (la posizione di default è "0", mentre la prima riga del risultato è in posizione "1"
rs.next();

//prelevo i dati binari dalla prima colonna (supponendo di avere fatto una SELECT selezionando direttamente la colonna desiderata)
b = rs.getBytes(1);

//creo il file in locale (momentaneamente vuoto) con nome uguale al codice dello spettacolo
String codiceSPT = rs.getString(2);
OutputStream fos = new java.io.FileOutputStream(new File(codiceSPT+".avi"));

//trasferisco i dati binari appena prelevati nel contenuto del nuovo file
fos.write(b);

//forzo la sovrascrittura e chiudo il file
fos.flush();
fos.close();

//chiudo il ResultSet e lo Statement
rs.close();
pstmt.close();
}

// Chiude la connessione con il Database
public void disconnetti()
{
try
{
db.close();
connesso = false;
} catch (Exception e) { e.printStackTrace(); }
}

public boolean isConnesso() { return connesso; } // Ritorna TRUE se la connessione con il Database è attiva
public String getErrore() { return errore; } // Ritorna il messaggio d'errore dell'ultima eccezione sollevata
}



due precisazioni:

1) se ti dà fastidio l'SQLException del close(), cancella il contenuto del 'catch' del metodo disconnetti() e non ti accorgerai di alcuna eccezione.
2) come avrai notato ci sono alcuni metodi un po' particolari che servivano al caso mio (lettura di file), tu prendi solo quello che ti serve, presumo i metodi per aprire/chiudere la connessione ed eseguire queries.

Alessandro

joeykiske
03-05-2010, 15:16
devo provare la tua soluzione ma,sembra molto interessante..grazie! ;)