Utilisation du caractère générique "J'aime" dans une instruction préparée

176

J'utilise des instructions préparées pour exécuter des requêtes de base de données mysql. Et je souhaite implémenter une fonctionnalité de recherche basée sur une sorte de mot-clé.

Pour cela, j'ai besoin d'utiliser des LIKEmots-clés, je le sais. Et j'ai également utilisé des instructions préparées auparavant, mais je ne sais pas comment l'utiliser avec LIKEcar à partir du code suivant, où ajouterais-je le 'keyword%'?

Puis-je l'utiliser directement dans le pstmt.setString(1, notes)comme (1, notes+"%")ou quelque chose comme ça. Je vois beaucoup de messages à ce sujet sur le Web mais aucune bonne réponse nulle part.

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

Réponses:

281

Vous devez le définir dans la valeur elle-même, pas dans la chaîne SQL de l'instruction préparée.

Donc, cela devrait faire pour une correspondance de préfixe:

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

ou une correspondance de suffixe:

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

ou une correspondance globale:

pstmt.setString(1, "%" + notes + "%");
BalusC
la source
18
+1 L'OP pourrait le "définir" dans le SQL - comme par ... LIKE '%' || ? || '%'ou similaire - mais c'est beaucoup moins flexible.
Pilcrow
comment faire avec le mode NON-CASE SENSITIVE? :)
Alpha Gabriel V.Timbol
2
Non sensible à la casse peut toujours être utilisé WHERE UPPER(?) LIKE UPPER(?)lors de l'utilisationpstmt.setString(2, "%" + notes + "%")
Zig
1
@Alain: Merci. Vous vous demandez simplement, est-ce que cela s'applique à tous les SGBDR dont le monde a connaissance? Peut-être '%' || ? || '%'que comme mentionné dans le premier commentaire était mieux, après tout? Je n'ai pas l'opportunité d'expérimenter pour le moment.
BalusC
2
@BalusC cela s'applique à MSSQL, Postgres et MySQL dans mes tests. La chaîne transformée en paramètre est elle-même interprétée comme un mélange de données et d'instructions de contrôle. La concaténation SQL se produit avant son interprétation et préserve la vulnérabilité. Le Centre IEEE pour la conception sécurisée dit de séparer strictement les données et les instructions de contrôle, et de ne jamais traiter les instructions de contrôle reçues de sources non fiables .
Alain O'Dea
28

Codez-le comme ceci:

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

Assurez-vous de NE PAS inclure les guillemets '' comme ci-dessous car ils provoqueront une exception.

pstmt.setString(1,"'%"+ notes + "%'");
Le loup de mariage
la source
1
Bien qu'il semble que quelqu'un ne se heurte pas à cette hypothèse, elle est en fait très valable, en particulier lorsque vous travaillez avec Oracle. Merci de l'avoir signalé!
asgs
5

nous pouvons le faire simplement, en utilisant la fonction SQL CONCATE.

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

cela fonctionne parfaitement pour mon cas.

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

Essayez ceci.

Faiz
la source
1
String fname = "Sam\u0025";

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

ps.setString(1, fname);
Ram Kumar
la source
2
Pourriez-vous élaborer la réponse plutôt que de simplement donner la réponse? Voir: 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
mahesh dhote
la source
il est dangereux, veuillez utiliser la déclaration préparée paramétrée.
Durgesh Kumar