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

使用FOR循环随机从base-info插入数据至person表遇ORA-06550错误

PL/SQL批量插入随机数据报错修复

你需要从已有的base-info表(包含name、family、gen、city、age、job、id字段)通过FOR循环和INSERT INTO VALUES语法,随机抽取数据插入新的person表,但执行代码时遇到了ORA-06550等语法错误。

原代码

Declare
  c1 number(3):=0;
  c2 number(3):=0;
 begin 
 for c1 in 1..200 loop
 for c2 in 1..200 loop 
    insert into person p 
    (
     id, 
     name, 
     family,
     gen,
     job,
     city, 
     age
    )
 values 
   ( 
   seq_person_id,
   (select b.name from base_info b where b.id=c1) ,
   ( SELECT * FROM  (SELECT b.family  FROM   base_info b ORDER BY DBMS_RANDOM.RANDOM)  WHERE  rownum=1;) ,
   (select b.gen from base_info b where b.id=c1) ,
   (SELECT * FROM  (SELECT b.job  FROM   base_info b ORDER BY DBMS_RANDOM.RANDOM) WHERE  rownum=1;) ,
   (SELECT * FROM  (SELECT b.city  FROM   base_info b ORDER BY DBMS_RANDOM.RANDOM) WHERE  rownum=1;) , 
   (SELECT * FROM  (SELECT b.age  FROM   base_info b ORDER BY DBMS_RANDOM.RANDOM) WHERE  rownum=1;)
   ); 
  end loop;
  end loop; 
end; 


 select t.*, t.rowid from PERSON t ;

报错信息(翻译后)

ORA-06550: 第7行, 第6列:
PL/SQL: ORA-00921: 意外的SQL命令结束
ORA-06550: 第7行, 第6列:
PL/SQL: SQL语句被忽略
ORA-06550: 第18行, 第112列:
PLS-00103: 遇到符号 ")",需要下列之一:
( begin case declare end exit for goto if loop mod null
pragma raise return select update while with
<<
continue close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge pipe purge
json_exists json_value json_query json_object json_array
ORA-06550: 第20行, 第106列:
PLS-00103: 遇到符号 ";",需要下列之一:
) * & - + / at mod remainder rem with <指数 ()> and
or group having intersect minus order start union where
connect || multiset
符号 ";" 已被忽略。
ORA-06550: 第21行, 第107列:
PLS-00103: 遇到符号 ";",需要下列之一:
) * & - + / at mod remainder rem with <指数 (
)> and
or group having intersect minus order start union where
connect || multiset
符号 ";" 已被忽略。
ORA-06550: 第22行, 第106列:
PLS-00103: 遇到符号 ";",需要下列之一:
) * & - + / at mod remainder rem with <指数 (**)> and
or group having intersect minus order start union where
connect || multiset

错误分析

  • INSERT语句表别名冗余:insert into person p中的别名p完全多余,INSERT语句不需要给目标表加别名,这直接触发了ORA-00921错误。
  • 子查询末尾非法分号:所有随机抽取字段的子查询(比如(SELECT * FROM ... WHERE rownum=1;))末尾的分号是语法错误,子查询内部不能使用分号,导致了PLS-00103报错。
  • 序列调用方式错误:直接写seq_person_id无法获取序列的下一个值,必须使用seq_person_id.NEXTVAL。
  • 未使用的循环变量:内层循环c2在代码中没有被任何逻辑引用,属于冗余代码,要么删除要么合理利用。

修正后的代码

DECLARE
  c1 NUMBER(3) := 0;
BEGIN 
  FOR c1 IN 1..200 LOOP
    INSERT INTO person 
    (
      id, 
      name, 
      family,
      gen,
      job,
      city, 
      age
    )
    VALUES 
    ( 
      seq_person_id.NEXTVAL,
      (SELECT b.name FROM base_info b WHERE b.id = c1),
      (SELECT * FROM (SELECT b.family FROM base_info b ORDER BY DBMS_RANDOM.RANDOM) WHERE rownum = 1),
      (SELECT b.gen FROM base_info b WHERE b.id = c1),
      (SELECT * FROM (SELECT b.job FROM base_info b ORDER BY DBMS_RANDOM.RANDOM) WHERE rownum = 1),
      (SELECT * FROM (SELECT b.city FROM base_info b ORDER BY DBMS_RANDOM.RANDOM) WHERE rownum = 1),
      (SELECT * FROM (SELECT b.age FROM base_info b ORDER BY DBMS_RANDOM.RANDOM) WHERE rownum = 1)
    ); 
  END LOOP;
  COMMIT; -- 建议添加提交语句,确保数据持久化
END;
/

-- 验证插入结果
SELECT t.*, t.rowid FROM PERSON t;

补充说明

  1. 如果需要生成更多数据,可以保留c2循环,但要确保变量被合理使用(比如控制插入次数)。
  2. 子查询中的SELECT *可以替换为具体字段名(如SELECT b.family),让代码更清晰,避免潜在的字段不匹配问题。
  3. 添加COMMIT语句是为了避免PL/SQL块执行后数据停留在事务中未提交。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 14:01:17