如何在Oracle存储过程发生异常时获取out类型参数的值

news2024/10/7 11:25:16

Oracle存储过程关于在出现(自定义/自带)异常下out类型参数的获取问题的分析

✈️ 场景:

有一些关于金额和时间的精确且量大的计算需要在存储过程中完成。存储过程中有一些自定义的异常。并且将在RAISE前通过out类型的参数将详细的异常原因返回。

但是在通过Csharp的调用中,发现了很多的问题。需要书面总结。

💥问题点1:存储过程自身的问题

存储过程中发生异常时,在存储过程中发生异常无法获取out类型参数。

例表:

请添加图片描述

procedure:

create or replace procedure SP_TEST(EXC_MSG out varchar2)
as
    ExcOne EXCEPTION;    --自定义异常
    ExcTwo EXCEPTION;
    item varchar2(10);
    
    cursor curOne is select ABBREVIATION from TB_CM_CPNAME;
begin
    open curOne;
    
    loop
    
    fetch curOne into item;
    exit when curOne%NOTFOUND;
        
        IF(item='云久鴻') then
            exc_msg := 'XXX错误';    --在异常raise前给out参数赋值
            RAISE ExcOne;            --raise异常
        end if;
        
        IF(item='海浪') then
            exc_msg := 'YYY错误';
            RAISE ExcTwo;            --raise异常
        end if;
    end loop;
end;

测试执行语句:

SET SERVEROUTPUT ON;
declare
    V_msg varchar2(20);
    
begin
    SP_TEST(V_msg);
    
Exception              --外部执行时尝试获取out参数
    when others then
        DBMS_OUTPUT.put_line('COUT<<'||v_msg);
end;

结果:

请添加图片描述

当在存储过程中去处理异常

修改存储过程:

create or replace procedure SP_TEST(EXC_MSG out varchar2)
as
    ExcOne EXCEPTION;    --自定义异常
    ExcTwo EXCEPTION;
    item varchar2(10);
    
    cursor curOne is select ABBREVIATION from TB_CM_CPNAME;
begin
    open curOne;
    loop
    
    fetch curOne into item;
    exit when curOne%NOTFOUND;
        IF(item='云久鴻') then
            exc_msg := 'XXX错误';
            RAISE ExcOne;            --raise异常
        end if;
        
        IF(item='海浪') then
            exc_msg := 'YYY错误';
            RAISE ExcTwo;            --raise异常
        end if;
    end loop;
    
    EXCEPTION                        --在SP内处理异常
        when ExcOne then
        ROLLBACK;
        --RAISE  注意不在再向上抛异常,不然还是获取不到out参数
        when ExcTwo then
        ROLLBACK;
end;

测试:

请添加图片描述

💥问题点2 :在外部调用中获取out参数

关于:

一般不会写了个存储过程只通过sql去调用,大部分情况是通过其他的外部语言来调用。所以对于外部调用来获取out参数又是一个需要注意的问题。

🌀使用C#调用oracle存储过程

Dapper调用存储过程

namespace UnitTest
{
    [TestFixture]
    public class TestDual
    {
        private IServiceProvider provider;

        [SetUp]
        public void SetUp()
        {
            var collection = new ServiceCollection();
			//这是一个Dapper实现的执行sql工具
            collection.AddSingleton(new SqlDapperService("XXXX", Db_Type.DbName.Oracle,
                "XXXX","XXXX" ));

            provider =  collection.BuildServiceProvider();
        }

        [Test]
        public void RealTest()
        {
            SqlDapperService dapper = provider.GetService<SqlDapperService>();

            string EXC_MSG = $@"传参前";

            int res = dapper.ExcuteNonQuery("sp_test", new { EXC_MSG }, CommandType.StoredProcedure);

            Console.WriteLine($@"COUT<<"+EXC_MSG);
        }
    }
}

测试结果:并没有获取到out类型参数的值

请添加图片描述

ADO.NET 原生方式获取

/// <summary>
/// ADO.NET 测试调用存储过程
/// </summary>
[TestFixture]
public class ADO_test
{
    [Test]
    public void TestOne()
    {
        
        using(var conn = new OracleConnection(Encrypter.DecryptAES("XXXXX",
            "xxxx", "xxxxx")))
        {
            conn.Open();

            OracleCommand command = conn.CreateCommand();

            command.CommandText = "SP_TEST";
            command.CommandType = System.Data.CommandType.StoredProcedure;
		   //设置out参数
            OracleParameter outparm = command.Parameters.Add("EXC_MSG", OracleDbType.Varchar2, ParameterDirection.Output);
            outparm.Size = 200; //参数的长度

            command.ExecuteNonQuery();

            Console.WriteLine(outparm.Value) ;输出
        }
    }
}

请添加图片描述

小节

如果想要在Oracle的存储过程发生异常时获取out类型的参数,需要

  • 在SP中处理异常,且不要再向上抛出(再次抛出会导致out类型参数的值被清除)
  • 在数据库外部调用时,尽量选择原生的调用方式

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

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

相关文章

商业智能BI分析报表很慢是什么原因?应该如何优化?

当下&#xff0c;数据计算已成为了分析工作中必不可少的高频次操作之一&#xff0c;而且在大数据的发展背景下&#xff0c;应用性能往往关系着项目的成败&#xff0c;成为了大家最为关注的产品技术参数。那么我们先来分析一下BI分析表计算很慢的原因是什么&#xff0c;再对症下…

Microsoft Dynamics 365 Business Central 生产订单扣料的几种方法

学习目标&#xff1a; 掌握生产订单扣料的几种方法 学习内容&#xff1a; Forward flush by routing operation&#xff08;通过工序&#xff1a;向前扣料&#xff09;Backward flush by routing operation&#xff08;通过工序&#xff1a;向后扣料&#xff09;Forward flus…

Java-Redis持久化之RDB操作

Java-Redis持久化之RDB操作 1.为什么redis需要持久化&#xff1f;2.什么是RDB操作?3.请你用自己的话讲下RDB的过程?4.如何恢复rdb文件? 1.为什么redis需要持久化&#xff1f; Redis是内存数据库&#xff0c;如果不将内存数据库保存到磁盘&#xff0c;那么服务器进程退出&am…

匿名对象的特性和使用场景你知道吗?

目录 一、匿名对象的概念 二、单参数和多参数构造场景的匿名对象 ①只有一个参数的构造函数 ②多个参数的构造函数 三、使用匿名对象作为函数的参数的缺省值 四、只为调用类中的一个函数时 五、匿名对象的特性 1、匿名对象的生命周期只有一行 2、匿名对象具有常性 3、当匿…

今天去面一个点工,HR要我会数据库,Linux还有Python,这合理吗?

软件测试出路在哪&#xff1f; 业务编程&#xff01;&#xff01; 1、软件测试的变化趋势 变化趋势1&#xff1a; 功能测试是核心&#xff0c;但是价值降低 目前测试这个行业&#xff0c;还是有大量的点工。但是行业的进步&#xff0c;技术的创新&#xff0c;导致了企业的需求…

不用下载的网页版Axure在这里

作为一名产品经理&#xff0c;你一定需要一款能够帮助你更好更快地制作原型&#xff0c;更方便地和团队协作的软件。网页版Axure工具替代即时设计无需下载激活&#xff0c;就可免费使用。那么&#xff0c;Axure网页版工具替代即时设计是如何进行的呢&#xff1f; 首先&#xf…

【数据结构】双向带头循环链表

文章目录 一、什么是带头双向循环链表二、带头双向循环链表的实现&#xff08;一&#xff09;链表中结构体的声明&#xff08;二&#xff09;头节点的创建&#xff08;链表的初始化&#xff09;&#xff08;三&#xff09;新节点的创建&#xff08;四&#xff09;链表的尾插&am…

( 位运算 ) 231. 2 的幂 ——【Leetcode每日一题】

❓231. 2 的幂 难度&#xff1a;简单 给你一个整数 n&#xff0c;请你判断该整数是否是 2 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 如果存在一个整数 x 使得 n 2 x n 2^x n2x &#xff0c;则认为 n 是 2 的幂次方。 示例 1&…

软考高级架构师笔记1-计算机硬件

目录 1. 前言 & 更新2. CPU组成3. CPU的指令集:4.存储器5. 总线1. 前言 & 更新 注意:绪论不考,直接略过。 计算机硬件章节19-21年没考过,在22年真题考过磁盘调度,根据趋势分析,以后考的概率也不大,了解即可。 本节删掉了第一版中的编码、海明码等内容。 2. CP…

一篇文章搞定《Android异常处理》

------《Android异常处理》 异常种类&#xff08;简述&#xff09;编译时异常运行时异常 运行时的异常和崩溃受检时的异常第一种做法&#xff1a;第二种做法&#xff1a; 不受检时的异常(崩溃Crash)异常的传播崩溃的兜底Looper 循环问题主流程抛出异常问题 安全气囊的实现方案设…

计算机组成原理---第六章总线系统 习题详解版

&#xff08;一&#xff09;课内习题 &#xff08;二&#xff09;课后习题 1.比较单总线、多总线结构的性能特点。 答&#xff1a; &#xff08;1&#xff09; 单总线结构:它是用单一的系统总线连接整个计算 机系统的各大功能部件,各大部件之间的所有的信息传送都通过这组总线…

【企业信息化】第6集 免费开源ERP: Odoo 16 MRP + 维护+ PLM +质量全面生产制造管理

文章目录 一、MRP 物料需求计划1.一款软件&#xff0c;满足您的所有需要2.工作中心控制面板3.优化您的库存等级4.条形码&#xff0c;即开即用5.出色报告关键绩效指标6.与其他Odoo应用程序完全集成 二、PLM 产品生命周期管理1.管理工程变更2.集成文件管理3.智能版本管理4.与其他…

还在为项目初始化、依赖管理问题困扰?Dubbo Initializer 来了!

作者&#xff1a;Dubbo 社区 通过这篇文章&#xff0c;你将学习如何在 1 分钟内用 Dubbo Initializer 模板快速创建 Dubbo Spring Boot 项目&#xff0c;帮你解决项目初始化问题。 什么是 Dubbo Initializer&#xff1f; Dubbo Initializer 是一款帮助开发者快速生成 Dubbo …

【0基础也能学会】JMeter:如何开始简单的WEB压力测试?

背景 最近工作上被安排针对Web网站进行性能压测&#xff0c;以评估特定的硬件配置下Web网站可支持的并发用户数。考虑到JMeter是流行的Web性能压测工具&#xff0c;因此趁着这次机会上网查阅了很多关于JMeter的资料&#xff0c;也自己动手进行软件的配置和调测&#xff0c;从最…

前瞻洞察|借助机器学习,揪出利用DNS隐蔽隧道作恶黑手

黑客会利用DNS协议进行违法犯罪活动&#xff0c;那DNS协议到底是什么&#xff1f;它有何作用&#xff1f;为什么会被选作进行作恶的手段&#xff1f;会造成什么危害&#xff1f;怎么检测及研究现状如何&#xff1f;一连串疑问接踵而至。本篇文章中&#xff0c;我们会为大家一一…

【Java多线程编程】Thread类

Thread类是什么&#xff1f; Thread 类是 Java 提供的一个标准库&#xff0c;我们可以通过 Thread 类进行多线程编程。因此&#xff0c;今天我给大家讲解的是如何使用 Thread 类进行线程编程。 详细讲解 Thread 类中的&#xff1a;lambda 表达式、start 方法&#xff08;启动线…

WiFi(Wireless Fidelity)基础(七)

目录 一、基本介绍&#xff08;Introduction&#xff09; 二、进化发展&#xff08;Evolution&#xff09; 三、PHY帧&#xff08;&#xff08;PHY Frame &#xff09; 四、MAC帧&#xff08;MAC Frame &#xff09; 五、协议&#xff08;Protocol&#xff09; 六、安全&#x…

Cloud Kernel SIG月度动态:发布ANCK 5.10、4.19新版本,ABS新增仓库构建功能

Cloud Kernel SIG&#xff08;Special Interest Group&#xff09;&#xff1a;支撑龙蜥内核版本的研发、发布和服务&#xff0c;提供生产可用的高性价比内核产品。 01 SIG 整体进展 发布 ANCK 5.10-014 版本。 发布 ANCK 4.19-027.2 版本。 ABS 平台新增 OOT 仓库临时构建功…

如何远程控制电脑?3个方法轻松搞定!

案例&#xff1a;如何远程控制电脑&#xff1f; 【我不想时时刻刻都带着自己的电脑&#xff0c;听朋友说可以远程电脑。有没有大神分享一下具体的操作方法&#xff1f;感谢&#xff01;】 随着科技的不断进步&#xff0c;远程控制电脑已经不再是一件难以实现的事情。如今&…

09.python可视化-Seanorn绘制类别关系图boxplot() boxenplot() violinplot()

分类散点图 分类分布图 1). 箱线图 : boxplot() 2).增强箱图boxenplot() 3).小提琴图 :violinplot() 分类统计图 2. 分类分布图 1). 箱线图 应用场景&#xff1a;主要用来显示与类别相关的数据分布。 seaborn.boxplot(xNone, yNone, hueNone, dataNone, orderNone, hue_orde…