使用TypeORM查询构建器向Oracle批量插入数据失败求助
解决TypeORM QueryBuilder向Oracle批量插入数据的ORA-00928错误
Oracle不支持标准SQL的INSERT INTO table (cols) VALUES (v1),(v2)多行插入语法,这是触发ORA-00928: missing SELECT keyword错误的核心原因。要在保持QueryBuilder多数据库兼容的前提下实现批量插入,可改用**INSERT ... SELECT ... UNION ALL**的方式构造查询。
解决方案代码
const result = [ { agent: 'linux', bytes: 12, responsible_request_id: '1234-4567-7890-0123' }, { agent: 'windows', bytes: 200, responsible_request_id: '1234-4567-7890-0123' }, ]; // 为每一行数据构造带参数绑定的子查询,避免SQL注入 const selectSubQueries = result.map((item, idx) => connection.createQueryBuilder() .select(`:agent_${idx}`, 'agent') .addSelect(`:bytes_${idx}`, 'bytes') .addSelect(`:req_id_${idx}`, 'responsible_request_id') .setParameters({ [`agent_${idx}`]: item.agent, [`bytes_${idx}`]: item.bytes, [`req_id_${idx}`]: item.responsible_request_id }) ); // 合并子查询并执行批量插入 const insertQuery = connection .createQueryBuilder(queryRunner) .insert() .into('STORAGE_AGENT.testcollection') .select(selectSubQueries[0]); // 用UNION ALL拼接所有子查询 for (let i = 1; i < selectSubQueries.length; i++) { insertQuery.unionAll(selectSubQueries[i]); } await insertQuery.exec();
原理说明
- Oracle仅支持通过
SELECT语句提供插入数据源,因此将每一行数据转换为独立的SELECT子查询 - 使用
UNION ALL合并所有子查询,形成完整的插入数据集 - 通过参数绑定传递数据,避免SQL注入风险
- 该写法可兼容MySQL、PostgreSQL等主流数据库,满足多数据库兼容需求
内容的提问来源于stack exchange,提问作者Neel Thakkar
相关产品推荐
相关产品推荐

