配置含函数与存储过程的SQL包时遇PLS-00103错误求助
解决PL/SQL包编译错误的问题
看起来你在写PL/SQL包的时候踩了几个常见的语法坑,我帮你梳理下错误点,然后给出修正后的代码。
先对应你遇到的编译错误拆解问题:
- PLS-00103: 遇到符号 "FUNCTION",期望以下之一: is authid...:包规范开头缺少
IS/AS关键字,正确的包声明结构应该是CREATE OR REPLACE PACKAGE 包名 IS ... END; - PLS-00103: 遇到符号 "NUMBER",期望以下之一: (:函数声明的返回类型位置错误,同时参数格式不规范
- PLS-00103: 遇到符号 "CREATE",期望以下之一: is as...:包体里的子程序(函数/存储过程)不能单独加
CREATE OR REPLACE,直接定义即可
1. 包规范的修正
你的包规范存在几个核心问题:缺少连接关键字、函数返回类型错误、子程序签名不一致、声明结尾缺分号,修正后的代码如下:
CREATE OR REPLACE PACKAGE e_con_pack IS -- 修正函数名(去掉多余的l)和返回类型,规范参数格式 FUNCTION GET_LOCATION_NAME (p_con_id IN NUMBER, p_con_name OUT VARCHAR2) RETURN NUMBER; -- 补全ADD_CONSULTANT的参数声明,和包体保持一致 PROCEDURE ADD_CONSULTANT ( p_con_id LDS_CONSULTANT.CONSULTANT_ID%TYPE, p_con_name LDS_CONSULTANT.CST_NAME%TYPE, p_con_start LDS_CONSULTANT.START_DATE%TYPE, p_con_end LDS_CONSULTANT.LEAVE_DATE%TYPE, p_con_loc LDS_CONSULTANT.LOCATION%TYPE, p_con_spec LDS_CONSULTANT.SPECIALIST_AREA%TYPE ); PROCEDURE update_location ( p_con_id IN lds_consultant.consultant_id%TYPE, p_con_loc IN lds_consultant.location%TYPE ); PROCEDURE delete_con ( p_con_id IN lds_consultant.consultant_id%TYPE ); END e_con_pack; /
2. 包体的修正
包体的主要问题是缺少连接关键字、子程序前多余的创建语句、函数返回未定义变量,同时优化了重复查询,修正后的代码如下:
CREATE OR REPLACE PACKAGE BODY e_con_pack IS FUNCTION GET_LOCATION_NAME (p_con_id IN NUMBER, p_con_name OUT VARCHAR2) RETURN NUMBER IS v_location VARCHAR2(30); -- 用v_前缀标识局部变量,避免和参数混淆 BEGIN -- 合并两次查询,一次获取所需字段,提升效率 SELECT LOCATION, CST_NAME INTO v_location, p_con_name FROM LDS_CONSULTANT WHERE CONSULTANT_ID = p_con_id; -- 这里假设你要返回传入的顾问ID,若需返回LOCATION,需将函数返回类型改为VARCHAR2 RETURN p_con_id; END GET_LOCATION_NAME; PROCEDURE ADD_CONSULTANT ( p_con_id LDS_CONSULTANT.CONSULTANT_ID%TYPE, p_con_name LDS_CONSULTANT.CST_NAME%TYPE, p_con_start LDS_CONSULTANT.START_DATE%TYPE, p_con_end LDS_CONSULTANT.LEAVE_DATE%TYPE, p_con_loc LDS_CONSULTANT.LOCATION%TYPE, p_con_spec LDS_CONSULTANT.SPECIALIST_AREA%TYPE ) IS BEGIN INSERT INTO LDS_CONSULTANT ( CONSULTANT_ID, CST_NAME, START_DATE, LEAVE_DATE, LOCATION, SPECIALIST_AREA ) VALUES ( p_con_id, p_con_name, p_con_start, p_con_end, p_con_loc, p_con_spec ); END ADD_CONSULTANT; PROCEDURE update_location ( p_con_id IN lds_consultant.consultant_id%TYPE, p_con_loc IN lds_consultant.location%TYPE ) IS BEGIN UPDATE lds_consultant SET location = p_con_loc WHERE consultant_id = p_con_id; END update_location; PROCEDURE delete_con ( p_con_id IN lds_consultant.consultant_id%TYPE ) IS BEGIN DELETE FROM LDS_CONSULTANT WHERE CONSULTANT_ID = p_con_id; END delete_con; END e_con_pack; /
关键注意事项
- 包规范和包体中的子程序签名(名字、参数、返回类型)必须完全一致,否则会编译失败
- 包体里的子程序属于包的一部分,不需要单独使用
CREATE OR REPLACE - 局部变量建议用统一前缀(如
v_)区分参数,提升代码可读性 - 尽量合并重复的查询操作,减少数据库IO开销
内容的提问来源于stack exchange,提问作者kalagod
相关产品推荐
相关产品推荐

