Параметризованный запрос Oracle SQL в Java?
-
27-09-2019 - |
Вопрос
Я пытался выяснить, почему следующий код не генерирует никаких данных в моих результатах:
String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL = ? ";
PreparedStatement prepStmt = conn.prepareStatement(sql);
prepStmt.setString(1, "Waterloo");
ResultSet rs = prepStmt.executeQuery();
С другой стороны, следующее работает должным образом:
String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL = 'Waterloo' ";
PreparedStatement prepStmt = conn.prepareStatement(sql);
ResultSet rs = prepStmt.executeQuery();
Тип данных для школы является CHAR (9 байт). Вместо того, чтобы SetString я также пробовал:
String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL = ? ";
PreparedStatement prepStmt = conn.prepareStatement(sql);
String school = "Waterloo";
Reader reader = new CharArrayReader(school.toCharArray());
prepStmt.setCharacterStream(1, reader, 9);
prepStmt.setString(1, "Waterloo");
ResultSet rs = prepStmt.executeQuery();
Я полностью застрял на том, что расследовать дальше; Отладчик Eclipse говорит, что запрос SQL не меняется даже после SetString или SetCharacterTream. Я не уверен, что это потому, что параметры настройки не работают, или если отладчик просто не может забрать изменения в HoneyStatement.
Любая помощь будет очень оценена, спасибо!
Решение
Я думаю, что проблема в том, что ваш DataType является Char (9) и «Waterloo» имеет только 8 символов. Я предполагаю, что это вернет ожидаемые результаты (например и%). Или добавьте недостающее место.
String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL LIKE ? ";
PreparedStatement prepStmt = conn.prepareStatement(sql);
prepStmt.setString(1, "Waterloo%");
ResultSet rs = prepStmt.executeQuery();
Лучший способ, чтобы использовать varchar вместо char, если ваши строки имеют гибкую длину. Тогда готовность будет работать, как ожидалось.
Обходной путь заключается в том, чтобы использовать метод SetFixedCHADCHADCHAL SETFIXEDCHADCHAL (но лучше изменить DataType на varchar).
Ниже приведен из Aracle's Honeedstatement Javadoc:
Данные CHAR в базе данных дополнены к ширине столбца. Это приводит к ограничению с использованием метода SetChar () для привязки данных символов в предложение о том, где указанное оператора выбора - символьные данные в пункте «Таким» также должны быть дополнены к ширине столбца, чтобы создать совпадение в списке «Выбор». Это особенно неприятно, если вы не знаете ширину столбца.
setfixedchar () исправляет это. Этот метод выполняет недвижимое сравнение.
Примечания:
- Не забудьте отбросить свой подготовленный объект оператора в OraclePReparedstatement для использования метода setfixedchar ().
- Нет необходимости использовать 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