Oracle c#number函数始终返回0

时间:2015-12-01 09:24:45

标签: c# oracle oracle11g oledb to-char

我试图调用一个返回类型为number的Oracle函数。我使用OleDB从C#调用,我理解Oracle中类型编号的映射是小数。每当我打电话给我时,我都会回来。

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客户端有问题的内容,我实际上能够通过select to_char(function) from dual对11.1客户端的行为进行总结 - 我得到的结果不是to_char而是0to_char。将我的客户端升级到11.2可以在本地解决此问题。

2 个答案:

答案 0 :(得分:1)

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

希望我的遗失能够帮助其他正在摸不着头脑的人!

的Dom

答案 1 :(得分: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;

我认为您的ParameterDirection财产需要Output而不是ReturnValue。我可能错了,但我认为ReturnValue与普通的SQL命令一起使用,你有一个RETURNING子句,例如:

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;
}