【问题标题】:Error caused by bad sql grammar, but it works perfect in database错误的sql语法导致的错误,但它在数据库中完美运行
【发布时间】:2021-12-25 02:25:01
【问题描述】:

我在存储库中的方法中有这段 SQL 代码。它是根据给定的 id 查找项目的总价格。这个价格应该返回一个 BigDecimel 总价,但它给了我一个错误的 SQL 语法错误。当我将此 SQL 放入我的 MariaDB (phpMyAdmin) 时,它运行良好。为什么这不起作用?

我在 Java Spring 存储库中使用它。

@Override
public BigDecimal vindTotalePrijsByIds(Set<Long> ids) {
    var sql = "select sum(prijs) from films where id in (" +
            "?,".repeat(ids.size()-1) +
            "?)";
    return template.queryForObject(sql, BigDecimal.class, ids);
}

这些是列:(数据库没有问题,适用于所有其他语句)。但是你可以看到我采用了正确的价值观。

id |genreId |标题 |沃拉德 | gereserveerd|prijs

我收到此错误。

org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback;糟糕的 SQL 语法 [select sum(prijs) from id 在 (?,?)] 中的电影;嵌套异常是 java.sql.SQLException: 没有为参数 2 指定值

我的 SQL 语句有什么问题? 要回答这个问题来验证是有两个。是的,我通过测试运行它(查找 id 的公式):

    @Test
    void findtotaleprijsbyids() {
        long idEen = idVanTestFilm();
        long idTwee = idVanTestFilmTwee();
        assertThat(filmRepository.vindTotalePrijsByIds(Set.of(idTwee, idEen))).isEqualByComparingTo(BigDecimal.TEN);
    }

在我的数据库中插入这个,insertFilm.sql (你可以假设我的测试一切都正确)

insert into films (genreId, titel, voorraad, gereserveerd, prijs) values (8, 'testFilm', 5, 0, 5.00),
                                                                         (8, 'testFilmTwee', 5, 0, 5.00);

所以我知道它有 2 个参数。但所以也许我执行错了。现在朝那个方向看。

【问题讨论】:

  • 你的SQL语句本身没有问题,你执行它的方式有问题。 Set ids 被视为单个参数。 JdbcTemplate.queryForObject(String, Class&lt;?&gt;, Object...):最后一个是可变参数,所以需要将集合转换为数组。

标签: java sql spring


【解决方案1】:

被调用方法的签名是queryForObject(String query, Class&lt;T&gt; requiredType, Object... args)。因此,Set&lt;Long&gt; 被解释为单个参数,而不是多个参数。如果我们要将Set转化为数组,可以调用Set::toArray

return template.queryForObject(sql, BigDecimal.class, ids.toArray());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-01
    • 2016-11-28
    • 1970-01-01
    • 2013-07-25
    • 2017-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多