ORA-01403: 未找到数据 ORA-06512: 在第 1 行尝试使用 ODP.NET 运行 存储过程
ORA-01403: no data found ORA-06512: at line 1 when trying to run a stored proc using ODP.NET
我正在构建一个界面,该界面将 运行 通过我的 .NET Winforms 应用程序从 Oracle 数据库存储过程。我能够成功连接到 Oracle 数据库,并且可以成功地使用 ODP.NET API 检索所有存储过程的列表以及我选择的任何存储过程的所有参数。
当我尝试 运行 存储过程时存在问题。当我尝试执行并且 returns Oracle 错误告诉我没有记录时它中断了,但是当我 运行 来自 sql 开发人员的存储过程时,它 returns 正是我正在寻找。这是存储过程:
create or replace procedure sp_get_emp_info
(
empid in INTEGER,
m_UserName out VARCHAR2,
m_Email out VARCHAR2,
m_IsActive out INTEGER
) as
begin
SELECT
UserName,
Email,
IsActive
INTO
m_UserName,
m_Email,
m_IsActive
FROM
MICHAELTABLE
WHERE ID = empid;
end sp_get_emp_info;
这是一个测试 class 我写这篇文章只是为了尝试用 C# 阅读:
using Oracle.ManagedDataAccess.Client;
using System;
namespace OracleTester
{
class Program
{
static void Main(string[] args)
{
OracleConnection conn = new OracleConnection();
conn.ConnectionString = "User Id=apps;Password=apps;Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = Orchid64)(PORT = 1521))(CONNECT_DATA = (SERVICE_NAME = MVP)));";
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.DarkYellow;
//string procs = "SELECT object_name FROM dba_objects WHERE object_type = 'PROCEDURE' AND owner = 'APPS'";
//OracleCommand cmd = new OracleCommand(procs, conn);
//cmd.CommandType = System.Data.CommandType.Text;
//cmd.Connection.Open();
//OracleDataReader reader = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
//int i = 1;
//while (reader.Read())
//{
// Console.WriteLine(i + ". " +reader.GetString(0));
// i++;
//}
OracleCommand comm = new OracleCommand();
comm.CommandText = "SP_GET_EMP_INFO";
comm.CommandType = System.Data.CommandType.StoredProcedure;
comm.Connection = conn;
OracleParameter user = new OracleParameter("m_UserName", OracleDbType.Varchar2, 25);
user.Direction = System.Data.ParameterDirection.Output;
OracleParameter email = new OracleParameter("m_Email", OracleDbType.Varchar2, 50);
email.Direction = System.Data.ParameterDirection.Output;
OracleParameter active = new OracleParameter("m_IsActive", OracleDbType.Double, 38);
active.Direction = System.Data.ParameterDirection.Output;
comm.Parameters.Add(user);
comm.Parameters.Add(email);
comm.Parameters.Add(active);
OracleParameter empID = new OracleParameter("empid", OracleDbType.Double, 38);
empID.Direction = System.Data.ParameterDirection.Input;
empID.SourceColumn = "empid";
empID.Value = 1;
comm.Parameters.Add(empID);
comm.Connection.Open();
OracleDataReader rdr = comm.ExecuteReader();
while (rdr.Read())
{
Console.WriteLine(rdr["m_UserName"].ToString());
}
Console.WriteLine("Server Version: " + conn.ServerVersion);
conn.Dispose();
Console.ReadLine();
}
}
}
当我尝试 运行 时,这是我收到的异常:
Oracle.ManagedDataAccess.Client.OracleException was unhandled
DataSource=""
ErrorCode=-2147467259
HResult=-2147467259
IsRecoverable=false
Message=ORA-01403: no data found
ORA-06512: at "APPS.SP_GET_EMP_INFO", line 9
ORA-06512: at line 1
Number=1403
Procedure=""
Source=Oracle Data Provider for .NET, Managed Driver
StackTrace:
at OracleInternal.ServiceObjects.OracleCommandImpl.VerifyExecution(OracleConnectionImpl connectionImpl, Int32& cursorId, Boolean bThrowArrayBindRelatedErrors, OracleException& exceptionForArrayBindDML, Boolean& hasMoreRowsInDB, Boolean bFirstIterationDone)
at OracleInternal.ServiceObjects.OracleCommandImpl.ExecuteReader(String commandText, OracleParameterCollection paramColl, CommandType commandType, OracleConnectionImpl connectionImpl, OracleDataReaderImpl& rdrImpl, Int32 longFetchSize, Int64 clientInitialLOBFS, OracleDependencyImpl orclDependencyImpl, Int64[] scnForExecution, Int64[]& scnFromExecution, OracleParameterCollection& bindByPositionParamColl, Boolean& bBindParamPresent, Int64& internalInitialLOBFS, OracleException& exceptionForArrayBindDML, Boolean isDescribeOnly, Boolean isFromEF)
at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteReader(Boolean requery, Boolean fillRequest, CommandBehavior behavior)
at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteReader()
at OracleTester.Program.Main(String[] args) in C:\TestProjects\OracleTester\OracleTester\Program.cs:line 54
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
任何帮助将不胜感激!!
By default, ODP.NET parameters for OracleCommand.CommandType = Text commands are bound by position. The OracleCommand class provides a BindByName property—set this property to true to bind parameters by name instead of by position.
您正在创建命名参数,但它们实际上是按位置添加的,这意味着您有效地为 m_IsActive
提供了一个值(尽管它是一个 OUT 参数)并留下 empid
null,就程序而言。
您可以设置 comm.BindByName=true
正如 @b_levitt 在评论中指出的那样。或者,如果您重新排序参数分配以匹配形式参数顺序,它将选择正确的值:
OracleParameter empID = new OracleParameter("empid", OracleDbType.Double, 38);
empID.Direction = System.Data.ParameterDirection.Input;
empID.SourceColumn = "empid";
empID.Value = 1;
comm.Parameters.Add(empID);
comm.Parameters.Add(user);
comm.Parameters.Add(email);
comm.Parameters.Add(active);
comm.Connection.Open();
OracleDataReader rdr = comm.ExecuteReader();
当 CommandType 属性 设置为 StoredProcedure 时,documentation 似乎不太清楚 return 值将包含什么,如果您重新调用函数;但是对于过程调用,没有关联的结果集,因此这可能是空的。遍历它不会找到任何东西:
while (rdr.Read())
{
Console.WriteLine(rdr["m_UserName"].ToString());
}
相反,您可以直接引用 OUT 参数的值:
Console.WriteLine(user.value);
我正在构建一个界面,该界面将 运行 通过我的 .NET Winforms 应用程序从 Oracle 数据库存储过程。我能够成功连接到 Oracle 数据库,并且可以成功地使用 ODP.NET API 检索所有存储过程的列表以及我选择的任何存储过程的所有参数。
当我尝试 运行 存储过程时存在问题。当我尝试执行并且 returns Oracle 错误告诉我没有记录时它中断了,但是当我 运行 来自 sql 开发人员的存储过程时,它 returns 正是我正在寻找。这是存储过程:
create or replace procedure sp_get_emp_info
(
empid in INTEGER,
m_UserName out VARCHAR2,
m_Email out VARCHAR2,
m_IsActive out INTEGER
) as
begin
SELECT
UserName,
Email,
IsActive
INTO
m_UserName,
m_Email,
m_IsActive
FROM
MICHAELTABLE
WHERE ID = empid;
end sp_get_emp_info;
这是一个测试 class 我写这篇文章只是为了尝试用 C# 阅读:
using Oracle.ManagedDataAccess.Client;
using System;
namespace OracleTester
{
class Program
{
static void Main(string[] args)
{
OracleConnection conn = new OracleConnection();
conn.ConnectionString = "User Id=apps;Password=apps;Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = Orchid64)(PORT = 1521))(CONNECT_DATA = (SERVICE_NAME = MVP)));";
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.DarkYellow;
//string procs = "SELECT object_name FROM dba_objects WHERE object_type = 'PROCEDURE' AND owner = 'APPS'";
//OracleCommand cmd = new OracleCommand(procs, conn);
//cmd.CommandType = System.Data.CommandType.Text;
//cmd.Connection.Open();
//OracleDataReader reader = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
//int i = 1;
//while (reader.Read())
//{
// Console.WriteLine(i + ". " +reader.GetString(0));
// i++;
//}
OracleCommand comm = new OracleCommand();
comm.CommandText = "SP_GET_EMP_INFO";
comm.CommandType = System.Data.CommandType.StoredProcedure;
comm.Connection = conn;
OracleParameter user = new OracleParameter("m_UserName", OracleDbType.Varchar2, 25);
user.Direction = System.Data.ParameterDirection.Output;
OracleParameter email = new OracleParameter("m_Email", OracleDbType.Varchar2, 50);
email.Direction = System.Data.ParameterDirection.Output;
OracleParameter active = new OracleParameter("m_IsActive", OracleDbType.Double, 38);
active.Direction = System.Data.ParameterDirection.Output;
comm.Parameters.Add(user);
comm.Parameters.Add(email);
comm.Parameters.Add(active);
OracleParameter empID = new OracleParameter("empid", OracleDbType.Double, 38);
empID.Direction = System.Data.ParameterDirection.Input;
empID.SourceColumn = "empid";
empID.Value = 1;
comm.Parameters.Add(empID);
comm.Connection.Open();
OracleDataReader rdr = comm.ExecuteReader();
while (rdr.Read())
{
Console.WriteLine(rdr["m_UserName"].ToString());
}
Console.WriteLine("Server Version: " + conn.ServerVersion);
conn.Dispose();
Console.ReadLine();
}
}
}
当我尝试 运行 时,这是我收到的异常:
Oracle.ManagedDataAccess.Client.OracleException was unhandled
DataSource=""
ErrorCode=-2147467259
HResult=-2147467259
IsRecoverable=false
Message=ORA-01403: no data found
ORA-06512: at "APPS.SP_GET_EMP_INFO", line 9
ORA-06512: at line 1
Number=1403
Procedure=""
Source=Oracle Data Provider for .NET, Managed Driver
StackTrace:
at OracleInternal.ServiceObjects.OracleCommandImpl.VerifyExecution(OracleConnectionImpl connectionImpl, Int32& cursorId, Boolean bThrowArrayBindRelatedErrors, OracleException& exceptionForArrayBindDML, Boolean& hasMoreRowsInDB, Boolean bFirstIterationDone)
at OracleInternal.ServiceObjects.OracleCommandImpl.ExecuteReader(String commandText, OracleParameterCollection paramColl, CommandType commandType, OracleConnectionImpl connectionImpl, OracleDataReaderImpl& rdrImpl, Int32 longFetchSize, Int64 clientInitialLOBFS, OracleDependencyImpl orclDependencyImpl, Int64[] scnForExecution, Int64[]& scnFromExecution, OracleParameterCollection& bindByPositionParamColl, Boolean& bBindParamPresent, Int64& internalInitialLOBFS, OracleException& exceptionForArrayBindDML, Boolean isDescribeOnly, Boolean isFromEF)
at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteReader(Boolean requery, Boolean fillRequest, CommandBehavior behavior)
at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteReader()
at OracleTester.Program.Main(String[] args) in C:\TestProjects\OracleTester\OracleTester\Program.cs:line 54
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
任何帮助将不胜感激!!
By default, ODP.NET parameters for OracleCommand.CommandType = Text commands are bound by position. The OracleCommand class provides a BindByName property—set this property to true to bind parameters by name instead of by position.
您正在创建命名参数,但它们实际上是按位置添加的,这意味着您有效地为 m_IsActive
提供了一个值(尽管它是一个 OUT 参数)并留下 empid
null,就程序而言。
您可以设置 comm.BindByName=true
正如 @b_levitt 在评论中指出的那样。或者,如果您重新排序参数分配以匹配形式参数顺序,它将选择正确的值:
OracleParameter empID = new OracleParameter("empid", OracleDbType.Double, 38);
empID.Direction = System.Data.ParameterDirection.Input;
empID.SourceColumn = "empid";
empID.Value = 1;
comm.Parameters.Add(empID);
comm.Parameters.Add(user);
comm.Parameters.Add(email);
comm.Parameters.Add(active);
comm.Connection.Open();
OracleDataReader rdr = comm.ExecuteReader();
当 CommandType 属性 设置为 StoredProcedure 时,documentation 似乎不太清楚 return 值将包含什么,如果您重新调用函数;但是对于过程调用,没有关联的结果集,因此这可能是空的。遍历它不会找到任何东西:
while (rdr.Read())
{
Console.WriteLine(rdr["m_UserName"].ToString());
}
相反,您可以直接引用 OUT 参数的值:
Console.WriteLine(user.value);