实例详解数据库的游标管理

本文分享自华为云社区《GaussDB数据库SQL系列-游标管理》,作者:酷哥。

一、前言

在数据库中,游标(cursor)是一种非常重要的工具,用于在数据库查询结果集中进行定位和操作。游标提供了一种在多行数据结果集中逐行处理每一行的机制,允许开发人员对每一行的数据进行操作,如检索、过滤、修改等。本文将结合GaussDB数据库,简单的给大家做一介绍。

二、概述(GaussDB)

1、游标概述

在GaussDB数据库中,为了处理SQL语句,存储过程进程分配一段内存区域来保存上下文联系。游标是指向上下文区域的句柄或指针。借助游标,存储过程可以控制上下文区域的变化。

2、游标的使用分类

游标的使用分为显式游标和隐式游标。对于不同的SQL语句,游标的使用情况不同。

• **显式游标:**显式游标主要用于对查询语句的处理,尤其是在查询结果为多条记录的情况下。

隐式游标**:**对于非查询语句,如修改、删除操作,则由系统自动地为这些操作设置游标并创建其工作区,这些由系统隐含创建的游标称为隐式游标,隐式游标的名称为SQL,这是由系统定义的。

游标循环**:**游标在WHILE语句、LOOP语句中的使用称为游标循环,一般这种循环都需要使用OPEN、FETCH和CLOSE语句。

三、GaussDB中的显式游标(示例)

1、显式游标的使用与操作步骤

第一步 **,定义 (声明)游标:**定义一个游标名,以及与其相对应的SELECT语句。

第二步 **,打开游标****:**执行游标所对应的SELECT语句,将其查询结果放入工作区,并且指针指向工作区的首部,标识游标结果集合。如果游标查询语句中带有FOR UPDATE选项,OPEN语句还将锁定数据库表中游标结果集合对应的数据行。

第三步 **,**提取游标数据:检索结果集合中的数据行,放入指定的输出变量中。

• **第四步,**对该记录进行处理

• **第五步,**继续处理,直到活动集合中没有记录。

第六步**,****关闭游标:**当提取和处理完游标结果集合数据后,应及时关闭游标,以释放该游标所占用的系统资源,并使该游标的工作区变成无效,不能再使用FETCH语句获取其中数据。关闭后的游标可以使用OPEN语句重新打开。

2、显式游标示例

sql 复制代码
--给工资大于等于20000的员工降薪500。

--复制一张测试表

CREATE TABLE company2 AS TABLE company1;
CREATE OR REPLACE PROCEDURE cursor_p()

AS

DECLARE

v_id NUMBER(6);

v_salary NUMBER(8,2);

CURSOR c1 IS SELECT id, salary FROM company2;

BEGIN

OPEN c1;

LOOP

FETCH c1 INTO v_id, v_salary;

EXIT WHEN c1%NOTFOUND;

IF v_salary>=20000 THEN

UPDATE company2 SET salary =salary - 500 WHERE id = v_id;

END IF;

END LOOP;

CLOSE c1;

END;

/
--执行存储过程

CALL cursor_p();
--查看,比对结果变化

SELECT t2.*,t1.salary as "降薪前" FROM company2 t2 LEFT JOIN company1 t1 ON t2.id=t1.id ORDER BY ID ASC;

游标属性说明**:**

%NOTFOUND是游标的属性之一,用于控制程序流程或者了解程序的状态。此处的意思是,当最近的DML(数据操作语言)操作(如INSERT,UPDATE,DELETE等)没有影响任何行时,该属性为真。也就是说,如果对表执行的操作没有找到任何匹配的行,那么这个属性就会为真,'EXIT WHEN c1%NOTFOUND;' 就会执行。

执行结果**:**

四、GaussDB中的隐式游标(示例)

1、隐式游标简介

对于隐式游标的操作,如定义、打开、取值及关闭操作,都由系统自动地完成,无需用户进行处理。用户只能通过隐式游标的相关属性,来完成相应的操作。在隐式游标的工作区中,所存放的数据是最新处理的一条SQL语句所包含的数据,与用户自定义的显式游标无关。

2、隐式游标示例

sql 复制代码
--创建临时表,删除已离职的员工Allen,如果Allen已经不存在,则新增一条新员工信息(重名)

CREATE TABLE company3 AS TABLE company1;
CREATE OR REPLACE PROCEDURE cursor_p1()

AS

DECLARE

v_name VARCHAR(10) := 'Allen';

BEGIN

     DELETE FROM company3 WHERE name = v_name;

--根据游标状态做进一步处理

IF SQL%NOTFOUND THEN

INSERT INTO company3 VALUES(4,v_name,24,'China',30000);

END IF;

END;

/
--执行

CALL cursor_p1();
--查看,比对执行结果

SELECT *, 'company1' as "company1" FROM company1 WHERE NAME ='Allen'

union all

SELECT *, 'company3' as "company3" FROM company3 WHERE NAME ='Allen'

游标属性说明**:**

SQL%NOTFOUND 是GaussDB数据库中的一个属性,用于检查最近的 SQL 语句是否对数据库没有任何影响。如果 SQL 语句没有找到任何匹配的记录,那么这个属性就为真。所以,本段SQL中的IF SQL%NOTFOUND THEN 这一行代码的意思是:如果最近的 SQL 语句没有找到任何匹配的记录,那么就执行后续的代码。通常,这个语句用于处理 SQL 查询可能找不到数据的情况。

执行结果**:**

五、小结

在GaussDB数据库中,游标主要用于执行复杂的查询语句、处理多行数据以及进行数据操作等场景。游标的使用可以提高程序的灵活性和可维护性,并且可以减少不必要的内存消耗。使用游标,开发人员可以灵活地控制查询结果集的遍历顺序和处理方式,以满足不同的业务需求。

点击关注,第一时间了解华为云新鲜技术~

相关推荐
武子康1 分钟前
Java-02 深入浅出MyBatis 3 快速入门:环境配置、项目创建与 CRUD 操作
java·后端
南极企鹅10 分钟前
事务&@Transactional注解
java·数据库·spring·oracle·mybatis
UrSpecial14 分钟前
Redis与多线程
数据库·redis·缓存
bqq1986102619 分钟前
MySQL 8与MySQL 5.7的主要区别
数据库·mysql
chushiyunen1 小时前
r树索引、mysql对r树的支持
数据库·mysql
会编程的土豆1 小时前
Redis Sorted Set(有序集合)详解
数据库·redis·bootstrap
未若君雅裁1 小时前
Spring Boot 自动配置原理与常用注解
java·spring boot·后端
Xiacqi11 小时前
Java数据库连接--JDBC--DRUID
数据库·后端
浮游本尊1 小时前
用结构化 Prompt 让大模型「干活」:以数据库巡检告警建议生成为例
后端
Yushan Bai1 小时前
ORACLE Enterprise Manager Cloud Control 系列测试3-Data Masking
数据库·oracle