繁体   English   中英

Spring - JdbcTemplate - 使用 CTE 和枚举行查询

[英]Spring - JdbcTemplate - query with CTE and enumerated rows

我正在尝试创建一个使用 CTE 结构的查询。 查询如下所示:

with data (a, b, c) as (
    values  ('a1', 'b1', 'c1'), ('a2', 'b2', 'c2')
)
select * from data

这个查询当然是简化的,为了保持这里的重点。

以下效果很好:

@Component
public class QueryTest {
    private NamedParameterJdbcTemplate template;

    @Autowired
    public QueryTest(final DataSource source) {
        template = new NamedParameterJdbcTemplate(source);
    }

    @Scheduled(fixedRate = 1000)
    public void test() {
        MapSqlParameterSource p = new MapSqlParameterSource()
                .addValue("data", Arrays.asList(
                        new Object[]{"a1", "b1", "c1"},
                        new Object[]{"a2", "b2", "c2"}));
        System.out.println(template.query("with data (a, b, c) as (values :data) select * from data", p, (set, index) -> new Object()));
    }
}

但是,如果我的data命名参数中只有一行,则它不起作用:

@Component
public class QueryTest {
    private NamedParameterJdbcTemplate template;

    @Autowired
    public QueryTest(final DataSource source) {
        template = new NamedParameterJdbcTemplate(source);
    }

    @Scheduled(fixedRate = 1000)
    public void test() {
        MapSqlParameterSource p = new MapSqlParameterSource()
                .addValue("data", Arrays.asList(
                        new Object[]{"a1", "b1", "c1"}));
        System.out.println(template.query("with data (a, b, c) as (values :data) select * from data", p, (set, index) -> new Object()));
    }
}

我收到以下错误:

Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"
  Position: 32
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2284) ~[postgresql-9.4.1208.jar:9.4.1208]
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2003) ~[postgresql-9.4.1208.jar:9.4.1208]
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:200) ~[postgresql-9.4.1208.jar:9.4.1208]
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:424) ~[postgresql-9.4.1208.jar:9.4.1208]
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:161) ~[postgresql-9.4.1208.jar:9.4.1208]
    at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:114) ~[postgresql-9.4.1208.jar:9.4.1208]
    at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52) ~[HikariCP-2.5.1.jar:?]
    at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java) ~[HikariCP-2.5.1.jar:?]
    at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:688) ~[spring-jdbc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:629) ~[spring-jdbc-4.2.5.RELEASE.jar:4.2.5.RELEASE]

知道这里出了什么问题吗? 有没有更好的方法来执行这些查询?

更新

我启用了 postgres 登录,看起来第一个查询被解析为:

with data (a, b, c) as (values ($1, $2, $3), ($4, $5, $6)) select * from data

但第二个被解决为:

with data (a, b, c) as (values $1, $2, $3) select * from data

看起来周围的括号丢失了?

问题在于您使用Arrays.asList 当您传入多个对象数组时,您会得到一个对象数组列表。 如果您只传入单个对象数组,您将获得数组内容的列表,而不是单个对象数组的列表。 它将数组解释为单独的可变参数而不是一个参数。 如果你打印出Arrays.asList(new Object[]{"a1", "b1", "c1"})给你的内容,它看起来像:[a1, b1, c1]。

对于单个数组用例,请尝试使用Collections.singletonList创建您的 List,或者创建一个ArrayList ,然后使用add方法添加您的数据值。

MapSqlParameterSource p = new MapSqlParameterSource() .addValue("data", Collections.singletonList(new Object[]{"a1", "b1", "c1"}));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM