0

我有一个 Oracle 数据库(带有 12.1 客户端位的 11.2 服务器端),其中包含许多返回 SYS_REFCURSOR 对象类型的存储过程。

我尝试通过 Visual Studio 2017 (15.6.3) 和 Oracle Managed DataAccess 客户端 (12.1) 中的添加新 ADO.NET 实体数据模型向导导入这组程序。但是当我访问这些存储过程时,我会遇到如下异常: PLS-00306: wrong number or types of arguments in call to 'my_procedure'

此类 Oracle 存储过程的示例如下所示:

create or replace PROCEDURE my_procedure (
       input               IN  VARCHAR2,
       cur_output OUT SYS_REFCURSOR
)
IS
BEGIN
    OPEN cur_output FOR
    SELECT    col1
    ,    col2
    ,    col3
    FROM my_table
    WHERE col1 = input;
    EXCEPTION
        WHEN NO_DATA_FOUND THEN
            NULL;
        WHEN OTHERS THEN    
            RAISE;
END my_procedure;

生成的模型 xml 如下所示:

<Function Name="my_procedure" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="myschema">
    <Parameter Name="input" Type="varchar2" Mode="In" />
</Function>

生成的 C# 代码如下所示:

public virtual int my_procedure(string input) {
    var inputParameter = input != null ?
        new ObjectParameter("input", input) :
        new ObjectParameter("input", typeof(string));

    return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("my_procedure", inputParameter);
}

我玩了一下手动调用 Oracle DataAccess API,以下代码有效:

OracleConnection conn = new OracleConnection(...);  
conn.Open();
using (OracleCommand cmd = new OracleCommand("my_procedure", conn)) {
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("input", OracleDbType.Varchar2).Value = "myinput";                
    cmd.Parameters.Add("cur_output", OracleDbType.RefCursor, null, ParameterDirection.Output);
    var dr = cmd.ExecuteReader();
    dr.Read();
    var col1id = dr.GetOrdinal("col1");
    var valuecol1 = SafeGetString(dr, col1id);
}
conn.Dispose();

理想情况下,我希望有一个自动化过程来生成正确的 C# 代码来访问存储过程。解决此问题的最实用方法是什么?

4

1 回答 1

0

您将存储过程定义为带有两个参数的 my_procedure,input 和 cur_output。当您在 C# 中调用此过程时,您还应该传递一个参数FOR BOTH input 和 cur_output。过程不是返回值的函数。过程会将输出分配给您分配为 OUT 参数的变量,在本例中命名为 cur_output。

于 2018-03-25T20:18:45.677 回答