从 ASP.NET 中的 Oracle DB 函数读取数据表
Posted
技术标签:
【中文标题】从 ASP.NET 中的 Oracle DB 函数读取数据表【英文标题】:Read data table from Oracle DB function in ASP.NET 【发布时间】:2015-01-08 14:30:26 【问题描述】:背景
我是一个很少有 Oracle 经验的 .NET 开发人员。客户向我们提供了我们需要针对其网络上的数据库执行的 Oracle 功能的详细信息。它返回一个数据表。我需要在 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
经过更多阅读,我现在发现如果我添加这样的返回参数......
OracleParameter retVal = new OracleParameter("retVal", OracleDbType.RefCursor);
retVal.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(retVal);
...然后command.ExecuteNonQuery();
我发现retVal.Value
的类型是OracleRefCursor
。但是,如果我那时...
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 Server 数据库。由于这个问题已经超出了我最初的问题的范围,我有started a new thread 并且如果有一个问题出现,我会将此线程链接到那里的任何答案。
【问题讨论】:
在 Oracle 中是Package
中的存储过程还是存储过程节点..?尝试完全限定数据库用户的名称,例如,我的 Oracle 数据库中有一个存储过程,位于 OtherUsers
节点内,名为 Humana
,所以我会在命令文本 Humana.FNC_APPTS
中做一些简单的事情,你也可以剪切那个连接字符串在你的 web.config 里面变成这样的东西。它可以工作,因为我已经尝试过像你一样的东西,使用起来很讨厌
见这里***.com/questions/13662497/…
更改您的连接字符串并在 web.config 文件中进行设置,类似于 <add name="DbConn" connectionString=" Data Source=YourDatabaseNamev;User Id=yourDBUser;Password=yourdbpassword;" />
@MethodMan 谢谢,当然,一旦它工作,我将配置连接字符串。我只是在这里测试。您的连接字符串看起来像一个 SQL Server 吗?至于存储过程的细节,我知之甚少。我假设因为我有一个可以在 SQL Plus 中成功执行的 SQL 字符串,所以我拥有在 C# 中执行和处理返回的表所需的一切。如果函数调用需要明确的用户名,那么 SQL Plus 中的 SQL 肯定也会失败吗?
@Avijit 谢谢,但你能解释一下这个链接有什么帮助吗?
【参考方案1】:
在确定了我的问题的具体原因后,我最终针对这个问题提出了一个新问题。这个问题和最终答案在这里:Error "fetch out of sequence" returning table from Oracle function in C# where function uses dblink to SQL Server
【讨论】:
以上是关于从 ASP.NET 中的 Oracle DB 函数读取数据表的主要内容,如果未能解决你的问题,请参考以下文章
使用前端 ASP.net 从 Access db 迁移到 SQL Server 2008
如何从现有 SQL DB ASP.Net MVC 4 在下拉列表中填充数据