準備済みステートメントでの「like」ワイルドカードの使用


176

mysqlデータベースクエリを実行する準備済みステートメントを使用しています。そして、一種のキーワードに基づく検索機能を実装したいと思います。

そのため、LIKEキーワードを使用する必要があります。また、前に準備済みステートメントも使用しましLIKEたが、次のコードからどこに'keyword%'

私は直接にそれを使用することができますpstmt.setString(1, notes)ように(1, notes+"%")またはそのような何か。私はこれに関する多くの投稿をウェブ上で見ていますが、良い答えはどこにもありません。

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

回答:


281

準備済みステートメントの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 + "%");

18
+1 OPはそれをSQLで「設定」することもできます... LIKE '%' || ? || '%'が、これは柔軟性がはるかに低くなります。
ピルクロー

NON-CASE SENSITIVEモードでそれを行うにはどうすればよいですか?:)
Alpha Gabriel V. Timbol 2015

2
大文字と小文字を区別せずに使用するWHERE UPPER(?) LIKE UPPER(?)場合pstmt.setString(2, "%" + notes + "%")
Zig

1
@Alain:ありがとう。不思議なことに、これは世界が知っているすべてのRDBMSに適用されますか?おそらく'%' || ? || '%'、最初のコメントで述べたように、結局のところ、より良かったのでしょうか?今は実験する機会がありません。
BalusC、2015

2
@BalusCこれは、私のテストではMSSQL、Postgres、およびMySQLに適用されます。パラメータにされる文字列は、それ自体がデータと制御命令の混合として解釈されます。SQL連結は、解釈されて脆弱性が保持される前に発生します。IEEE Center for Secure Designは、データと制御命令厳密に分離し、信頼できないソースから受け取った制御命令は絶対に処理しないと述べています。
Alain O'Dea

28

次のようにコーディングします。

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

あなたがいることを確認しないでください、彼らは例外が発生しますと以下のように引用符「」を含んでいます。

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

1
誰かがこの仮定に遭遇しないように思えますが、それは特にOracleで作業する場合には実際に非常に有効です。指摘してくれてありがとう!
asgs

5

CONCATE SQL関数を使用して、これを簡単に行うことができます。

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

これは私の場合には完全に機能します。


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

これを試してみてください。



-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

安全ではありません。パラメータ化された準備済みステートメントを使用してください。
Durgesh Kumar
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.