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

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

于是动手一试:

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

CREATE OR REPLACE FUNCTION F_Update_Grade(v_UserID in Number)
 return nvarchar2 is
 V_Grade nVARCHAR2(20);
begin
 V_Grade := '1205';
 update TESTDB3 set Grade = V_Grade where PKID = v_UserID;
 commit;
 return (V_Grade);
end F_Update_Grade;

正常调用返回:

declare
 V_Result nvarchar2(1000) := '';
 V_UserID number(10) := 1;
begin
 V_Result := f_update_grade(V_UserID);
  dbms_output.put_line('Value:' || V_Result);
end;

/*
Value:1205
*/

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

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

2、核心访问代码:

using Oracle.ManagedDataAccess.Client;
using System;
using System.Data;
using System.Data.SqlClient;

namespace TestOracle_ManagedDataAccess
{
  class Program
  {
    static void Main(string[] args)
    {
      TestFUNCTION3();
      Console.ReadLine();
    }

    static void TestFUNCTION3()
    {
      string strConn = "Data Source=127.0.0.1/BCS;User ID=user2019;Password=password9102";
      //OracleConnection objConn = new OracleConnection(strConn);
      string strFun = "F_Update_Grade";
      //string strFun = "F_Get_Grade";
      using (OracleConnection objConn = new OracleConnection(strConn))
      {
        using (OracleCommand cmd = new OracleCommand(strFun, objConn))
        {
          try
          {
            // 获取选中行
            //int strRowIdex = 1;

            // 创建参数对象
            OracleParameter p1 = new OracleParameter("v_UserID", OracleDbType.Int32, ParameterDirection.Input);
            OracleParameter p2 = new OracleParameter("V_Grade", OracleDbType.NVarchar2, 20);
            p1.Value = 1;//取PKID为1的记录
            p2.Direction = ParameterDirection.ReturnValue;
            // 更新数据库表
            cmd.CommandType = CommandType.StoredProcedure;
            objConn.Open();

            /***************************************************************
             * 注意,输出参数一定要第一个加,函数的返回值也是赋给第一个参数*;
             * *************************************************************/
            cmd.Parameters.Add(p1);
            cmd.Parameters.Add(p2);
            cmd.ExecuteNonQuery();

            //返回结果值
            Console.WriteLine("V_Grade is :" + p2.Value.ToString());
            Console.WriteLine("OK");
          }
          catch (SqlException ex)
          {
            objConn.Close();
            Console.WriteLine("ERROR in :" + ex.Message);
          }
          finally
          {
            cmd.Dispose();
            objConn.Close();
          }
        }
      }
    }

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

update testdb3 set grade=1 where PKID=1;

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

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

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

小结:

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#利用ODP.net连接Oracle数据库的操作方法

    本文介绍了C#连接Oracle数据库的过程.通过instant client和ODP.net中的Oracle.DataAccess.dll,我们就可以方便的部署.net应用程序或者站点,而不需要安装Oracle客户端.接下来我们就介绍这一过程. 1. ODAC的安装 在oracle的官方网站上下载与你安装的oracle对应版本的ODAC. 下载地址:ODAC Download 下载好后解压安装,安装时不用安装全部的组件.主要安装以下组件: Oracle Instant Client Oracle

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

    有人在社区问到:C#调用Oracle中自定义函数的返回值时,无法正常调用.但在PL/SQL中正常调用返回. 于是动手一试: 1.准备函数(Oralce 11g.2.0.0.4) CREATE OR REPLACE FUNCTION F_Update_Grade(v_UserID in Number) return nvarchar2 is V_Grade nVARCHAR2(20); begin V_Grade := '1205'; update TESTDB3 set Grade = V_Gr

  • python读取oracle函数返回值

    在oracle中创建一个函数,本来是想返回一个index table的,没有成功.想到文本也可以传输信息,就突然来了灵感,把返回值设置文本格式. 考虑到返回数据量可能会很大,varchar2类型长度吃紧,于是将返回值类型设置为clob.  我是用scott用户的测试表emp,这个是函数定义情况: create or replace function test_query_func(dept varchar2) return clob is type test_record is record (

  • python 定义函数 返回值只取其中一个的实现

    看代码吧~ def test(): return 1,2 a, b = test() 1 2 a, _ = test() 1 # 说明 a, _ = test() 中 返回的是一个int类型 后续可直接运算 # a, b = test() 返回值是一个元组, 直接运算报错 补充:Python-装饰器(被装饰函数有返回值的情况) 题目: 装饰器实现一个函数计时器比较for循环与map,匿名函数的运算速度 问题: 被装饰的函数有返回值怎么办 程序内容: import time import rand

  • Python函数返回值实例分析

    本文实例讲述了Python的函数返回值用法.分享给大家供大家参考.具体分析如下: 最近学一些Python的基本用法,看到定义函数,发现似乎只能返回一个返回值,想想matlab里返回多个返回值多方便啊,网上查了查,看到有返回多个值的方法.   python 函数返回值有两种形式: 1 返回一个值. 2 返回多个值.   现看看返回一个值的吧. def firstvalue(a,b): c = a + b return c print firstvalue(1,2) #结果:3 再看看返回多个值的:

  • 详解C语言函数返回值解析

    详解C语言函数返回值解析 程序一: int main() { int *p; int i; int*fun(void); p=fun(); for(i=0;i<3;i++) { printf("%d\n",*p); p++; } return 0; }; int* fun(void) { static int str[]={1,2,3,4,5}; int*q=str; return q; } //不能正确返回 虽然str是在动态变量区,而该动态变量是局部的,函数结束时不保留的.

  • Linux Shell函数返回值

    Shell函数返回值,一般有3种方式:return,argv,echo 1) return 语句 shell函数的返回值,可以和其他语言的返回值一样,通过return语句返回. 示例: #!/bin/bash - function mytest() { echo "arg1 = $1" if [ $1 = "1" ] ;then return 1 else return 0 fi } echo echo "mytest 1" mytest 1 e

  • C语言 用指针作为函数返回值详解

    C语言允许函数的返回值是一个指针(地址),我们将这样的函数称为指针函数.下面的例子定义了一个函数 strlong(),用来返回两个字符串中较长的一个: #include <stdio.h> #include <string.h> char *strlong(char *str1, char *str2){ if(strlen(str1) >= strlen(str2)){ return str1; }else{ return str2; } } int main(){ cha

  • Shell $?获取函数返回值或者上一个命令的退出状态

    $? 是一个特殊变量,用来获取上一个命令的退出状态,或者上一个函数的返回值. 所谓退出状态,就是上一个命令执行后的返回结果.退出状态是一个数字,一般情况下,大部分命令执行成功会返回 0,失败返回 1,这和C语言的 main() 函数是类似的. 不过,也有一些命令返回其他值,表示不同类型的错误. 1) $? 获取上一个命令的退出状态 编写下面的代码,并保存为 test.sh: #!/bin/bash if [ "$1" == 100 ] then exit 0 #参数正确,退出状态为0

  • 通过实例详解C语言函数返回值

    目录 前言 C语言返回值 c语言函数调用后必须带回返回值? 总结 前言 函数的返回值是指函数被调用之后,执行函数体中的代码所得到的结果,这个结果通过 return 语句返回. return 语句的一般形式为: return 表达式; 或者: return (表达式); 有没有( )都是正确的,为了简明,一般也不写( ).例如: return max; return a+b; return (100+200); C语言返回值 1 . 没有返回值的函数为空类型,用void表示.例如: void fu

  • 解析go语言调用约定多返回值实现原理

    目录 go简单代码反汇编 go语言调用约定分析 1.C/C++调用约定类别 2.go语言调用约定 go语言如何实现多返回值的 总结 go简单代码反汇编 用简单的代码用以分析go的调用约定及多返回值的返回方式. package main func vals(c, d int) (a int, b int) { e := 1 f := 2 a = c + d + e + f b = d * 2 return } func testMutil() { i, j := vals(1, 2) i = i

随机推荐