問題は、データ型がCHAR(9)であり、「Waterloo」の文字数が8文字しかないことだと思います。これにより、期待される結果(LIKEおよび%)が返されると思います。または、不足しているスペースを追加します。
String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL LIKE ? ";
PreparedStatement prepStmt = conn.prepareStatement(sql);
prepStmt.setString(1, "Waterloo%");
ResultSet rs = prepStmt.executeQuery();
文字列の長さが柔軟な場合は、charの代わりにvarcharを使用するのが最善の方法です。そうすれば、PreparedStatementは期待どおりに機能します。
回避策は、Oracle固有のsetFixedCHARメソッドを使用することです(ただし、可能であれば、データ型をvarcharに変更することをお勧めします)。
以下は、OracleのPreparedStatementJavaDocからのものです。
データベース内のCHARデータは、列幅に埋め込まれます。これにより、setCHAR()メソッドを使用して文字データをSELECTステートメントのWHERE句にバインドする際の制限が発生します。SELECTステートメントで一致を生成するには、WHERE句の文字データも列幅にパディングする必要があります。列幅がわからない場合、これは特に厄介です。
setFixedCHAR()はこれを修正します。このメソッドは、埋め込みなしの比較を実行します。
注:
- setFixedCHAR()メソッドを使用するには、プリペアドステートメントオブジェクトをOraclePreparedStatementにキャストすることを忘れないでください。
- INSERTステートメントにsetFixedCHAR()を使用する必要はありません。データベースは、データを挿入するときに、常に自動的に列幅にデータを埋め込みます。
次の例は、setString()、setCHAR()、およびsetFixedCHAR()メソッドの違いを示しています。
// Schema is : create table my_table (col1 char(10));
// insert into my_table values ('JDBC');
PreparedStatement pstmt = conn.prepareStatement
("select count() from my_table where col1 = ?");
ResultSet rs;
pstmt.setString (1, "JDBC"); // Set the Bind Value
rs = pstmt.executeQuery(); // This does not match any row
// ... do something with rs
CHAR ch = new CHAR("JDBC ", null);
((OraclePreparedStatement)pstmt).setCHAR(1, ch); // Pad it to 10 bytes
rs = pstmt.executeQuery(); // This matches one row
// ... do something with rs
((OraclePreparedStatement)pstmt).setFixedCHAR(1, "JDBC");
rs = pstmt.executeQuery(); // This matches one row
// ... do something with rs