在预准备语句中使用“like”通配符

Using "like" wildcard in prepared statement

提问人:ssn 提问时间:11/24/2011 最后编辑:ssn 更新时间:10/7/2020 访问量:224411

问:

我正在使用准备好的语句来执行mysql数据库查询。我想实现基于各种关键字的搜索功能。

为此,我需要使用关键字,我知道的太多了。而且我以前也使用过准备好的语句,但我不知道如何使用它,因为从下面的代码中,我将在哪里添加?LIKELIKE'keyword%'

我可以直接在as或类似的东西中使用它吗?我在网上看到很多关于这个的帖子,但在任何地方都没有好的答案。pstmt.setString(1, notes)(1, notes+"%")

PreparedStatement pstmt = con.prepareStatement(
      "SELECT * FROM analysis WHERE notes like ?");
pstmt.setString(1, notes);
ResultSet rs = pstmt.executeQuery();
java mysql jdbc 准备语句

评论


答:

325赞 BalusC 11/24/2011 #1

您需要在值本身中设置它,而不是在准备好的语句 SQL 字符串中设置它。

因此,这应该适用于前缀匹配:

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

或后缀匹配:

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

或全局匹配:

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

评论

22赞 pilcrow 11/24/2011
+1 OP 可以在 SQL 中“设置”它——比如 by 或类似——但这要灵活得多。... LIKE '%' || ? || '%'
2赞 Zig 11/21/2015
不区分大小写,使用时仍可使用WHERE UPPER(?) LIKE UPPER(?)pstmt.setString(2, "%" + notes + "%")
1赞 BalusC 12/24/2015
@Alain:谢谢。只是想知道,这是否适用于世界上已知的所有 RDBMS?也许正如第一条评论中提到的,毕竟更好?我现在没有机会做实验。'%' || ? || '%'
2赞 Alain O'Dea 12/24/2015
@BalusC这适用于我的测试中的 MSSQL、Postgres 和 MySQL。被制成参数的 String 本身被解释为数据和控制指令的混合。SQL 串联在解释之前发生,并保留漏洞。IEEE安全设计中心表示,要严格分离数据和控制指令,切勿处理来自不受信任来源的控制指令
1赞 dpelisek 2/26/2020
请问你为什么要转义“[”字符?
37赞 The Wedding Wolf 3/14/2015 #2

像这样编码:

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

确保您不要像下面那样包含引号 ' ',因为它们会导致异常。

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

评论

2赞 asgs 6/15/2015
虽然听起来有人不会遇到这个假设,但它实际上非常有效,尤其是在与 Oracle 合作时。感谢您的指出!
7赞 Faiz 3/11/2016 #3
PreparedStatement ps = cn.prepareStatement("Select * from Users where User_FirstName LIKE ?");
ps.setString(1, name + '%');

试试这个。

0赞 Ram Kumar 11/15/2017 #4
String fname = "Sam\u0025";

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

ps.setString(1, fname);

评论

3赞 Edwin 11/15/2017
你能详细说明答案而不仅仅是给出答案吗?请参见:stackoverflow.com/help/how-to-answer
-21赞 mahesh dhote 10/5/2018 #5
String query="select * from test1 where "+selected+" like '%"+SelectedStr+"%';";


PreparedStatement preparedStatement=con.prepareStatement(query);


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

评论

1赞 Durgesh Kumar 9/23/2019
这是不安全的,请使用参数化的准备声明。
0赞 Rafs 8/19/2022
jsparrow.github.io/rules/......
47赞 Basharat Ali 11/21/2019 #6

我们可以使用 SQL 函数。CONCAT

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

这非常适合我的情况。

评论

2赞 shooma 1/14/2022
.. notes like '%' || ? || '%'也有效
0赞 David Tonhofer 8/28/2023
可悲的是,在 H2 2.2.220 中不起作用。如图所示,在对准备好的语句给出的参数中,A 被解释为另一个通配符,而不是应转义的字符。有关参数的语法,请参见 Like Predicate Right Hand Side%LIKE