Utilizzo del carattere jolly "mi piace" nell'istruzione preparata


176

Sto usando istruzioni preparate per eseguire query sul database mysql. E voglio implementare una funzionalità di ricerca basata su una sorta di parola chiave.

Per questo ho bisogno di usare una LIKEparola chiave, questo lo so. E ho anche usato istruzioni preparate prima, ma non so come usarlo LIKEperché dal seguente codice dove aggiungerei il'keyword%' ?

Posso usarlo direttamente nel pstmt.setString(1, notes)come (1, notes+"%")o qualcosa del genere. Vedo molti post su questo sul web ma nessuna buona risposta da nessuna parte.

PreparedStatement pstmt = con.prepareStatement(
      "SELECT * FROM analysis WHERE notes like ?");
pstmt.setString(1, notes);
ResultSet rs = pstmt.executeQuery();

Risposte:


281

È necessario impostarlo nel valore stesso, non nella stringa SQL dell'istruzione preparata.

Quindi, questo dovrebbe fare per un prefisso-match:

notes = notes
    .replace("!", "!!")
    .replace("%", "!%")
    .replace("_", "!_")
    .replace("[", "![");
PreparedStatement pstmt = con.prepareStatement(
        "SELECT * FROM analysis WHERE notes LIKE ? ESCAPE '!'");
pstmt.setString(1, notes + "%");

o una corrispondenza suffisso:

pstmt.setString(1, "%" + notes);

o una partita globale:

pstmt.setString(1, "%" + notes + "%");

18
+1 L'OP potrebbe "impostarlo" nell'SQL - come da ... LIKE '%' || ? || '%'o simile - ma è molto meno flessibile.
Pilcrow

come posso farlo con la modalità NON CASE SENSITIVE? :)
Alpha Gabriel V. Timbol,

2
Non WHERE UPPER(?) LIKE UPPER(?)utilizzare pstmt.setString(2, "%" + notes + "%")
mai la

1
@Alain: grazie. Mi chiedo, questo vale per tutti i RDBMS di cui il mondo è a conoscenza? Forse, '%' || ? || '%'come detto nel primo commento, era meglio, dopo tutto? Non ho l'opportunità di sperimentare in questo momento.
BalusC,

2
@BalusC questo vale per MSSQL, Postgres e MySQL nei miei test. La stringa che viene trasformata in un parametro viene di per sé interpretata come un mix di dati e istruzioni di controllo. La concatenazione di SQL si verifica prima che venga interpretata e preservi la vulnerabilità. Il Centro IEEE per la progettazione sicura afferma di separare rigorosamente i dati e le istruzioni di controllo e di non elaborare mai le istruzioni di controllo ricevute da fonti non attendibili .
Alain O'Dea,

28

Codificalo in questo modo:

PreparedStatement pstmt = con.prepareStatement(
    "SELECT * FROM analysis WHERE notes like ?");
pstmt.setString(1, notes + "%");`

Assicurati di NON includere le virgolette '' come sotto in quanto causeranno un'eccezione.

pstmt.setString(1,"'%"+ notes + "%'");

1
Anche se sembra che qualcuno non si imbatterà in questo presupposto, in realtà è molto valido soprattutto quando si lavora con Oracle. Grazie per la segnalazione!
chiede il

5

possiamo semplicemente farlo, usando la funzione CONCATE SQL.

PreparedStatement pstmt = con.prepareStatement(
      "SELECT * FROM analysis WHERE notes like CONCAT( '%',?,'%')";
pstmt.setString(1, notes);
ResultSet rs = pstmt.executeQuery();

questo funziona perfettamente per il mio caso.


4
PreparedStatement ps = cn.prepareStatement("Select * from Users where User_FirstName LIKE ?");
ps.setString(1, name + '%');

Prova questo.


1
String fname = "Sam\u0025";

PreparedStatement ps= conn.prepareStatement("SELECT * FROM Users WHERE User_FirstName LIKE ? ");

ps.setString(1, fname);

2
Potresti elaborare la risposta anziché limitarti a dare la risposta? Vedi: stackoverflow.com/help/how-to-answer
Edwin

-13
String query="select * from test1 where "+selected+" like '%"+SelectedStr+"%';";


PreparedStatement preparedStatement=con.prepareStatement(query);


// where seleced and SelectedStr are String Variables in my program

non è sicuro, si prega gentilmente di utilizzare una dichiarazione preparata parametrizzata.
Durgesh Kumar,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.