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

Oracle 18c批量插入10万行报ORA-00933/ORA-00001错误如何解决

报错原因及解决方法

1. ORA-00933 SQL命令未正确结束

原因

Oracle默认不支持在单条请求中执行多条用分号拼接的独立INSERT语句,你把两条INSERT语句合并提交就会触发该报错。

解决方法

  • 若使用数据库客户端执行,逐行运行单条INSERT语句,或开启客户端的多语句执行权限
  • 若在代码中调用(如JDBC场景),可在数据库连接串添加参数allowMultiQueries=true,或改用JDBC批量执行API(addBatch+executeBatch)

2. ORA-00001 唯一约束违反

原因

该报错由你的INSERT ALL写法的两个问题共同导致:

  • Oracle的INSERT ALL语法中,序列NEXTVAL在整个语句执行周期内仅会生成一次,所有INTO子句取到的ID值完全相同,直接触发主键/唯一键重复
  • INSERT ALL尾部的SELECT语句返回多少行,整组INTO插入逻辑就会重复执行多少次,你写的SELECT 1 FROM schema_name.table_name如果来源表非空,会导致重复插入多轮相同数据,进一步触发约束报错

解决方法

INSERT ALL本身不适合搭配序列生成逐行唯一主键的场景,建议直接更换为更适合批量插入的写法,见下文。

Oracle 10万行量级批量插入的正确方案

根据你的数据来源不同,可选择以下最优方案:

方案1:数据来自其他Oracle表(性能最优)

直接使用INSERT INTO ... SELECT语法,这是Oracle官方推荐的批量插入方式,全程单语句执行,序列会为每一行生成独立值,不会出现重复问题。
示例代码:

INSERT INTO table_name (ID, code, date_t)
SELECT 
    schema_name.SEQ$table_name.NEXTVAL,
    数据源表.code字段,
    数据源表.date字段
FROM 数据源表
WHERE 数据过滤条件;

方案2:数据为程序/脚本生成的离散值

使用PL/SQL的FORALL批量绑定特性,性能比逐行INSERT高数十倍,适合10万行级别的数据插入。
示例代码:

DECLARE
    -- 定义存储批量数据的集合类型
    TYPE code_arr IS TABLE OF VARCHAR2(20) INDEX BY PLS_INTEGER;
    TYPE date_arr IS TABLE OF DATE INDEX BY PLS_INTEGER;
    v_codes code_arr;
    v_dates date_arr;
BEGIN
    -- 填充需要插入的10万条数据
    v_codes(1) := '232323232323';
    v_dates(1) := TO_DATE('2020-09-01','YYYY-MM-DD');
    v_codes(2) := '242424242424';
    v_dates(2) := TO_DATE('2020-09-01','YYYY-MM-DD');
    -- 循环填充剩余数据
    FOR i IN 3..100000 LOOP
        v_codes(i) := '你的自定义code值' || i;
        v_dates(i) := TO_DATE('2020-09-01','YYYY-MM-DD');
    END LOOP;

    -- 批量执行插入
    FORALL i IN 1..v_codes.COUNT
        INSERT INTO table_name (ID, code, date_t)
        VALUES (schema_name.SEQ$table_name.NEXTVAL, v_codes(i), v_dates(i));
    
    COMMIT;
END;
/

方案3:小批量离散值插入(Oracle 12c及以上版本支持)

12c以上版本支持多值行构造语法,写法更简洁,适合几百到几千行的小批量插入,不建议用于10万行级别(语句过长会影响解析性能)。
示例代码:

INSERT INTO table_name (ID, code, date_t)
SELECT schema_name.SEQ$table_name.NEXTVAL, code, date_t
FROM (
    VALUES 
        ('232323232323', TO_DATE('2020-09-01','YYYY-MM-DD')),
        ('242424242424', TO_DATE('2020-09-01','YYYY-MM-DD'))
        -- 剩余行按相同格式追加即可
) t(code, date_t);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 18:36:02