set serveroutput on DECLARE var_number number; --存储要进行运算的值和运算后的结果 var_temp number; --存储要进行运算的值 boo_flag boolean; --平方或平方根的逻辑标记 BEGIN var_temp :=3; --变量赋值 var_number :=var_temp; boo_flag := false; --false表示计算平方根;true表示计算平方 pro_square(var_number,boo_flag); --调用存储过程pro_square IF boo_flag THEN dbms_output.put_line(var_temp ||'的平方是:'||var_number); --输出计算结果 ELSE dbms_output.put_line(var_temp ||'平方根是:'||var_number); END IF; END; /
SQL 执行存储过程的代码逐行详解
这段代码是调用者(caller),它负责:
准备数据
调用前面定义的
pro_square存储过程输出最终结果
下面我逐行、不跳步地讲清楚。
一、第1行:set serveroutput on
sql
set serveroutput on
含义
打开 SQL*Plus / SQL Developer 中的服务器输出开关。
为什么需要?
Oracle 存储过程中的
dbms_output.put_line会把内容缓存在服务器端如果不加这一行,你看不到任何输出
加上之后,程序执行完会把缓冲区内容打印到屏幕
词源角度
set:设置(古英语settam)serveroutput:server(服务器)+ output(输出)
💡 记住:
看不到输出时,先检查set serveroutput on
二、变量声明部分
第2行:DECLARE
sql
DECLARE
含义
PL/SQL 块的声明部分开始。
作用
在 BEGIN 之前,定义所有要用的变量。
第3~5行:定义三个变量
sql
var_number number; --存储要进行运算的值和运算后的结果var_temp number; --存储要进行运算的值boo_flag boolean; --平方或平方根的逻辑标记
| 变量名 | 类型 | 作用 |
|---|---|---|
var_number | number | 传给存储过程,既存原始值,也接收结果 |
var_temp | number | 只保存原始值(用于最后输出显示) |
boo_flag | boolean | 控制存储过程的行为(平方还是平方根) |
👉 为什么需要两个数字变量?
var_temp:原始值(保留不让它变)
var_number:进入过程之前等于原始值,出来后变成运算结果
三、执行体开始
第6行:BEGIN
sql
BEGIN
含义
PL/SQL 块的执行部分开始。
第7行:var_temp := 3;
sql
var_temp := 3;
把 3 赋给
var_temp这是原始值,后面不会被改
第8行:var_number := var_temp;
sql
var_number := var_temp;
把
var_temp(当前 3)复制给var_number此时:
var_number = 3,var_temp = 3
为什么要有这一步?
因为var_number要同时承载输入和输出,初始值必须和var_temp一致。
第9行:boo_flag := false;
sql
boo_flag := false; --false表示计算平方根;true表示计算平方
把
false赋给boo_flag意思是:选择计算平方根
第10行:调用存储过程 pro_square
sql
pro_square(var_number, boo_flag); --调用存储过程pro_square
这里只传变量名,不带括号写参数类型。
调用前后对比
| 调用前 | 调用后 |
|---|---|
var_number = 3 | var_number = 1.732...(3的平方根) |
boo_flag = false | boo_flag 不变(IN 参数) |
解释:
因为
pro_square的参数中:num是IN OUTflag是IN
所以:
flag只流入,不会改var_number的值在过程内部被改掉并带回来
四、结果输出
第11行:IF boo_flag THEN
sql
IF boo_flag THEN
判断 boo_flag 的值:
true→ 走平方分支false→ 走平方根分支
当前 boo_flag = false,所以进入 ELSE。
第12~13行:dbms_output.put_line
sql
dbms_output.put_line(var_temp ||'的平方是:'||var_number); --输出计算结果
这一行不会执行(因为走 else)。
第14~15行:真正的输出(else 分支)
sql
ELSE dbms_output.put_line(var_temp ||'平方根是:'||var_number);
实际执行的是:
sql
dbms_output.put_line(var_temp ||'平方根是:'||var_number);
代入当前值:
var_temp = 3var_number = √3 ≈ 1.7320508
最终输出:
text
3平方根是:1.7320508075688772
||是 Oracle 的字符串拼接符。
第16行:END IF;
sql
END IF;
条件分支结束。
第17行:END;
sql
END;
PL/SQL 块结束。
第18行:/
sql
/
在 SQL*Plus / 大多数 Oracle 工具中,
/表示 执行上面整个 PL/SQL 块没有它,代码不会运行
五、完整执行流程图(和存储过程配合)
text
【变量赋值】 var_temp = 3 var_number = 3 boo_flag = false ↓ 【调用 pro_square(var_number, false)】 ↓ (进入存储过程内部) │ ├── flag = false → 走 ELSE ├── num := sqrt(3) └── 返回(num 被改成 √3) ↓ 【回到调用方】 var_number 变成了 √3 var_temp 依然是 3 boo_flag 依然是 false ↓ 【条件判断】 boo_flag = false → 输出“平方根”
六、常见易错点提醒
| 错误写法 | 原因 |
|---|---|
pro_square(3, false) | 不能直接传常量,因为第一个参数需要被改回 |
忘了 set serveroutput on | 看不到任何输出 |
用 var_temp 作为存储过程参数 | 结果会被覆盖,就丢掉了原始值 |
七、总结
| 代码段 | 作用 |
|---|---|
set serveroutput on | 允许输出 |
DECLARE … BEGIN … END; | PL/SQL 块 |
var_temp := 3 | 保留原始值 |
var_number := var_temp | 准备传给存储过程 |
boo_flag := false | 开关:平方根 |
pro_square(var_number, boo_flag) | 执行核心逻辑(值被改) |
IF … ELSE … | 判断输出哪种中文 |
/ | 执行块 |
一句话总结:
这个调用代码的精华在于——用两个变量分别保存“原始值”和“可变化的运算值”,让存储过程的 IN OUT 机制能正常工作并正确输出结果