简体   繁体   English

如何通过C#调用重载的oracle过程

[英]How to call an overloaded oracle procedure via c#

I have two procedures in a package (TEST_PAK) that are overloaded on Oracle 9i. 软件包(TEST_PAK)中有两个过程,这些过程在Oracle 9i上过载。 One takes a string and one takes an array as parameters. 一个使用字符串,一个使用数组作为参数。 The problem i run into is when i try to call with null as a parameter. 我遇到的问题是当我尝试使用null作为参数调用时。 I am using C# and ODP.NET to call the procedures. 我正在使用C#和ODP.NET来调用过程。

Here's the head of the two procs: 这是两个过程的负责人:

PROCEDURE get_requests_with_files
(
    o_results OUT sys_refcursor, 
    in_communicator IN VARCHAR2, 
    in_state        IN VARCHAR2  -- State of requests wanted (use NULL for ALL records)
)

and

PROCEDURE get_requests_with_files
(
     o_results OUT SYS_REFCURSOR,    
     in_communicator IN VARCHAR2,    
     in_states       IN flagTableType 
)

The flagTypeTable is how i pass in a PLSQLAssociativeArray to my procedure and not really a part of the problem (i think). flagTypeTable是我将PLSQLAssociativeArray传递给过程的方式,但实际上并不是问题的一部分(我认为)。

Here's the C# code i use to call the proc. 这是我用来调用proc的C#代码。

private static DataSet GetRequests(String consumer, List<string> states)
{
    try
    {
        const string query = "TEST_PAK.get_requests_with_files";

        var retVal = new DataSet();
        var oComm = new OracleCommand(query, _oConn);
        var oDa = new OracleDataAdapter(oComm);
        oComm.CommandType = CommandType.StoredProcedure;
        oComm.CommandTimeout = CommandTimeout;

        //Parameters

        oComm.Parameters.Add("o_results", OracleDbType.RefCursor);
        oComm.Parameters["o_results"].Direction = ParameterDirection.Output;

        oComm.Parameters.Add("in_communicator", OracleDbType.Varchar2);
        oComm.Parameters["in_communicator"].Value = consumer;

        if (states.Count != 0)
        {
            oComm.Parameters.Add(new OracleParameter("in_states", OracleDbType.Varchar2)
            {
                CollectionType = OracleCollectionType.PLSQLAssociativeArray,
                Value = states.ToArray()
            });
        }
        else
        {
            oComm.Parameters.Add("in_state", OracleDbType.Varchar2);
            oComm.Parameters["in_state"].Value = null;
        }

        _oConn.Open();

        oDa.Fill(retVal);
        return retVal;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
        return null;
    }
    finally
    {
        if (_oConn.State != ConnectionState.Closed) _oConn.Close();
    }
}

I have tried placing colons in front of the parameters thinking the named parameters would do the trick with no luck. 我尝试将冒号放在参数的前面,以为命名的参数可以成功实现。

I know i can call the code in SQLDeveloper like this: 我知道我可以像这样在SQLDeveloper中调用代码:

variable o_results refcursor;
execute Apps.Base_communicator.get_requests_with_files(:o_results, in_communicator => 'MYCOMM', in_state => null);
print o_results;

So i know the overloads work, just not how to call them in c# 所以我知道重载工作,只是不知道如何在C#中调用它们

I found the solution was to add BindByName to the OracleCommand object. 我发现解决方案是将BindByName添加到OracleCommand对象。 Doing this (and removing the colons) allowed it to bind to the variables by name. 这样做(并删除冒号)可以使其按名称绑定到变量。 This let the overloads work as long as the names were different. 只要名称不同,就可以使重载起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM