0

我正在尝试调用返回类型为数字的 Oracle 函数。我使用 OleDB 从 C# 调用,并且我知道 Oracle 中类型编号的映射是小数。每当我打电话给这个时,我都会得到一个 0。

using (OleDbCommand _cmdDueAtDock = new OleDbCommand()) {

   _cmdDueAtDock.Connection = connection;
   _cmdDueAtDock.CommandType = CommandType.StoredProcedure;
   _cmdDueAtDock.CommandText = "IFSAPP.PURCHASE_ORDER_LINE_API.GET_DUE_AT_DOCK";

   _cmdDueAtDock.Parameters.Add(new OleDbParameter() {
       ParameterName = "rv_",
       OleDbType = OleDbType.Decimal,
       Direction = ParameterDirection.ReturnValue
   });
   _cmdDueAtDock.Parameters.Add(new OleDbParameter() {
       ParameterName = "order_no_",
       OleDbType = OleDbType.VarChar,
       Size = 50,
       Direction = ParameterDirection.Input,
       Value = _order_line.ORDER_NO
   });
   _cmdDueAtDock.Parameters.Add(new OleDbParameter() {
       ParameterName = "line_no_",
       OleDbType = OleDbType.VarChar,
       Size = 50,
       Direction = ParameterDirection.Input,
       Value = _order_line.LINE_NO
   });
   _cmdDueAtDock.Parameters.Add(new OleDbParameter() {
       ParameterName = "release_no_",
       OleDbType = OleDbType.VarChar,
       Size = 50,
       Direction = ParameterDirection.Input,
       Value = _order_line.RELEASE_NO
   });

   try {
      _cmdDueAtDock.ExecuteNonQuery();
      dueAtDock = Convert.ToDecimal(_cmdDueAtDock.Parameters["rv_"].Value);
   } catch (Exception ex)  {
      dueAtDock = 0;
   }
}

我正在使用Oracle client 11.2.0,oracle 数据库版本是10.2.0.4.0.

我已经阅读了有关 11.1 客户端有问题的信息,我实际上能够通过 11.1 客户端总结行为select to_char(function) from dual- 我得到了正确的结果,to_char但没有0with to_char。将我的客户端升级到 11.2 可以在本地解决此问题。

4

2 回答 2

1

非常感谢您的回复,但这取决于数据库事务和代码执行顺序 - 在此之前有一段代码正在执行影响函数结果的内容。

希望我错过的这个可以帮助其他挠头的人!

多姆

于 2015-12-01T16:52:39.863 回答
0

我的猜测是该值始终为 0,因为 catch 块总是被触发。我看到一个明显的罪魁祸首,另一个可能。我假设您的存储过程看起来像这样:

create or replace procedure GET_DUE_AT_DOCK(
  order_no_ in varchar2,
  line_no_ in varchar2,
  release_no_ in varchar2,
  rv_ out number
) as
BEGIN
  rv_ := 999;
END;

我相信您的ParameterDirectionProperty 需要Output代替ReturnValue. 我可能是错的,但我认为ReturnValue它与一个有RETURNING子句的普通 SQL 命令一起使用,例如:

insert into foo (name, birthday)
values (:NAME, :BIRTHDAY)
returning unique_id into :ID;

我可能是错的,但我认为是这样。

其次,对于存储过程,我认为参数的声明很重要,需要与过程中的实际参数保持一致。如果我上面的示例在理论上是正确的,那么您需要按照确切的顺序(order_no、line_no、release_no、rv)放置参数。如果没有实际看到您的存储过程,很难说 - 您实际上可能是正确的。

因此,假设 SP 看起来像我的示例,应该这样做:

_cmdDueAtDock.Parameters.Add(new OleDbParameter() {
    ParameterName = "order_no_", OleDbType = OleDbType.VarChar,
    Direction = ParameterDirection.Input, Value = _order_line.ORDER_NO });
_cmdDueAtDock.Parameters.Add(new OleDbParameter() {
    ParameterName = "line_no_", OleDbType = OleDbType.VarChar,
    Direction = ParameterDirection.Input, Value = _order_line.LINE_NO });
_cmdDueAtDock.Parameters.Add(new OleDbParameter() {
    ParameterName = "release_no_", OleDbType = OleDbType.VarChar,
    Direction = ParameterDirection.Input, Value = _order_line.RELEASE_NO });
_cmdDueAtDock.Parameters.Add(new OleDbParameter() {
    ParameterName = "rv_", OleDbType = OleDbType.Decimal,
    Direction = ParameterDirection.Output });   /// <- change is here

try
{
    _cmdDueAtDock.ExecuteNonQuery();
    decimal dueAtDock = Convert.ToDecimal(_cmdDueAtDock.Parameters[3].Value);
}
catch (Exception ex)
{
    decimal dueAtDock = 0;
}
于 2015-12-01T14:22:25.560 回答