我有一个 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# 代码来访问存储过程。解决此问题的最实用方法是什么?