C# ODP.NET 调用Oracle函数返回值时报错的一个解决方案

有人在社区问到:C#调用Oracle中自定义函数的返回值时,无法正常调用。但在PL/SQL中正常调用返回。

于是动手一试:

1、准备函数(Oralce 11g.2.0.0.4)

1CREATE OR REPLACE FUNCTION F_Update_Grade(v_UserID in Number) 2 return nvarchar2 is 3 V_Grade nVARCHAR2(20); 4begin 5 V_Grade := '1205'; 6 update TESTDB3 set Grade = V_Grade where PKID = v_UserID; 7 commit; 8 return (V_Grade); 9end F_Update_Grade;

正常调用返回:

1declare 2 V_Result nvarchar2(1000) := ''; 3 V_UserID number(10) := 1; 4begin 5 V_Result := f_update_grade(V_UserID); 6 dbms_output.put_line('Value:' || V_Result); 7end; 8 9/* 10Value:1205 11*/

2、C#环境准备:(VS2019 社区版)

1)准备Oracle.ManagedDataAccess.Client,在Nuget管理器中搜索Oralce,并安装Oracle.ManagedDataAccess最新稳定版19.5

C# ODP.NET 调用Oracle函数返回值时报错的一个解决方案

2、核心访问代码:

1 1 using Oracle.ManagedDataAccess.Client; 2 2 using System; 3 3 using System.Data; 4 4 using System.Data.SqlClient; 5 5 6 6 namespace TestOracle_ManagedDataAccess 7 7 { 8 8 class Program 9 9 { 1010 static void Main(string[] args) 1111 { 1212 TestFUNCTION3(); 1313 Console.ReadLine(); 1414 } 1515 1616 static void TestFUNCTION3() 1717 { 1818 string strConn = "Data Source=127.0.0.1/BCS;User ID=user2019;Password=password9102"; 1919 //OracleConnection objConn = new OracleConnection(strConn); 2020 string strFun = "F_Update_Grade"; 2121 //string strFun = "F_Get_Grade"; 2222 using (OracleConnection objConn = new OracleConnection(strConn)) 2323 { 2424 using (OracleCommand cmd = new OracleCommand(strFun, objConn)) 2525 { 2626 try 2727 { 2828 // 获取选中行 2929 //int strRowIdex = 1; 3030 3131 // 创建参数对象 3232 OracleParameter p1 = new OracleParameter("v_UserID", OracleDbType.Int32, ParameterDirection.Input); 3333 OracleParameter p2 = new OracleParameter("V_Grade", OracleDbType.NVarchar2, 20); 3434 p1.Value = 1;//取PKID为1的记录 3535 p2.Direction = ParameterDirection.ReturnValue; 3636 // 更新数据库表 3737 cmd.CommandType = CommandType.StoredProcedure; 3838 objConn.Open(); 3939 4040 /*************************************************************** 4141 * 注意,输出参数一定要第一个加,函数的返回值也是赋给第一个参数*; 4242 * *************************************************************/ 4343 cmd.Parameters.Add(p1); 4444 cmd.Parameters.Add(p2); 4545 cmd.ExecuteNonQuery(); 4646 4747 //返回结果值 4848 Console.WriteLine("V_Grade is :" + p2.Value.ToString()); 4949 Console.WriteLine("OK"); 5050 } 5151 catch (SqlException ex) 5252 { 5353 objConn.Close(); 5454 Console.WriteLine("ERROR in :" + ex.Message); 5555 } 5656 finally 5757 { 5858 cmd.Dispose(); 5959 objConn.Close(); 6060 } 6161 } 6262 } 6363 }

运行调试,没报错,但也没有更新数据表,注意:在执行前先将原数据表中Grade值更新为1,程序运行后Grade值仍为1。

update testdb3 set grade=1 where PKID=1;

跟踪调试,发现参数值不对,  p2.Direction = ParameterDirection.ReturnValue;,结果返回值给p1。

C# ODP.NET 调用Oracle函数返回值时报错的一个解决方案

莫非,默认给的是第一个参数,调换p1,p2的顺序,果然正常调用:

C# ODP.NET 调用Oracle函数返回值时报错的一个解决方案

运行结果,数据表中的行也更新完成:

C# ODP.NET 调用Oracle函数返回值时报错的一个解决方案

小结:

Oracle.ManagedDataAccess.Client调用有返回值的函数时, cmd.Parameters.Add的第一个参数一定要是ParameterDirection.ReturnValue。不确定这是不是一个bug?

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )