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

如何将多个列表作为值插入AnyLogic数据库表?

错误原因

你的写法核心问题是搞反了values()方法的参数语义:

  • jOOQ的insertInto(...).values()方法,每一组传入的参数,对应数据库表中一行的所有列值。
  • 你单插list1不报错是特殊适配逻辑:当插入列只有1个时,传入List会被自动识别为批量插入的多行单值,也就是把List里的每个元素拆成单独一行,刚好匹配1列的要求。
  • 多列场景下你直接传4个List对象,框架会认为你要插入1行数据,这行需要4个标量值(字符串、浮点数),但你实际传了4个集合,解析时直接判定传入值的数量、类型和声明的列不匹配,就抛出"row column count mismatch"错误。

另外你当前的实现还有个隐含风险:就算写法改对了,如果四个查询返回的列表长度不一致,或者相同索引位置的数据不属于同一个零件,会直接出现数据错位的脏数据问题。

正确实现方案

根据你的场景选一种即可:

方案1:内存组装行数据批量插入

适合四个表没有显式关联字段、只能靠查询返回顺序对齐数据的场景,必须先做长度校验:

List<String> partIdList = selectFrom(identifiers).list(identifiers.part_id);
List<Double> cfsTimeList = selectFrom(cfs_time).list(cfs_time.cfs_time);
List<Double> deburrTimeList = selectFrom(deburr_time).list(deburr_time.deburr_time);
List<Double> drillTimeList = selectFrom(drill_time).list(drill_time.drill_time);

// 强制校验行数一致,避免错行
if (partIdList.size() != cfsTimeList.size() 
    || cfsTimeList.size() != deburrTimeList.size() 
    || deburrTimeList.size() != drillTimeList.size()) {
    throw new IllegalStateException("各工序表返回数据行数不一致,无法生成汇总记录");
}

var insertQuery = insertInto(results)
        .columns(results.part_id, results.cfs_time, results.deburr_time, results.drill_time);

// 按索引逐行组装每行的4个字段值
for (int i = 0; i < partIdList.size(); i++) {
    insertQuery.values(
            partIdList.get(i),
            cfsTimeList.get(i),
            deburrTimeList.get(i),
            drillTimeList.get(i)
    );
}

insertQuery.execute();

方案2:直接执行insert-select关联插入(推荐)

不需要把数据查到应用内存,直接在数据库层面完成关联查询+插入,性能更好,也不会出现内存里列表长度不匹配的问题。如果四个表都有part_id作为关联键,直接用这个写法:

insertInto(results)
.columns(results.part_id, results.cfs_time, results.deburr_time, results.drill_time)
.select(
        select(
                identifiers.part_id,
                cfs_time.cfs_time,
                deburr_time.deburr_time,
                drill_time.drill_time
        )
        .from(identifiers)
        .innerJoin(cfs_time).on(identifiers.part_id.eq(cfs_time.part_id))
        .innerJoin(deburr_time).on(identifiers.part_id.eq(deburr_time.part_id))
        .innerJoin(drill_time).on(identifiers.part_id.eq(drill_time.part_id))
)
.execute();

如果四个表没有公共关联键,是靠写入顺序一一对应的,可以用数据库的ROW_NUMBER()开窗函数给每个查询结果加行号,再按行号关联即可。

补充说明
  • 不要尝试给values()传多个单列列表实现批量插入,jOOQ没有提供按列传值的API,所有批量插入都需要按行组织字段值
  • 如果模型销毁阶段需要汇总的数据量很大,优先选insert-select方案,比内存捞数据再插入的性能高几个量级
  • 没有关联键靠行顺序对齐的场景,必须加长度校验,不要假设四个查询返回的行数永远一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 22:01:09