PL/SQL语句中的函数、游标、及存储过程的应用

在PL/SQL(ProceduralLanguage/SQL)中,游标、函数和存储过程是重要的编程结构,能够极大地增强Oracle数据库的处理能力。

下面分别介绍它们的语法和应用。


1.游标(Cursor)

游标简介 游标用于在PL/SQL代码中逐行处理SQL查询结果集。游标有两种类型:显式游标和隐式游标。

1.1 显式游标

显式游标语法及示例显式游标需要手动声明、打开、提取数据、关闭。

-- 声明游标
CURSOR cursor_name ISSELECT column1, column2FROM table_nameWHERE condition;-- 示例
DECLARECURSOR emp_cursor ISSELECT emp_id, emp_nameFROM employeesWHERE department_id = 10;emp_record emp_cursor%ROWTYPE;
BEGIN-- 打开游标OPEN emp_cursor;LOOP-- 提取数据到emp_recordFETCH emp_cursor INTO emp_record;-- 退出循环条件EXIT WHEN emp_cursor%NOTFOUND;-- 处理数据DBMS_OUTPUT.PUT_LINE('Employee ID: ' || emp_record.emp_id || ', Name: ' || emp_record.emp_name);END LOOP;-- 关闭游标CLOSE emp_cursor;
END;
/
1.2隐式游标

隐式游标由Oracle自动处理,主要用于SELECT INTO语句和DML操作。

DECLAREemp_name employees.emp_name%TYPE;
BEGINSELECT emp_nameINTO emp_nameFROM employeesWHERE emp_id = 100;DBMS_OUTPUT.PUT_LINE('Employee Name: ' || emp_name);
EXCEPTIONWHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('No employee found with ID 100');
END;
/
1.3游标for循环

在PL/SQL中,FOR循环是一种简便的方式来遍历游标返回的结果集。使用FOR循环可以自动处理游标的打开、提取和关闭操作,无需显式地编写这些步骤。这种方式简化了代码,提高了可读性和可维护性。

基本语法:

FOR record IN cursor_name LOOP-- 处理record
END LOOP;

示例:

假设我们有一个employees表,包含员工的ID和名字。我们希望通过一个游标循环来遍历所有员工,并输出他们的ID和名字。

DECLARE-- 声明游标CURSOR emp_cursor ISSELECT emp_id, emp_nameFROM employees;
BEGIN-- 使用游标FOR循环FOR emp_record IN emp_cursor LOOP-- 处理游标返回的每一行DBMS_OUTPUT.PUT_LINE('Employee ID: ' || emp_record.emp_id || ', Name: ' || emp_record.emp_name);END LOOP;
END;
/

在这个示例中,emp_cursor游标定义了一个查询,选择employees表中的emp_id和emp_name。FOR循环会自动打开游标,逐行提取数据并将每一行的数据放入emp_record中。循环体内的代码可以直接访问emp_record中的各个字段。

使用隐式游标 FOR 循环

在某些情况下,可以省略游标的显式声明,直接在FOR循环中使用一个SELECT语句。这种方式称为隐式游标FOR循环。

BEGIN-- 直接在FOR循环中使用SELECT语句FOR emp_record IN (SELECT emp_id, emp_name FROM employees) LOOP-- 处理每一行数据DBMS_OUTPUT.PUT_LINE('Employee ID: ' || emp_record.emp_id || ', Name: ' || emp_record.emp_name);END LOOP;
END;
/

在这个示例中,FOR循环直接包含一个SELECT查询。每次循环迭代时,emp_record会自动获取查询结果集中的一行数据。

游标 FOR 循环的优点
  1. 简化代码:自动处理游标的打开、提取和关闭操作,无需显式地编写这些步骤。

  2. 提高可读性:减少了代码量,使程序更简洁易读。

  3. 避免错误:通过自动管理游标生命周期,减少了由于忘记关闭游标而引发的资源泄漏问题。

    完整示例

    为了更全面地展示游标 FOR 循环的用法,下面是一个稍微复杂的示例,包含更多业务逻辑。

    假设我们有一个任务是将所有部门ID为10的员工的工资提高10%。

    DECLARE-- 声明游标CURSOR emp_cursor ISSELECT emp_id, salaryFROM employeesWHERE department_id = 10;
    BEGIN-- 使用游标FOR循环FOR emp_record IN emp_cursor LOOP-- 更新每个员工的工资UPDATE employeesSET salary = salary * 1.10WHERE emp_id = emp_record.emp_id;-- 输出更新信息DBMS_OUTPUT.PUT_LINE('Updated Salary for Employee ID: ' || emp_record.emp_id);END LOOP;-- 提交事务COMMIT;
    END;
    /

    在这个示例中,我们通过游标 FOR 循环遍历所有部门ID为10的员工记录,并更新每个员工的工资。循环体内的UPDATE语句根据emp_record中的emp_id进行更新,并输出更新信息。最后,我们提交事务以保存更改。

游标 FOR 循环的语法和示例

  1. 函数(Function)

    函数是PL/SQL中的子程序,用于执行特定任务并返回一个值。函数可以在SQL语句中调用。

函数语法及示例

-- 创建函数
CREATE OR REPLACE FUNCTION function_name (param1 datatype, param2 datatype)
RETURN return_datatype 
IS-- 声明部分variable_name datatype;
BEGIN-- 执行部分-- 逻辑处理RETURN result_value;
EXCEPTION-- 异常处理WHEN exception_name THEN-- 处理代码
END function_name;
/-- 示例
CREATE OR REPLACE FUNCTION get_employee_name (p_emp_id NUMBER)
RETURN VARCHAR2 
ISv_emp_name employees.emp_name%TYPE;
BEGINSELECT emp_name INTO v_emp_nameFROM employeesWHERE emp_id = p_emp_id;RETURN v_emp_name;
EXCEPTIONWHEN NO_DATA_FOUND THENRETURN 'No employee found';
END get_employee_name;
/-- 调用函数
DECLAREv_name VARCHAR2(100);
BEGINv_name := get_employee_name(100);DBMS_OUTPUT.PUT_LINE('Employee Name: ' || v_name);
END;
/

存储过程

存储过程是PL/SQL中的子程序,用于执行一系列任务,但不返回值。存储过程可以包含输入、输出和输入输出参数。

--语法-- 创建存储过程
CREATE OR REPLACE PROCEDURE procedure_name (param1 IN datatype, param2 OUT datatype, param3 IN OUT datatype) --默认为输入参数
IS-- 声明部分variable_name datatype;
BEGIN-- 执行部分-- 逻辑处理
EXCEPTION-- 异常处理WHEN exception_name THEN-- 处理代码
END procedure_name;
/-- 示例
CREATE OR REPLACE PROCEDURE update_employee_salary (p_emp_id IN employees.emp_id%TYPE,p_new_salary IN employees.salary%TYPE
) ISBEGINUPDATE employeesSET salary = p_new_salaryWHERE emp_id = p_emp_id;IF SQL%ROWCOUNT = 0 THENDBMS_OUTPUT.PUT_LINE('No employee found with ID ' || p_emp_id);ELSEDBMS_OUTPUT.PUT_LINE('Salary updated for employee ID ' || p_emp_id);END IF;
EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
END update_employee_salary;
/-- 调用存储过程
BEGINupdate_employee_salary(100, 8000);
END;
/

应用场景

游标:适用于需要逐行处理查询结果集的场景,如批量数据处理、数据迁移等。

函数:适用于需要返回计算结果或查询结果的场景,如计算公式、数据查询等。函数可以嵌入在SQL语句中使用。

存储过程:适用于执行一系列数据库操作的场景,如批量更新、数据导入导出等。存储过程可以包含复杂的业务逻辑,并且可以接受参数进行动态处理。

通过使用游标、函数和存储过程,可以提高PL/SQL程序的灵活性、可维护性和性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/839073.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

04-Json/Ajax/Vue的知识

1. Json结构 1.1 Json概述 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,实现数据前后端交互。 它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。 JSON采用完全独立于程序语言的文本格式。这些特性使JSON成为理想的数据交换…

英码科技算能系列边缘计算盒子再添新成员!搭载TPU处理器BM1688CV186AH,功耗更低、接口更丰富

在数据呈现指数级增长的今天,越来越多的领域和细分场景对实时、高效的数据处理和分析的需求日益增长,对智能算力的需求也不断增强。为应对新的市场趋势,英码科技凭借自身的硬件研发优势,携手算能相继推出了基于BM1684的边缘计算盒…

5.23.1 深度学习在乳腺癌成像中的应用

乳腺成像在早期发现乳腺癌以及在治疗期间监测和评估乳腺癌方面发挥着重要作用。最常用的乳腺成像方式是数字乳房X线摄影、数字乳腺断层合成、超声和磁共振成像。 传统的 CAD 系统基于传统的机器学习 (ML) 技术;预定义(手工制作)的特征是系统…

【堡垒机小知识】堡垒机和接口机的重要区别分析

在企业IT架构管理中,接口机和堡垒机各自扮演着不可或缺的角色。但不少IT小伙伴对于两者不是很了解,不知道两者之间有什么区别,今天我们就来一起分析一下。 堡垒机和接口机的重要区别分析 1、功能区别 接口机主要用于数据库层面的数据交换和…

Linux多线程系列2: 模拟封装简易语言级线程库,线程互斥和锁,线程同步和条件变量,线程其他知识点

Linux多线程系列2: 模拟封装简易语言级线程库,线程互斥和互斥锁,线程同步和条件变量,线程其他知识点 1.前言 一.模拟C11线程库自己封装简易语言级线程库1.实现框架2.迅速把构造等等函数写完3.start和work1.尝试一2.尝试二3.最终版本4.给出代码 二.模拟实现多线程(为编写线程池做…

代码随想录训练营Day34:背包问题解决打家劫舍

1.198打家劫舍 1.dp数组的含义:dp[i]表示从第零个偷到第i个能够偷到的最大价值。 2.递推公式:分成两种情况: 偷第i个的情况下的最大值,注意此时第i-1个肯定是不偷的,所以此时dp[i] dp[i-2]nums[i];>dp[j] dp[j…

Unity数据持久化2——XML

简介: 基础知识 XML文件格式 XML基本语法 XML属性 练习: C#读取存储XML XML文件存放位置 读取XML文件 练习: 存储修改XML文件 练习: 总结 实践小项目 必备知识点 必备知识点——C#中XML序列化 必备知识点——C#中XML反序列化 必备…

java 线程执行原理,java线程在jvm中执行流程

java 线程执行原理,java线程在jvm中执行流程 从jvm视角看java线程执行过程 ##首先thread.c注册jni函数 JNIEXPORT void JNICALL Java_java_lang_Thread_registerNatives(JNIEnv *env, jclass cls) {(*env)->RegisterNatives(env, cls, methods, ARRAY_LENGTH(…

第八课,分支语句嵌套、随机数函数、初识while循环

一,分支结构的嵌套语法 在 Python 中,分支结构可以嵌套,这意味着你可以在一个条件语句中包含另一个条件语句。嵌套的分支结构可以让你更灵活地控制程序的逻辑流程。 怎么理解呢?打个比方:放学后,请三年级…

【MySQL精通之路】MySQL8.0新增功能-原子DDL语句支持

太长不看系列: 本文一句话总结,MySQL8.0支持多条DDL语句执行时的原子性了(仅限Innodb) 本文属于下面这篇博客的子博客: 【MySQL精通之路】MySQL8.0官方文档-新增功能 1.意义描述 MySQL 8.0支持原子数据定义语言&…

知乎广告推广开户最低需要多少钱?

精准高效的广告推广,是企业成功的关键,知乎作为知识分享与交流的高端平台,汇聚了大量高质量用户群体,无疑是品牌传播与产品推广的黄金之地。云衔科技作为您数字营销旅程中的得力伙伴,正以专业的知乎广告开户及代运营服…

快速搭建本地全文搜索

MeiliSearch 说起全文检索,在项目开发中,用的最多的就是 ElaticSearch 了,ElaticSearch 是基于 Apache Lucene 开发的全文检索服务,是一个端到端的解决方案,因此,部署和维护都非常复杂。今天介绍的这个全文…

AI配音可以商用吗?

随着人工智能技术的迅猛发展,AI配音技术在近几年的进步尤为显著。从最初的机械合成音到如今的智能语音合成,AI配音已经在广告、教育、媒体等领域中崭露头角,展现出其无限的潜力和广阔的应用空间。 AI配音技术的发展历程 AI配音技术起源于语…

如何在go项目中实现发送邮箱验证码、邮箱+验证码登录

前期准备 GoLand :2024.1.1 下载官网:https://www.jetbrains.com/zh-cn/go/download/other.html Postman: 下载官网:https://www.postman.com/downloads/ 效果图(使用Postman) Google: QQ: And …

【星海随笔】微信小程序(二)

WXML 模板语法 - 数据绑定 在data中定义页面的数据 在页面对应的 .js 文件中,把数据定义到 data 对象中即可: Page({data: {// 字符串类型的数据info: init data,// 数据类型的数据msgList: [{msg: hello},{msg: world}]} })Mustache 语法的格式 把 …

jQuery值操作例子 (代码)

直接上代码 <!DOCTYPE html> <html><head></head><body><div id"x1">例子</div><script src"js/jquery-3.7.1.min.js"></script><script>console.log($("#x1").text()) // 在浏览…

创建vue工程、Vue项目的目录结构、Vue项目-启动、API风格

环境准备 介绍&#xff1a;create-vue是Vue官方提供的最新的脚手架工具&#xff0c;用于快速生成一个工程化的Vue项目create-vue提供如下功能&#xff1a; 统一的目录结构 本地调试 热部署 单元测试 集成打包依赖环境&#xff1a;NodeJS 安装NodeJS 一、 创建vue工程 npm 类…

自定义横向思维导图,横向组织架构图,横向树图。可以自定义节点颜色,样式,还可以导出为图片

最近公司设计要求根据目录结构&#xff0c;横向展示。所以做了一个横向的思维导图&#xff0c;横向的树结构&#xff0c;横向的组织架构图&#xff0c;可以自定义节点颜色&#xff0c;样式&#xff0c;还可以导出为图片 话不多说&#xff0c;直接上图片&#xff0c;这个就是一…

使用redis优化纯真IP库访问

每次请求都需要加载10m的纯真IP qqwry.dat 文件&#xff0c;自己测试不会发现问题&#xff0c;但如果访问量上去了&#xff0c;会影响每次请求的相应效率&#xff0c;并且会消耗一定的io读写&#xff0c;故打算优化 优化方案 每个IP区间之间不存在交集&#xff0c;每个查找只要…

【已验证】debian12 更换国内源

1. 编辑 /etc/apt/sources.list 文件 sudo nano /etc/apt/sources.list2. 清空 sources.list 文件里的内容&#xff0c;讲下面内容拷贝到 sources.list deb http://mirrors.163.com/debian/ bookworm main contrib non-free non-free-firmware deb http://mirrors.163.com/de…