DECLARE CURSOR cur_emp(var_job in varchar2:='SALESMAN') IS SELECT empno,ename,sal FROM emp WHERE job=var_job;
Oracle 游标声明代码逐行详解
这段代码声明了一个带参数的游标,并且参数有默认值。让我从最基础的概念开始讲。
一、整体功能概述
这段代码声明了一个名为 cur_emp 的游标,作用是:
查询 emp 表中指定职位的员工信息(编号、姓名、工资)
特殊之处:
职位通过参数
var_job传入如果不传参数,默认查询
'SALESMAN'(销售员)
二、逐行详细讲解
第1行:DECLARE
sql
DECLARE
| 单词 | 词源 | 含义 |
|---|---|---|
| DECLARE | 拉丁语 declarare(清楚说明) | 声明、定义 |
作用:表示接下来要声明变量、游标、常量等。这是 PL/SQL 块的声明部分。
第2行:CURSOR cur_emp(var_job in varchar2:='SALESMAN')
sql
CURSOR cur_emp(var_job in varchar2:='SALESMAN')
这句话是游标声明,可以拆解为几个部分:
| 部分 | 含义 |
|---|---|
CURSOR | 关键字,表示声明一个游标 |
cur_emp | 游标名称(custom + emp 的缩写) |
var_job in varchar2 | 游标参数:输入参数,类型为 varchar2 |
:='SALESMAN' | 默认值:如果调用时不传值,就默认为 'SALESMAN' |
参数模式 IN 的含义
| 模式 | 方向 | 说明 |
|---|---|---|
IN | 进入游标 | 参数值从外部传入,游标内部使用 |
OUT | 离开游标 | 基本不用,游标参数通常是 IN |
为什么需要参数?
没有参数的游标:
sql
CURSOR cur_emp IS SELECT * FROM emp WHERE job = 'SALESMAN'; -- 永远只查销售员
有参数的游标:
sql
CURSOR cur_emp(var_job VARCHAR2) IS SELECT * FROM emp WHERE job = var_job; -- 可以查任意职位
第3行:IS
sql
IS
| 单词 | 词源 | 含义 |
|---|---|---|
| IS | 古英语 is | 是 |
表示游标定义开始,后面要跟着 SELECT 语句。
第4-6行:SELECT 查询语句
sql
SELECT empno,ename,sal FROM emp WHERE job=var_job;
| 部分 | 含义 |
|---|---|
empno | 员工编号 |
ename | 员工姓名 |
sal | 工资 |
emp | 员工表 |
WHERE job = var_job | 使用游标参数作为过滤条件 |
这里的 var_job 就是游标声明时定义的参数。
第7行:;
sql
;
结束游标声明。
三、完整结构图
text
┌─────────────────────────────────────────────────────────────┐ │ DECLARE │ │ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ CURSOR cur_emp(var_job IN VARCHAR2 := 'SALESMAN') │ │ │ │ IS │ │ │ │ SELECT empno, ename, sal │ │ │ │ FROM emp │ │ │ │ WHERE job = var_job; │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ ↓ 后续还会跟 BEGIN ... END(执行部分)
四、完整使用示例
仅仅声明游标还不够,还需要打开、取数据、关闭。完整的 PL/SQL 块应该如下:
sql
DECLARE
-- 1. 声明游标(带参数和默认值)
CURSOR cur_emp(var_job IN VARCHAR2 := 'SALESMAN') IS
SELECT empno, ename, sal FROM emp WHERE job = var_job;
-- 2. 声明变量存放取出的数据
v_empno emp.empno%TYPE;
v_ename emp.ename%TYPE;
v_sal emp.sal%TYPE;
BEGIN
-- 3. 打开游标(不传参数,使用默认值 'SALESMAN')
OPEN cur_emp;
-- 或者:打开游标(传入参数,查询 'MANAGER')
-- OPEN cur_emp('MANAGER');
LOOP
-- 4. 取一行数据
FETCH cur_emp INTO v_empno, v_ename, v_sal;
-- 5. 没有数据了就退出
EXIT WHEN cur_emp%NOTFOUND;
-- 6. 输出
DBMS_OUTPUT.PUT_LINE(v_empno || ' - ' || v_ename || ' - ' || v_sal);
END LOOP;
-- 7. 关闭游标
CLOSE cur_emp;END;/五、参数传值的三种方式
方式1:使用默认值
sql
OPEN cur_emp; -- 自动使用 'SALESMAN'
方式2:按位置传值
sql
OPEN cur_emp('MANAGER'); -- 查询经理方式3:按名称传值
sql
OPEN cur_emp(var_job => 'CLERK'); -- 查询办事员
六、对比:无参数 vs 有参数游标
| 对比项 | 无参数游标 | 有参数游标 |
|---|---|---|
| 灵活性 | 低(查什么写死) | 高(可以传入不同值) |
| 重用性 | 低 | 高 |
| 默认值 | 不支持 | 支持 |
| 示例 | WHERE job = 'SALESMAN' | WHERE job = var_job |
七、词源角度总结
| 单词 | 词源 | 含义 |
|---|---|---|
| CURSOR | 拉丁语 cursor(奔跑者) | 游标(在数据上"跑") |
| DECLARE | 拉丁语 declarare(清楚说明) | 声明 |
| IS | 古英语 is | 是 |
| IN | 古英语 in | 输入 |
| DEFAULT | 古法语 defaut(缺乏) | 默认值 |
八、常见误区
| 误区 | 正确理解 |
|---|---|
| 游标参数不能有默认值 | ✅ 可以有,用 := 赋值 |
参数只用 IN | ✅ 对,游标参数只读 |
| 感觉声明了就能直接用 | ❌ 还需要 OPEN、FETCH、CLOSE |
九、总结
| 代码元素 | 含义 |
|---|---|
DECLARE | 开始声明部分 |
CURSOR cur_emp | 声明一个叫 cur_emp 的游标 |
var_job IN VARCHAR2 | 定义一个输入参数,类型是字符串 |
:= 'SALESMAN' | 参数的默认值 |
IS SELECT ... | 游标要执行的查询 |
WHERE job = var_job | 查询条件中使用参数 |
一句话总结:这段代码声明了一个带参数的游标,参数 var_job 有默认值 'SALESMAN',游标会根据传入的职位(或默认值)查询对应员工的信息。这种设计让游标更灵活、可复用