You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将元组列表转为OID适配格式传入PostgreSQL IN查询

错误原因

jdbcConvertValue函数处理嵌套列表时,递归返回的是通用Object数组,PostgreSQL JDBC驱动无法直接将其识别为匹配行构造器(customerId, subcustomer)的复合类型数组,因此抛出类型转换异常。

解决方案

方案1:调整类型转换逻辑,生成合规二维数组(推荐)

你需要修改jdbcConvertValue中嵌套列表的处理分支,将List<List<String>>类型的参数转换为PostgreSQL可识别的二维text数组:

fun jdbcConvertValue(session: Session, v: Any?): Any? =
    when (v) {
      is Collection<*> -> {
        when (val firstElem = v.firstOrNull()) {
          null -> null
          is String -> session.connection.underlying.createArrayOf("text", v.toTypedArray())
          is Long -> session.connection.underlying.createArrayOf("bigint", v.toTypedArray())
          is Int -> session.connection.underlying.createArrayOf("bigint", v.toTypedArray())
          is UUID -> session.connection.underlying.createArrayOf("uuid", v.toTypedArray())
          is List<*> -> {
              // 适配文本类型二维数组,对应你的customerId、subcustomer均为text字段
              val innerFirst = firstElem.firstOrNull()
              if (innerFirst is String) {
                  val innerArrays = v.map { innerList ->
                      session.connection.underlying.createArrayOf("text", (innerList as List<*>).toTypedArray())
                  }.toTypedArray()
                  // PostgreSQL中text数组的类型标识为_text
                  session.connection.underlying.createArrayOf("_text", innerArrays)
              } else {
                  throw Exception("Unsupported nested array element type: ${innerFirst?.javaClass}")
              }
          }
          else -> throw Exception("You need to map your array type $firstElem ${firstElem.javaClass}")
        }
      }
      else -> v
    }

同时将SQL中的行匹配逻辑改为使用ANY关键字适配数组参数:

where (customerId, subcustomer) = ANY (:customerIdSubCustomerPairs) AND is_deleted = false

方案2:字段拼接匹配(快速应急)

如果不想修改转换逻辑,可以用业务中不会出现的分隔符拼接两个字段,转换为一维数组匹配:

  1. 参数构造逻辑修改:
"customerIdSubCustomerPairs" to customers.map { "${it["customerId"] as String}|${it["subCustomer"] as String}" }
  1. SQL条件修改:
where concat(customerId, '|', subcustomer) IN (:customerIdSubCustomerPairs) AND is_deleted = false

注意需确认|不会出现在customerId或subcustomer的业务值中,否则会出现匹配错误。

内容的提问来源于stack exchange,提问作者Leff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 09:36:06