【问题标题】:How to handle anyarray parameterized stored function in batch execution with jooq (postgresql)?如何使用jooq(postgresql)在批量执行中处理anyarray参数化存储函数?
【发布时间】:2016-11-22 04:28:06
【问题描述】:

我有如下的数据库架构:

CREATE FUNCTION public.some_fun(anyarray) RETURNS anyarray AS $$
  SELECT $1;
$$ LANGUAGE sql;

CREATE TABLE some_table (some_col int[]);

我在java中调用以下代码:

DSLContext ctx = ... // retrieve DSLcontext
Query query = ctx.insertInto(Tables.SOME_TABLE)
    .values((Field) someFun(new Integer[]{1}));
ctx.batch(query).execute();

代码产生异常:

org.postgresql.util.PSQLException: 错误: 无法确定 多态类型,因为输入的类型为“未知”

产生的查询是:

插入 "public"."some_table" ("some_col") 值 ("public"."some_fun"('{"1"}'))

事实证明,jooq 没有明确类型转换 {1} 数组,postgres 无法推断数组类型。

有趣的是,以下代码产生了相同的查询并且确实有效:

Query query = ctx.insertInto(Tables.SOME_TABLE)
    .values((Field) someFun(new Integer[]{1}));
query.execute();

我猜这个问题与 jdbc 如何处理批处理查询有关,除非 jooq 将不同的查询记录到它真正执行的内容。我使用以下代码找到了解决该问题的 hackish 解决方法:

Query query = ctx.insertInto(Tables.SOME_TABLE)
    .values(
        (Field) someFun(
            DSL.field(DSL.array(new Integer[]{1}).toString() + "::int[]")
        )
    );
ctx.batch(query).execute();

我还尝试通过将强制转换模式设置为 ALWAYS 来使 jooq 始终明确键入强制转换值,但它似乎不起作用:

ctx.renderContext().castMode(RenderContext.CastMode.ALWAYS);
Query query = ctx.insertInto(Tables.SOME_TABLE)
    .values((Field) someFun(new Integer[]{1}));
ctx.batch(query).execute();

我真的需要以手动丑陋的方式进行类型转换还是有更好的方法来处理这个?


更新

可以通过生成这样的类型转换字符串来减少转换过程中的挫败感:

String.format("::%s[]", DefaultDataType.getDataType(SQLDialect.POSTGRES, Integer[].class).getCastTypeName())

不过,这只是一种解决方法。

【问题讨论】:

    标签: java postgresql jooq


    【解决方案1】:

    从 jOOQ 3.8 开始,尚不支持 PostgreSQL 的 any、anyarray 和其他多态数据类型。对此有一个待处理的功能请求: https://github.com/jOOQ/jOOQ/issues/5479

    您的解决方法可能与现在一样好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-21
      • 2018-06-29
      • 2016-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-11
      • 1970-01-01
      相关资源
      最近更新 更多