Oracle数据库中RETURNING子句

RETURNING子句允许您检索插入、删除或更新所修改的列(以及基于列的表达式)的值。如果不使用RETURNING,则必须在DML语句完成后运行SELECT语句,才能获得更改列的值。因此,RETURNING有助于避免再次往返数据库,即PL/SQL块中的另一个上下文切换。

RETURNING子句可以返回多行数据,在这种情况下,您将使用RETURNING BULK COLLECT INTO窗体。

您还可以在RETURNING子句中调用聚合函数,以获取DML语句更改的多行中的列的总和、计数等。

最后,还可以将RETURNING与EXECUTE IMMEDIATE一起使用(用于动态构建和执行的SQL语句)。

1、基本用法

1.1、单行操作:

当对单行数据进行DML操作时,可以使用RETURNING子句将受影响行的列值返回给变量。

DECLARE  
  v_empno employees.EMPLOYEE_ID%TYPE;  
  v_ename employees.FIRST_NAME%TYPE;  
BEGIN  
  UPDATE employees SET FIRST_NAME = 'superdb' WHERE EMPLOYEE_ID = 206 RETURNING EMPLOYEE_ID, FIRST_NAME INTO v_empno, v_ename;  
  DBMS_OUTPUT.PUT_LINE('Updated EMPLOYEE_ID: ' || v_empno || ', FIRST_NAME: ' || v_ename);  
END;
/

Updated EMPLOYEE_ID: 206, FIRST_NAME: superdb

PL/SQL procedure successfully completed.

1.2、多行操作:

当对多行数据进行DML操作时,需要使用PL/SQL的集合类型(如TABLE OF类型或嵌套表)来接收返回的多行数据。

示例(使用BULK COLLECT INTO):


HR@orcl> select EMPLOYEE_ID, FIRST_NAME,SALARY FROM employees WHERE DEPARTMENT_ID = 110 ;

EMPLOYEE_ID FIRST_NAME               SALARY
----------- -------------------- ----------
        205 Shelley                   12008
        206 William                    8300

DECLARE  
  TYPE emp_tab IS TABLE OF employees.EMPLOYEE_ID%TYPE INDEX BY PLS_INTEGER;  
  v_empnos emp_tab;  
  TYPE name_tab IS TABLE OF employees.FIRST_NAME%TYPE INDEX BY PLS_INTEGER;  
  v_enames name_tab;  
BEGIN  
  -- 正确的多列多行处理示例:  
  UPDATE employees SET FIRST_NAME = 'John Doe' WHERE DEPARTMENT_ID = 110   
  RETURNING EMPLOYEE_ID, FIRST_NAME BULK COLLECT INTO v_empnos, v_enames; 
  
  -- 遍历并输出  
  FOR i IN 1 .. v_empnos.COUNT LOOP  
    DBMS_OUTPUT.PUT_LINE('Empno: ' || v_empnos(i) || ', Ename: ' || v_enames(i));  
  END LOOP;  
END;
/
Empno: 205, Ename: John Doe
Empno: 206, Ename: John Doe

PL/SQL procedure successfully completed.

2、使用RECORD类型

对于需要同时处理多列数据的情况,可以使用PL/SQL的RECORD类型来定义一个能够包含多列数据的复合类型,然后结合BULK COLLECT INTO来使用。

DECLARE  
  TYPE emp_rec IS RECORD (  
    empno employees.EMPLOYEE_ID%TYPE,  
    ename employees.FIRST_NAME%TYPE  
  );  
  TYPE emp_tab IS TABLE OF emp_rec INDEX BY PLS_INTEGER;  
  v_emps emp_tab;  
BEGIN  
  -- 多列多行处理示例
  UPDATE employees SET FIRST_NAME = 'superdb' WHERE DEPARTMENT_ID = 110  
  RETURNING EMPLOYEE_ID, FIRST_NAME BULK COLLECT INTO v_emps;  
  -- 遍历并输出    
  FOR i IN 1 .. v_emps.COUNT LOOP  
    DBMS_OUTPUT.PUT_LINE('Empno: ' || v_emps(i).empno || ', Ename: ' || v_emps(i).ename);  
  END LOOP;  
END;
/
Empno: 205, Ename: superdb
Empno: 206, Ename: superdb

PL/SQL procedure successfully completed.

3、RETURNING子句中调用聚合函数

You can also call aggregate functions in the RETURNING clause to obtain sums, counts and so on of columns in multiple rows changed by the DML statement.
还可以在RETURNING子句中调用聚合函数,以获取DML语句更改的多行中的列的总和、计数等。


HR@orcl> select EMPLOYEE_ID, FIRST_NAME,SALARY FROM employees WHERE DEPARTMENT_ID = 110 ;

EMPLOYEE_ID FIRST_NAME               SALARY
----------- -------------------- ----------
        205 Shelley                   12008
        206 William                    8300

-- 您可以使用组函数执行另一个SQL语句来检索这些信息。

DECLARE l_total INTEGER; 
BEGIN 
   UPDATE employees 
      SET salary = salary * 2 
    WHERE DEPARTMENT_ID = 110;
   -- 要做SUM运算,需要写很多代码。
   SELECT SUM (salary) 
     INTO l_total 
     FROM employees 
    WHERE DEPARTMENT_ID = 110;
 
   DBMS_OUTPUT.put_line (l_total); 
END;

-- 可以在PL/SQL中执行计算。使用RETURNING可以收回所有修改后的工资。然后对它们进行迭代,一条语句完成总和。

DECLARE 
   l_salaries   DBMS_SQL.number_table; 
   l_total      INTEGER := 0; 
BEGIN 
      UPDATE employees 
         SET salary = salary * 2 
       WHERE DEPARTMENT_ID = 110
   RETURNING salary 
        BULK COLLECT INTO l_salaries; 
 
   FOR indx IN 1 .. l_salaries.COUNT 
   LOOP 
      l_total := l_total + l_salaries (indx); 
   END LOOP; 
 
   DBMS_OUTPUT.put_line (l_total); 
END;
/

在这里插入图片描述

您可以在RETURNING子句中直接调用SUM、COUNT等,从而在将数据返回到PL/SQL块之前执行分析。非常酷

Yes! You can call SUM, COUNT, etc. directly in the RETURNING clause and thereby perform analytics before you return the data back to your PL/SQL block. Very cool.

HR@orcl> select EMPLOYEE_ID, FIRST_NAME,SALARY FROM employees WHERE DEPARTMENT_ID = 110 ;

EMPLOYEE_ID FIRST_NAME               SALARY
----------- -------------------- ----------
        205 Shelley                   12008
        206 William                    8300

DECLARE l_total INTEGER; 
BEGIN 
  UPDATE employees 
     SET salary = salary * 2 
   WHERE DEPARTMENT_ID = 110
  RETURNING SUM (salary) INTO l_total; 
  DBMS_OUTPUT.put_line (l_total); 
END;
/

在这里插入图片描述

4、RETURNING与EXECUTE IMMEDIATE一起使用

you can also use RETURNING with EXECUTE IMMEDIATE (for dynamically constructed and executed SQL statements).
还可以将RETURNING与EXECUTE IMMEDIATE一起使用(用于动态构建和执行的SQL语句)

4.1、在执行动态SQL语句时,利用RETURNING子句返回单行

DECLARE  
   l_EMPLOYEE_ID   employees.EMPLOYEE_ID%TYPE;  
BEGIN  
   EXECUTE IMMEDIATE 
   q'[UPDATE employees  
         SET FIRST_NAME = FIRST_NAME || '-1' 
       WHERE EMPLOYEE_ID=206
      RETURNING EMPLOYEE_ID INTO :one_para_id]'       
   RETURNING INTO l_EMPLOYEE_ID;  
  
   DBMS_OUTPUT.put_line (l_EMPLOYEE_ID);   
END;
/

在这里插入图片描述

4.2、在执行动态SQL语句时,利用RETURNING子句返回多行

DECLARE  
   l_EMPLOYEE_ID   DBMS_SQL.number_table;  
BEGIN  
   EXECUTE IMMEDIATE 
   q'[UPDATE employees  
         SET FIRST_NAME = FIRST_NAME || 'list' 
	  WHERE DEPARTMENT_ID = 110
      RETURNING EMPLOYEE_ID INTO :para_list]'       
   RETURNING BULK COLLECT INTO l_EMPLOYEE_ID;  
  
   FOR indx IN 1 .. l_EMPLOYEE_ID.COUNT  
   LOOP  
      DBMS_OUTPUT.put_line (l_EMPLOYEE_ID (indx));  
   END LOOP;  
END;
/

在这里插入图片描述

5、限制和注意事项

  • RETURNING子句不能与并行DML操作或远程对象一起使用。

  • 在通过视图向基表中插入数据时,RETURNING子句只能与单基表视图一起使用。

  • 对于UPDATE和DELETE语句,RETURNING子句可以返回旧值(在Oracle 23ai/c及更高版本中增强)和新值,但对于INSERT语句,它只返回新值(因为插入前没有旧值)。

  • 在使用RETURNING子句时,必须确保返回的列与INTO子句中指定的变量类型兼容。

  • 在动态SQL中使用RETURNING子句时,需要注意绑定变量的使用,并且RETURNING BULK COLLECT INTO通常需要在

6、Oracle 23ai/c及更高版本中

在Oracle 23c及更高版本中,你可以使用FLASHBACK QUERY或AS OF VERSIONS BETWEEN子句(在适当的情况下)与RETURNING子句结合来访问旧值,但这通常不是直接返回旧值和新值的方式。实际上,更常见的是利用Oracle的闪回技术(如Flashback Data Archive)或触发器(Triggers)来捕获旧值。

但是,对于UPDATE和DELETE操作,如果你想要在同一个操作中同时获取旧值和新值,你可能需要采取以下策略之一:

  1. 使用触发器:在UPDATE或DELETE操作之前,使用触发器来捕获旧值,并将它们存储在另一个表或PL/SQL变量中。然后,你可以通过RETURNING子句获取新值。
  2. 使用PL/SQL变量:如果你正在执行单行操作,你可以在PL/SQL中先查询要更新的行以获取旧值,然后执行UPDATE或DELETE操作,并使用RETURNING子句获取新值。
  3. 利用Oracle的内置功能(如果可用):在某些Oracle版本中,可能有特定的内置函数或特性允许你同时访问旧值和新值,但这通常不是通过RETURNING子句直接实现的。
  4. 使用版本化表(如Oracle Total Recall或Flashback Data Archive):这些特性允许你查询表的历史版本,从而可以间接地获取旧值。
  5. 在SQL*Plus或SQLcl中使用SET SERVEROUTPUT ON和DBMS_OUTPUT.PUT_LINE:虽然这不会直接返回旧值和新值到客户端,但你可以在PL/SQL块中使用这些工具来打印出你在执行DML操作时捕获的旧值和新值。

请记住,RETURNING子句本身在Oracle 23c及更高版本中并没有直接提供返回旧值和新值的功能。相反,它主要用于在DML操作后返回新值给PL/SQL程序或触发器中的变量。如果你需要旧值,你可能需要结合使用其他Oracle特性或策略。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

EtherCAT通讯介绍

一、EtherCAT简介 EtherCAT(Ethernet for Control Automation Technology)是一种实时以太网技术,是由德国公司Beckhoff Automation在2003年首次推出的。它是一种开放的工业以太网标准,被设计用于满足工业自动化应用中的高性能和低…

【JVM排查问题】JProfiler性能分析工具连接远程服务器Docker容器中的Java服务

1、下载JProfiler https://www.ej-technologies.com/download/jprofiler/version_13 下载Windows版本以及Linux版本 Windows用于可视化、Linux用于在Docker容器中启动 2、将Linux版本的JProfiler上传到Docker容器中,宿主机cp命令到容器中 docker cp /home/data/s…

项目管理实用表格与应用【项目文件资料分享】

项目管理基础知识 项目管理可分为五大过程组(启动、规划、执行、监控、收尾)十大知识领域,其中包含49个子过程 项目十大知识领域分为:项目整合管理、项目范围管理、项目进度管理、项目成本管理、项目质量管理、项目资源管理、项目…

Nginx系列(二)---Mac上的快速使用

一、安装 前置软件&#xff1a;Homebrew 安装方法&#xff1a;终端输入/bin/bash -c "$(curl -fsSL <https://cdn.jsdelivr.net/gh/ineo6/homebrew-install/install.sh>)"更新&#xff1a; brew update 设置中科大镜像源&#xff1a;git -C "$(brew --r…

蓝牙模块的使用01,OOOLMF蓝牙模块HC05调试使用01AT设置从机,手机用软件对接

参考资料 https://blog.csdn.net/xia3976/article/details/122199162 1、实验目的 验证蓝牙模块是不是好的&#xff0c;能不能AT指令改变查询配置&#xff1b; 验证设置从机模式&#xff0c;成功之后&#xff0c;用手机现成的蓝牙软件&#xff08;实验室大群里面有&#xff09…

springboot 篮球馆管理系统-计算机毕业设计源码21945

目 录 摘要 1 绪论 1.1选题背景 1.2研究意义 1.3论文结构与章节安排 2 篮球馆管理系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分析 2.3 系统用例分析 2.4 …

程序员的职业发展有几个选择?程序员转行的困惑与方向!

面对着日新月异的代码和语言&#xff0c;你是否感到了力不从心&#xff1f;稍有懈怠&#xff0c;就跟不上岗位需要了&#xff1f;身体渐渐的发福&#xff0c;熬夜写代码开始扛不住了吗&#xff1f; 对于老板来说&#xff0c;永远都存在更年轻、更便宜的选择。老实说&#xff0c…

高校搭建AIGC新媒体实验室,创新新闻教育教学模式

高校作为人才培养的重要阵地&#xff0c;必须紧跟时代步伐&#xff0c;不断创新教育教学模式&#xff0c;提升跨界融合育人水平&#xff0c;通过AIGC新媒体实验室探索创新人才培养模式。AIGC新媒体实验室不仅能够高效赋能高校宣传媒体矩阵&#xff0c;也可以助力教学实践与AIGC…

KUKA机器人中断编程3—暂停功能的编程

在KUKA机器人的使用过程中&#xff0c;对于调试一个项目&#xff0c;当遇到特殊情况时需要暂停机器人&#xff0c;等异常情况处理完成后再继续机器人的程序运行。wait for指令是等待一个输入信号指令&#xff0c;没有输入信号&#xff0c;机器人一直等待。在一定程度上程序也不…

vue3中使用Antv G6渲染树形结构并支持节点增删改

写在前面 在一些管理系统中&#xff0c;会对组织架构、级联数据等做一些管理&#xff0c;你会怎么实现呢&#xff1f;在经过调研很多插件之后决定使用 Antv G6 实现&#xff0c;文档也比较清晰&#xff0c;看看怎么实现吧&#xff0c;先来看看效果图。点击在线体验 实现的功能…

仓颉——申请内测、环境搭建、编译测试

2024年6月21日&#xff0c;华为仓颉正式公开发布。 不少同学看过仓颉白皮书后&#xff0c;都在找SDK从哪下载&#xff0c;HelloWorld怎么跑。仓颉公众号也及时发布了内测的方式&#xff0c;我也亲自走了一遍整个流程&#xff0c; 一&#xff0c;申请内测 关注“仓颉编程语言…

香橙派AIpro做目标检测

使用香橙派AIpro做目标检测 文章目录 使用香橙派AIpro做目标检测香橙派AIpro开发板介绍香橙派AIpro应用体验YOLOV5s目标检测使用场景描述图像目标检测视频目标检测摄像头目标检测YOLOv5s 目标检测的运行结果分析香橙派 AIpro 在运行过程中的表现 香橙派AIpro AI应用场景总结 香…

leetCode-hot100-动态规划专题

动态规划 动态规划定义动态规划的核心思想动态规划的基本特征动态规划的基本思路例题322.零钱兑换53.最大子数组和72.编辑距离139.单词拆分62.不同路径63.不同路径Ⅱ64.最小路径和70.爬楼梯121.买卖股票的最佳时机152.乘积最大子数组 动态规划定义 动态规划&#xff08;Dynami…

Python 项目依赖离线管理 pip + requirements.txt

背景 项目研发环境不支持联网&#xff0c;无法通过常规 pip install 来安装依赖&#xff0c;此时需要在联网设备下载依赖&#xff0c;然后拷贝到离线设备进行本地安装。 两台设备的操作系统、Python 版本尽可能一致。 离线安装依赖 # 在联网设备上安装项目所需的依赖 # -d …

香港即将“放松”加密货币监管!加密牌照制度备受批评!全球主力军无法进入香港市场?动摇了香港Web3的信心!

2024年7月3日&#xff0c;香港金融服务及库务局局长许正宇在立法会会议上表示&#xff0c;香港金融管理局(HKMA)和证券及期货事务监察委员会(SFC)将根据市场发展情况&#xff0c;适时检讨虚拟资产相关活动的监管要求。 这一表态引发了人们对香港加密货币监管框架可能进行调整的…

AI智能音箱用2×15W立体声功放芯片NTP8918

智能音箱是近年来非常受欢迎的智能家居产品之一&#xff0c;它集成了人工智能技术和音频技术&#xff0c;能够为用户提供语音助手、音乐播放、智能家居控制等多种功能。其中&#xff0c;音频输出是智能音箱的核心功能之一&#xff0c;而功放芯片则是实现音频放大的关键组成部分…

尽量不写一行if...elseif...写出高质量可持续迭代的项目代码

背景 无论是前端代码还是后端代码&#xff0c;都存在着定位困难&#xff0c;不好抽离&#xff0c;改造困难的问题&#xff0c;造成代码开发越来越慢&#xff0c;此外因为代码耦合较高&#xff0c;总是出现改了一处地方&#xff0c;然后影响其他地方&#xff0c;要么就是要修改…

Liunx网络配置

文章目录 一、查看网络配置永久修改网卡临时修改网卡 二、查看主机名称 hostname三、查看路由表条目 route四、查看网络连接情况netstat五、获取socket统计信息ss六、查看当前系统中打开的文件和进程的工具lsof七、测试网络连通性ping八、跟踪数据包 traceroute九、域名解析 ns…

适合金融行业的国产传输软件应该是怎样的?

对于金融行业来说&#xff0c;正常业务开展离不开文件传输场景&#xff0c;一般来说&#xff0c;金融行业常用的文件传输工具有IM通讯、邮件、自建文件传输系统、FTP应用、U盘等&#xff0c;这些传输工具可以基础实现金融机构的文件传输需求&#xff0c;但也存在如下问题&#…

ONNXRuntime与CUDA所对应的版本

官方链接&#xff1a; NVIDIA - CUDA | onnxruntime