在Jupyter Notebook运行Oracle PL/SQL脚本报错,求解决方法
解决Jupyter Notebook中Oracle PL/SQL块执行报错问题
问题说明
在Jupyter Notebook用%%sql魔法命令运行Oracle PL/SQL脚本时触发报错:
(cx_Oracle.DatabaseError) ORA-06550: line 8, column 165: PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
普通SQL语句(如SELECT、UPDATE)能正常执行,且该脚本在SQL Developer等客户端运行无异常,尝试增减末尾的;无法解决问题。
原代码块:
%%sql DECLARE BEGIN FOR record_item IN ( SELECT * FROM duplicated_records ) LOOP EXECUTE IMMEDIATE 'UPDATE table_name SET record_id ='|| record_item.original_record_id || ' WHERE record_id =' || record_item.duplicated_record_id; EXECUTE IMMEDIATE 'DELETE FROM records WHERE id ='|| record_item.duplicated_record_id; END LOOP; END
解决方案
问题根源在于%%sql魔法命令的默认语句分隔规则:它以分号;作为语句结束标记,但PL/SQL块内部包含多个分号,导致命令提前截断,无法识别完整的PL/SQL块。需要指定PL/SQL专用的终止符/来处理,具体调整如下:
- 在
%%sql后添加--delimiter /,告知魔法命令使用/作为语句终止符 - 在PL/SQL块末尾添加
/ - 规范语法,将
DECLARE BEGIN拆分为两行(非报错原因,但提升代码可读性)
修改后的代码:
%%sql --delimiter / DECLARE BEGIN FOR record_item IN ( SELECT * FROM duplicated_records ) LOOP EXECUTE IMMEDIATE 'UPDATE table_name SET record_id ='|| record_item.original_record_id || ' WHERE record_id =' || record_item.duplicated_record_id; EXECUTE IMMEDIATE 'DELETE FROM records WHERE id ='|| record_item.duplicated_record_id; END LOOP; END; /
原理解释
Oracle PL/SQL块通常用/作为整体终止符,而Jupyter的%%sql默认以分号分隔语句,会把块内的分号误判为语句结束,导致块被拆分执行,最终因代码不完整抛出"end-of-file"错误。指定--delimiter /后,魔法命令会将整个PL/SQL块视为单一语句处理,避免截断问题。
内容的提问来源于stack exchange,提问作者Undo 123123
相关产品推荐
相关产品推荐

