【问题标题】:AWS Athena JDBC PreparedStatementAWS Athena JDBC PreparedStatement
【发布时间】:2018-11-06 22:06:06
【问题描述】:

我无法使 AWS Athena JDBC 驱动程序与 PreparedStatement 和绑定变量一起工作。如果我将所需的列值直接放在 SQL 字符串中,它就可以工作。但是如果我使用占位符'?我将变量与 PreparedStatement 的设置器绑定,它不起作用。当然,我们知道我们必须使用第二种方式(用于缓存,避免 SQL 注入等)。

我使用 JDBC 驱动程序 AthenaJDBC42_2.0.2.jar。尝试使用占位符 '?' 时出现以下错误在 SQL 字符串中。当我从 JDBC 连接获取 PreparedStatement 时,会引发错误。它抱怨找不到参数。但是我在代码中设置了它们。在获取 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));
                }
            }
        }
    }
}

【问题讨论】:

  • 我也遇到了同样的问题。由于 Athena 用于只读操作,因此 SQL 注入应该不是问题。所以我只使用了String.format()。在你的情况下,它是String.format("select * from my_table where col = %d limit 10", yourColValue)
  • @Andrii Karaivanskyi:SQL 注入不仅是更新问题;访问原始查询未引用的数据也可能是一个严重的问题。此外,还有例如CREATE TABLE、ALTER TABLE、DROP TABLE 语句确实会改变一些东西。这是 IMO 一个非常严重的问题。

标签: amazon-web-services jdbc amazon-athena


【解决方案1】:

Athena 仅支持此处列出的 SQL 函数 Athena SQL functions,而这些函数又基于 Functions and Operators Presto version 0.172 以及以下 Athena's SQL related limitations 列表。新版 Presto Presto Documentation 可以使用预处理语句。但是,Athena 还不支持这个新版本。您可以随时写信给 Athena 支持团队,要求添加 PREPARE 功能。

【讨论】:

    【解决方案2】:

    目前,我认为 Athena JDBC jar 不支持带有位置变量的预处理语句。在使用 myBatis 时,预处理语句变量 #{variable} 不起作用,而字符串替换 ${variable} 起作用。

    • select * from my_table where col = #{col} limit 10 无效
    • select * from my_table where col = ${col} limit 10 确实有效

    我认为出现错误是因为Athena SConnection 对象不支持位置变量,但由于我没有源,无法验证。

    【讨论】:

    • 抱歉恢复这个,但这是什么意思?我可以在 Hibernate 中做类似的技术吗?
    猜你喜欢
    • 2018-08-03
    • 1970-01-01
    • 2013-11-14
    • 2019-05-12
    • 1970-01-01
    • 1970-01-01
    • 2018-01-28
    • 1970-01-01
    • 2015-07-03
    相关资源
    最近更新 更多