Мне не удается заставить драйвер AWS Athena JDBC работать с PreparedStatement и связанными переменными. Если я помещаю желаемое значение столбца непосредственно в строку SQL, он работает. Но если я использую заполнители '?' и я связываю переменные с сеттерами PreparedStatement, это не работает. Конечно, мы знаем, что нужно использовать второй способ (для кеширования, избегайте SQL-инъекций и т. д.).
Я использую драйвер JDBC AthenaJDBC42_2.0.2.jar. Я получаю следующую ошибку при попытке использовать заполнители '?' в строке SQL. Ошибка возникает, когда я получаю PreparedStatement из соединения JDBC. Он жалуется на то, что параметры не найдены. Но я установил их после в коде. Как я могу установить параметры перед получением PreparedStatement :-)?
java.sql.SQLException: [Simba][AthenaJDBC](100071) An error has been thrown from the AWS Athena client. SYNTAX_ERROR: line 1:1: Incorrect number of parameters: expected 1 but found 0
at com.simba.athena.athena.api.AJClient.executeQuery(Unknown Source)
at com.simba.athena.athena.dataengine.AJQueryExecutor.<init>(Unknown Source)
at com.simba.athena.athena.dataengine.AJDataEngine.prepare(Unknown Source)
at com.simba.athena.jdbc.common.SPreparedStatement.<init>(Unknown Source)
at com.simba.athena.jdbc.jdbc41.S41PreparedStatement.<init>(Unknown Source)
at com.simba.athena.jdbc.jdbc42.S42PreparedStatement.<init>(Unknown Source)
at com.simba.athena.jdbc.jdbc42.JDBC42ObjectFactory.createPreparedStatement(Unknown Source)
at com.simba.athena.athena.jdbc42.AJJDBC42ObjectFactory.createPreparedStatement(Unknown Source)
at com.simba.athena.jdbc.common.SConnection.prepareStatement(Unknown Source)
at com.simba.athena.jdbc.common.SConnection.prepareStatement(Unknown Source)
at ****************************************************
Caused by: com.simba.athena.support.exceptions.GeneralException: [Simba][AthenaJDBC](100071) An error has been thrown from the AWS Athena client. SYNTAX_ERROR: line 1:1: Incorrect number of parameters: expected 1 but found 0
... 37 more
Я делаю что-то неправильно ? Вот код
@Test
public void testWhichFails() throws SQLException {
try (Connection connection = athenaConnexion()) {
String sql = "select * from my_table where col = ? limit 10";
try (PreparedStatement ps = connection.prepareStatement(sql)) {
ps.setInt(1, 30);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
System.out.println("rs.getString(1) = " + rs.getString(1));
}
}
}
}
}
@Test
public void testWhichWorks() throws SQLException {
try (Connection connection = athenaConnexion()) {
String sql = "select * from my_table where col = 30 limit 10";
try (PreparedStatement ps = connection.prepareStatement(sql)) {
//ps.setInt(1, 30);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
System.out.println("rs.getString(1) = " + rs.getString(1));
}
}
}
}
}
@ Андрей Караиванский: SQL-инъекция - это проблема не только с обновлениями; доступ к данным, на которые не ссылается исходный запрос, также может стать серьезной проблемой. Кроме того, есть, например, Операторы CREATE TABLE, ALTER TABLE, DROP TABLE, которые действительно изменят материал. ИМО, это невероятно серьезная проблема.





В настоящее время я не думаю, что jar-файл Athena JDBC поддерживает подготовленные операторы с позиционными переменными. При использовании myBatis подготовленная переменная оператора #{variable} не работала, в то время как замена строки ${variable} работала.
select * from my_table where col = #{col} limit 10 не работалselect * from my_table where col = ${col} limit 10 работалЯ думаю, что ошибка возникает из-за того, что объект Athena SConnection не поддерживает переменные позиции, но, поскольку у меня нет источника, я не могу проверить.
Извините, что возродил это, но что это значит? Могу ли я сделать подобную технику в Hibernate?
Athena поддерживает только перечисленные здесь функции SQL Функции Athena SQL, которые, в свою очередь, основаны на Функции и операторы Presto версии 0.172 со следующим списком Ограничения Афины, связанные с SQL. Подготовленные операторы можно использовать в новой версии Presto Документация Presto. Однако Athena еще не поддерживает эту новую версию. Вы всегда можете написать в службу поддержки Athena, чтобы попросить добавить функцию PREPARE.
У меня была такая же проблема. Поскольку Athena предназначена для операций только для чтения, SQL-инъекция не должна быть проблемой. Поэтому вместо этого я просто использовал
String.format(). В вашем случае этоString.format("select * from my_table where col = %d limit 10", yourColValue).