从 ASP.NET 中的 Oracle DB 函数读取数据 table

Read data table from Oracle DB function in ASP.NET

背景

我是一名 .NET 开发人员,几乎没有 Oracle 经验。一位客户向我们提供了我们需要针对其网络上的数据库执行的 Oracle 函数的详细信息。它 return 是 table 的数据。我需要在 ASP.NET 中使用它。

问题

我们有一台可以建立连接的服务器。在那台服务器上,我安装了 SQL Plus 并成功地使用它来执行以下 SQL 所以我知道连接和功能本身都是正确的:

SELECT FNC_APPTS(PIN_GMC =>'C2331780', PIN_LOCATION =>'RG26 5SW', PIN_DISTANCE => 1000, PIN_PERIOD => 7, PIN_SORT =>'DATE' ) from dual;

我一直在努力了解如何在 ASP.NET 中使用 Oracle.ManagedDataAccess 程序集来使用它来填充 DataTable。到目前为止,我有以下内容(混淆了连接字符串)...

string connstring = "Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=1.1.1.1)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=****)));User Id=****;Password=****;";

using (var connection = new OracleConnection(connstring))
{
    connection.Open();
    using (var command = new OracleCommand())
    {
        command.Connection = connection;
        command.CommandText = "FNC_APPTS";
        command.CommandType = CommandType.StoredProcedure;

        command.Parameters.Add(new OracleParameter("PIN_GMC", OracleDbType.Varchar2, 50)).Value = consultantCode;
        command.Parameters.Add(new OracleParameter("PIN_LOCATION", OracleDbType.Varchar2, 50)).Value = location;
        command.Parameters.Add(new OracleParameter("PIN_DISTANCE", OracleDbType.Int32)).Value = distance;
        command.Parameters.Add(new OracleParameter("PIN_PERIOD", OracleDbType.Int32)).Value = period;
        command.Parameters.Add(new OracleParameter("PIN_SORT", OracleDbType.Varchar2, 50)).Value = sort;

        using (var reader = command.ExecuteReader())
        {
            dt.Load(reader);
        }
    }
}

...但这给了我错误 PLS-00221: 'FNC_APPTS' is not a procedure or is undefined

我怀疑这与 SQL 语句的 "from dual" 部分有关,但我不知道它指的是什么(是否等同于 SQL 架构或什么?)。非常感谢您的建议。

更新 1

在@MethodMan 和@kevinsky 的一些建议后,我尝试添加一个额外的 OracleDbType.RefCursor 参数,现在我得到的错误是 PLS-00306: wrong number or types of arguments in call to 'FNC_APPTS' 这表明它是 终于实现了功能。因此,我假设原始 PLS-00221 错误消息更多是对我的语法的抱怨,而不是找不到函数。现在我真的被困住了,再次向你求助,明智而仁慈的 Stack Overflow 社区,寻求指导......

更新 2

经过更多阅读,我现在发现如果我像这样添加一个 return 参数...

OracleParameter retVal = new OracleParameter("retVal", OracleDbType.RefCursor);
retVal.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(retVal);

...然后 command.ExecuteNonQuery(); 我发现 retVal.ValueOracleRefCursor 类型。但是,如果我那时...

using (OracleDataReader reader = ((Oracle.ManagedDataAccess.Types.OracleRefCursor)retVal.Value).GetDataReader())
{
    dt.Load(reader);
}

...我收到错误 ORA-01002: fetch out of sequence。感觉我离这里越来越近了。这有什么帮助吗?

更新 3

我相信我越来越接近了。完整的错误是:

ORA-01002: fetch out of sequence
ORA-02063: preceding line from GATE_LINK

我现在可以访问函数体并相信 GATE_LINK 是一个 SQL 服务器数据库。由于这个问题已经超出了我原来的问题的范围,我 并且 link 如果有一个问题出现,这个线程将在那里给出任何答案。

在确定我的问题的具体原因后,我最终针对这个问题提出了一个新问题。这个问题和最终答案在这里: