Невозможно использовать запрос LIKE в JDBC PreparedStatement?
Код запроса и запрос:
ps = conn.prepareStatement("select instance_id, ? from eam_measurement where resource_id in (select RESOURCE_ID from eam_res_grp_res_map where resource_group_id = ?) and DSN like '?' order by 2");
ps.setString(1,"SUBSTR(DSN,27,16)");
ps.setInt(2,defaultWasGroup);
ps.setString(3,"%Module=jvmRuntimeModule:freeMemory%");
rs = ps.executeQuery();
while (rs.next()) { bla blah blah blah ...
Возвращает пустой ResultSet
.
Через базовую отладку я обнаружил ее третье связывание, которое является проблемой i.e.
DSN like '?'
Я пробовал всевозможные вариации, наиболее разумные из которых, казалось, использовались:
DSN like concat('%',?,'%')
но это не работает, поскольку я пропускаю '
по обе стороны от конкатенированной строки, поэтому я пытаюсь:
DSN like ' concat('%',Module=P_STAG_JDBC01:poolSize,'%') ' order by 2
но я просто не могу найти способ получить их в этих работах.
Что мне не хватает?
Ответы
Ответ 1
Во-первых, заполнители PreparedStatement
(те ?
вещи) предназначены для значений столбца, а не для имен таблиц, имен столбцов, функций/предложений SQL и т.д. Лучше использовать String#format()
. Во-вторых, вы должны не цитировать заполнители, такие как '?'
, это будет только искажать окончательный запрос. Установки PreparedStatement
уже выполняют задание кавычек (и экранирование) для вас.
Здесь фиксированный SQL:
private static final String SQL = "select instance_id, %s from eam_measurement"
+ " where resource_id in (select RESOURCE_ID from eam_res_grp_res_map where"
+ " resource_group_id = ?) and DSN like ? order by 2");
Вот как это использовать:
String sql = String.format(SQL, "SUBSTR(DSN,27,16)"); // This replaces the %s.
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, defaultWasGroup);
preparedStatement.setString(2, "%Module=jvmRuntimeModule:freeMemory%");
См. также:
Ответ 2
Если вы хотите использовать LIKE в подготовленном операторе, а также хотите использовать% символов в LIKE;
напишите подготовленный оператор как обычно ".... LIKE?...." и при назначении значения параметра знаку вопроса используйте
ps.setString(1, "%" + "your string value" + "%");
Это будет работать:)
Ответ 3
В вашем заявлении есть две проблемы. Вы должны понимать, как работают переменные привязки. Запрос не обрабатывается путем замены символов ?
вашими параметрами. Вместо этого оператор компилируется с помощью заполнителей, а затем во время выполнения фактические значения параметров передаются в БД.
Другими словами, вы анализируете следующий запрос:
SELECT instance_id, :p1
FROM eam_measurement
WHERE resource_id IN (SELECT RESOURCE_ID
FROM eam_res_grp_res_map
WHERE resource_group_id = :p2)
AND DSN LIKE '?'
ORDER BY 2
Я уверен, что последний параметр будет проигнорирован, потому что он находится в разделительной символьной строке. Даже если он не игнорируется, не имеет смысла иметь '
символов вокруг, потому что Oracle не будет связывать параметр в строке (я удивлен, что он не вызвал каких-либо ошибок, вы поймаете исключения?).
Теперь, если вы замените DNS LIKE '?'
на DSN LIKE ?
и привяжите "%Module=jvmRuntimeModule:freeMemory%"
, это будет иметь смысл и должно вернуть правильные строки.
У вас все еще есть проблема с вашим первым параметром, он не будет делать то, что вы ожидаете, i-e запрос, который будет выполнен, будет эквивалентен следующему запросу:
SELECT instance_id, 'SUBSTR(DSN,27,16)'
FROM ...
что совсем не совпадает с
SELECT instance_id, SUBSTR(DSN,27,16)
FROM ...
Я бы предложил разбор (= prepareStatement) следующий запрос, если вы ожидаете, что SUBSTR будет динамическим:
SELECT instance_id, SUBSTR(DSN,?,?)
FROM eam_measurement
WHERE resource_id IN (SELECT RESOURCE_ID
FROM eam_res_grp_res_map
WHERE resource_group_id = ?)
AND DSN LIKE ?
ORDER BY 2
Ответ 4
Опустите '
вокруг ?
. Без '
, ?
является заполнителем для параметра. С ним это строка SQL (то есть такая же, как "?"
в Java).
Затем вы должны конкатенировать строку на стороне Java; вы не можете передавать SQL-функции в качестве параметров для запросов; только базовые значения (например, string, integer и т.д.), потому что драйвер JDBC преобразует этот параметр в тип SQL, который ожидает база данных, и не может выполнять SQL-функции на этом этапе.
Ответ 5
Вы можете попробовать:
String beforeAndAfter = "%" + yourVariable + "%";
Ответ 6
Это должно работать:
"\'" + "?" + "\'"
Ответ 7
PreparedStatement ps = con.prepareStatement(
"select columname from tablename where LOWER(columnname) LIKE LOWER('"+var+"%')");
Здесь var
- это переменная, в которой сохраняется значение, которое нужно искать...