PL/SQL中CREATE PROCEDURE必须用AS或IS分隔参数列表与过程体,不可省略;参数模式(IN/OUT/IN OUT)严格决定数据流向与赋值规则;编译错误需用SHOW ERRORS定位;调试OUT参数推荐DBMS_OUTPUT.PUT_LINE。
PL/SQL里CREATE PROCEDURE必须带AS或IS,不能省略
很多人写完create procedure p1 (x in number)就直接跟begin,结果报错ora-00900: invalid sql statement。oracle要求声明体和执行体之间必须有as或is关键字,这是语法硬性分隔符,不是可选修饰。
实操建议:
-
AS和IS完全等价,选一个保持团队统一即可,推荐用AS(更接近SQL风格) - 参数列表后必须换行再写
AS,不能写成PROCEDURE p1(x IN NUMBER) AS这种连写——虽然某些工具不报错,但属于隐式换行依赖,跨版本可能出问题 - 如果过程体为空,仍需写
NULL;,不能只留BEGIN END;(会报PLS-00103)
IN/OUT/IN OUT参数的行为差异直接影响调用方式
参数模式不是“声明习惯”,它决定变量在过程内是否可被修改、调用方能否拿到新值。最常见错误是把OUT参数当成IN传入已有值,结果过程里一赋值就覆盖原值,而调用方还傻等返回。
实操建议:
-
IN:只读,过程内改了也不影响调用方变量;适合传条件、ID、配置值 -
OUT:只写,过程必须赋值,调用方变量初始值被忽略;适合返回单个结果,如status_code OUT VARCHAR2 -
IN OUT:可读可写,调用方传入的值能被过程读取,过程也能改写并回传;适合需要“输入+加工+覆盖”的场景,比如字符串拼接函数 - 所有
OUT和IN OUT参数,调用时必须传变量(不能传字面量),否则报PLS-00363:“expression 'xxx' cannot be used as an assignment target”
过程编译失败时,SHOW ERRORS比看SQL*Plus提示更准
执行CREATE PROCEDURE后如果报错,SQL*Plus只显示Warning: Procedure created with compilation errors.,但不会告诉你哪行错了。这时候直接SHOW ERRORS才能看到真实位置和原因,比如PLS-00306: wrong number or types of arguments这种典型参数不匹配错误。
实操建议:
- 每次创建或修改后立刻执行
SHOW ERRORS PROCEDURE <code>your_proc_name,别等调用时报错才查 - 如果用PL/SQL Developer或SQL Developer,注意它们的“编译错误”面板默认不自动刷新,要手动点刷新或按F8
- 常见陷阱:参数名和局部变量名重复导致意外覆盖;
DATE类型误用字符串比较(如my_date = '2024-01-01'没加TO_DATE)
调试OUT参数值,用DBMS_OUTPUT.PUT_LINE比单步更可靠
PL/SQL过程没法像Java那样断点看变量,尤其OUT参数的最终值是否正确,光靠调用语句看不出。很多人写完过程就用EXEC p1(1, :out_val)然后查:out_val,但中间逻辑错了一步,值早就歪了。
实操建议:
- 在过程末尾加
DBMS_OUTPUT.PUT_LINE('out_param = ' || out_param);,调用前先SET SERVEROUTPUT ON - 注意
DBMS_OUTPUT缓冲区默认只存10000字节,大字符串可能被截断,可提前DBMS_OUTPUT.ENABLE(1000000) - 避免在循环里频繁调用
PUT_LINE,IO开销大;真要跟踪循环,改用DBMS_OUTPUT.PUT拼接后一次输出
过程里参数传递的边界很窄,IN就是进,OUT就是出,中间没灰色地带。稍不注意,传进去的值被忽略,或者该出来的值根本没赋值,调用方就卡在空等待里——这种问题往往不是语法错,而是对模式理解偏了一点点。










