Uso de comodines "me gusta" en la declaración preparada


176

Estoy usando declaraciones preparadas para ejecutar consultas de bases de datos mysql. Y quiero implementar una funcionalidad de búsqueda basada en una especie de palabra clave.

Para eso necesito usar LIKEpalabras clave, eso lo sé. Y también he usado declaraciones preparadas antes, pero no sé cómo usarlo LIKEporque, desde el siguiente código, ¿dónde agregaría el 'keyword%'?

¿Puedo usarlo directamente en el pstmt.setString(1, notes)as (1, notes+"%")o algo así? Veo muchas publicaciones sobre esto en la web, pero no hay una buena respuesta en ningún lado.

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

Respuestas:


281

Debe establecerlo en el valor en sí, no en la cadena SQL de la declaración preparada.

Entonces, esto debería hacer para una coincidencia de prefijo:

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

o una coincidencia de sufijo:

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

o una coincidencia global:

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

18
+1 El OP podría "configurarlo" en el SQL, como por ... LIKE '%' || ? || '%'o similar, pero eso es mucho menos flexible.
— Pilcrow

¿Cómo lo hago con el modo SENSIBLE NO EN CASO? :)
— Alpha Gabriel V. Timbol

2
Todavía no se distingue entre mayúsculas y minúsculas WHERE UPPER(?) LIKE UPPER(?)cuando se usapstmt.setString(2, "%" + notes + "%")
— Zig

1
@Alain: Gracias. Me pregunto si esto se aplica a todos los RDBMS que el mundo conoce. ¿Tal vez '%' || ? || '%'como se menciona en el primer comentario fue mejor, después de todo? No tengo la oportunidad de experimentar en este momento.
— BalusC

2
@BalusC esto se aplica a MSSQL, Postgres y MySQL en mis pruebas. La cadena que se convierte en un parámetro se interpreta como una combinación de datos e instrucciones de control. La concatenación SQL ocurre antes de que se interprete y preserva la vulnerabilidad. El IEEE Center for Secure Design dice que separe estrictamente los datos y las instrucciones de control, y nunca procese las instrucciones de control recibidas de fuentes no confiables .
— Alain O'Dea

28

Codifícalo así:

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

Asegúrese de NO incluir las citas '' como se muestra a continuación, ya que causarán una excepción.

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

1
Aunque parece que alguien no se encontrará con esta suposición, en realidad es muy válida, especialmente cuando se trabaja con Oracle. Gracias por señalar!
— pide el

5

podemos hacer esto de manera simple, usando la función CONCATE SQL.

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

Este es un trabajo perfecto para mi caso.


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

Probar esto.


1
String fname = "Sam\u0025";

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

ps.setString(1, fname);

2
¿Podría elaborar la respuesta en lugar de simplemente dar la respuesta? Ver: 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

no es seguro, utilice amablemente la declaración preparada parametrizada.
— Durgesh Kumar el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.