欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.Net Core调用oracle存储过程

程序员文章站 2022-05-28 14:37:27
一 前言 实战踩坑系列,调用第三方Oracle存储,各种血泪史,现记录如下。 二 入坑 首先,调用Oracle需要安装客户端驱动才行,但是在程序开发中下载客户端驱动是一个不明智的选择。于是,不管是微软,还是oracle,都提供了方便我们程序开发的插件(dll/nuget),如System.Data. ......

一 前言

  实战踩坑系列,调用第三方oracle存储,各种血泪史,现记录如下。

二 入坑

  首先,调用oracle需要安装客户端驱动才行,但是在程序开发中下载客户端驱动是一个不明智的选择。于是,不管是微软,还是oracle,都提供了方便我们程序开发的插件(dll/nuget),如system.data.oracle,oracle.manageddataaccess。下图搜索结果中oracle.manageddataaccess.entityframework包含oracle.manageddataaccess,适用于.net framework,如果你想要使用ef的话。因为这里是netcore程序,所以我选择了oracle.manageddataaccess.core包。

.Net Core调用oracle存储过程

  初始程序:

private static void remote()
{
    // 创建oracle连接
    var connstring = "user id=user;password=password;data source=ip:port/service_name;";

    // 存储过程名称
    var storedprocname = "settemperaturedata";

    // 参数设置
    idataparameter[] parameters = new idataparameter[2];
    parameters[0] = new oracleparameter("@id", 1);
   parameters[1] = new oracleparameter("@date", datetime.now); parameters[2] = new oracleparameter("@result", oracledbtype.decimal, parameterdirection.output); using (oracleconnection conn = new oracleconnection(connstring)) using (oraclecommand command = buildquerycommand(conn, storedprocname, parameters)) { try { conn.open(); var issuccess = command.executenonquery(); var result = (int)command.parameters["@result"]; } catch (exception ex) { console.writeline(ex.tostring()); } } } private static oraclecommand buildquerycommand(oracleconnection connection, string storedprocname, idataparameter[] parameters) { oraclecommand command = new oraclecommand(storedprocname, connection); command.commandtype = commandtype.storedprocedure; foreach (oracleparameter parameter in parameters) { command.parameters.add(parameter); } return command; }

  运行程序报错:

  错误1:.Net Core调用oracle存储过程

    产生原因:对接方提供的链接是从库地址,只有读权限。

  错误2:.Net Core调用oracle存储过程

    产生原因:存储过程名称问题,缺少了表空间,大概的意思是test.settemperaturedata。

  错误3:.Net Core调用oracle存储过程

    产生原因:入参格式问题,字符串类型和时间类型不统一导致。

  错误4:.Net Core调用oracle存储过程

    产生原因:(int)command.parameters["@result"]不能直接转换,需要进行多次转换convert.todecimal(((oracledecimal)command.parameters["@result"].value).value);

  错误5:.Net Core调用oracle存储过程

    产生原因:了解到第三方oracle采用的是分布式负载均衡的方式,提供了多个ip地址,那原有的链接方式就不适用了,需要采用tsname.oa的方式链接。

.Net Core调用oracle存储过程

  错误6:若你由于粗心大意,也会有所收获

.Net Core调用oracle存储过程

    产生原因:链接字符错误,请仔细检查

三 出坑

   简直是错误大全,哈哈!最后代码粘贴如下:

private static void remote()
{
    // 创建oracle连接
    var connstring = "user id=uer;password=password;data source=test";
    if (string.isnullorwhitespace(oracleconfiguration.oracledatasources["test"]))
    {
        oracleconfiguration.oracledatasources.add("test",
            "(description=(address_list=(address=(protocol=tcp)(host=[ip1])(port=1521))(address=(protocol=tcp)(host=[ip2])" +
            "(port=1521))(load_balance=yes))(connect_data=(server=dedicated)(service_name=service_name))))");
    }

    // 存储过程名称
    var storedprocname = "test.storedprocname";

    // 参数设置
    idataparameter[] parameters = new idataparameter[3];
    parameters[0] = new oracleparameter("@id", 1);
    parameters[1] = new oracleparameter("@date", datetime.now);
    parameters[2] = new oracleparameter("@result", oracledbtype.decimal, parameterdirection.output);

    using (oracleconnection conn = new oracleconnection(connstring))
    using (oraclecommand command = buildquerycommand(conn, storedprocname, parameters))
    {
        try
        {
            conn.open();
            var issuccess = command.executenonquery();
            var result = convert.todecimal(((oracledecimal)command.parameters["@result"].value).value);
        }
        catch (exception ex)
        {
            console.writeline(ex.tostring());
        }
    }
}