使用FOR循环随机从base-info插入数据至person表遇ORA-06550错误
你需要从已有的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;
补充说明
- 如果需要生成更多数据,可以保留
c2循环,但要确保变量被合理使用(比如控制插入次数)。 - 子查询中的
SELECT *可以替换为具体字段名(如SELECT b.family),让代码更清晰,避免潜在的字段不匹配问题。 - 添加
COMMIT语句是为了避免PL/SQL块执行后数据停留在事务中未提交。
内容的提问来源于stack exchange,提问作者Hossein GH

