Oracle中游标和集合的定义查询及取值

在 Oracle 存储过程中,使用游标处理自定义数据行类型时,可以通过 定义记录类型(RECORD) 和 游标(CURSOR) 结合实现。
1. 定义自定义记录类型

使用 TYPE ... IS RECORD 定义自定义行数据类型:

sql 复制代码
DECLARE
  -- 定义自定义记录类型(包含所需字段)
  TYPE t_emp_record IS RECORD (
    emp_id   employees.employee_id%TYPE,
    emp_name VARCHAR2(100),
    salary   employees.salary%TYPE
  );
  
  v_emp t_emp_record;  -- 声明变量
BEGIN
  -- 逻辑代码
END;

2. 声明游标并关联查询

将游标的查询结果映射到自定义记录类型:

sql 复制代码
DECLARE
  -- 定义记录类型
  TYPE t_emp_record IS RECORD (
    emp_id   employees.employee_id%TYPE,
    emp_name VARCHAR2(100),
    salary   employees.salary%TYPE
  );
  
  -- 声明游标(显式指定返回类型)
  CURSOR cur_custom_emp IS
    SELECT employee_id, first_name || ' ' || last_name, salary
    FROM employees
    WHERE department_id = 10;  -- 示例查询条件
  
  v_emp t_emp_record;  -- 声明变量
BEGIN
  OPEN cur_custom_emp;
  LOOP
    FETCH cur_custom_emp INTO v_emp;
    EXIT WHEN cur_custom_emp%NOTFOUND;
    -- 处理数据(例如输出)
    DBMS_OUTPUT.PUT_LINE(
      'ID: ' || v_emp.emp_id || 
      ', Name: ' || v_emp.emp_name || 
      ', Salary: ' || v_emp.salary
    );
  END LOOP;
  CLOSE cur_custom_emp;
END;

3. 使用 %ROWTYPE 简化记录类型

如果查询字段与表结构一致,可直接用 %ROWTYPE

sql 复制代码
DECLARE
  CURSOR cur_emp IS
    SELECT employee_id, first_name, salary
    FROM employees;
  
  v_emp cur_emp%ROWTYPE;  -- 自动匹配游标字段
BEGIN
  OPEN cur_emp;
  LOOP
    FETCH cur_emp INTO v_emp;
    EXIT WHEN cur_emp%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(v_emp.first_name || '的工资是:' || v_emp.salary);
  END LOOP;
  CLOSE cur_emp;
END;

4. 将自定义记录类型作为参数传递

可以在存储过程或函数间传递自定义记录类型:

sql 复制代码
CREATE OR REPLACE PROCEDURE process_employee (
    p_emp IN t_emp_record  -- 假设 t_emp_record 已在包中定义
)
IS
BEGIN
  DBMS_OUTPUT.PUT_LINE('处理员工:' || p_emp.emp_name);
END;

5. 在包(Package)中定义公共记录类型

若需跨多个程序单元使用,可在包中定义:

sql 复制代码
CREATE OR REPLACE PACKAGE emp_pkg IS
  -- 定义公共记录类型
  TYPE t_emp_record IS RECORD (
    emp_id   employees.employee_id%TYPE,
    emp_name VARCHAR2(100),
    salary   employees.salary%TYPE
  );
  
  -- 声明游标
  CURSOR cur_emp RETURN t_emp_record;  -- 注意:此处仅定义游标规范
END emp_pkg;

CREATE OR REPLACE PACKAGE BODY emp_pkg IS
  -- 实现游标(关联查询)
  CURSOR cur_emp RETURN t_emp_record IS
    SELECT employee_id, first_name || ' ' || last_name, salary
    FROM employees;
END emp_pkg;

6. 使用 BULK COLLECT 批量提取数据

高效处理大量数据:

sql 复制代码
DECLARE
  -- t_emp_record上面方式进行定义
  TYPE t_emp_table IS TABLE OF t_emp_record;  -- 定义表类型
  v_emps t_emp_table;  -- 声明表变量
BEGIN
  -- 批量提取数据到表变量
  SELECT employee_id, first_name || ' ' || last_name, salary
  BULK COLLECT INTO v_emps
  FROM employees
  WHERE department_id = 10;

  -- 遍历表变量
  FOR i IN 1..v_emps.COUNT LOOP
    DBMS_OUTPUT.PUT_LINE(v_emps(i).emp_name);
  END LOOP;
END;

7. 动态游标与记录类型结合

使用 SYS_REFCURSOR 动态游标时,需显式匹配记录类型:

sql 复制代码
DECLARE
  TYPE t_emp_record IS RECORD (
    emp_id   NUMBER,
    emp_name VARCHAR2(100),
    salary   NUMBER
  );
  
  v_cur      SYS_REFCURSOR;  -- 动态游标
  v_emp      t_emp_record;   -- 自定义记录
  v_sql_stmt VARCHAR2(200) := 
    'SELECT employee_id, first_name || '' '' || last_name, salary 
     FROM employees 
     WHERE department_id = :dept_id';
BEGIN
  OPEN v_cur FOR v_sql_stmt USING 10;  -- 绑定参数
  LOOP
    FETCH v_cur INTO v_emp;
    EXIT WHEN v_cur%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(v_emp.emp_name);
  END LOOP;
  CLOSE v_cur;
END;

总结

**定义记录类型:**明确字段结构,可匹配游标查询。

**游标声明:**显式指定查询字段与记录类型匹配。

**数据提取:**使用 FETCH INTO 将游标数据存入记录变量。

**批量处理:**BULK COLLECT 提升大数据量性能。

**动态游标:**结合 SYS_REFCURSOR 和自定义类型处理动态 SQL。

通过以上方法,可以灵活控制游标返回的数据结构,并高效处理复杂业务逻辑。

相关推荐
数据皮皮侠44 分钟前
最新上市公司业绩说明会文本数据(2017.02-2025.08)
大数据·数据库·人工智能·笔记·物联网·小程序·区块链
小云数据库服务专线1 小时前
GaussDB数据库架构师修炼(十六) 如何选择磁盘
数据库·数据库架构·gaussdb
码出财富2 小时前
SQL语法大全指南
数据库·mysql·oracle
异世界贤狼转生码农4 小时前
MongoDB Windows 系统实战手册:从配置到数据处理入门
数据库·mongodb
QuZhengRong4 小时前
【数据库】Navicat 导入 Excel 数据乱码问题的解决方法
android·数据库·excel
码农阿豪4 小时前
Windows从零到一安装KingbaseES数据库及使用ksql工具连接全指南
数据库·windows
时序数据说10 小时前
时序数据库市场前景分析
大数据·数据库·物联网·开源·时序数据库
听雪楼主.13 小时前
Oracle Undo Tablespace 使用率暴涨案例分析
数据库·oracle·架构
我科绝伦(Huanhuan Zhou)13 小时前
KINGBASE集群日常维护管理命令总结
数据库·database
妖灵翎幺13 小时前
Java应届生求职八股(2)---Mysql篇
数据库·mysql