2014-02-25 75 views
5

我们在C#程序中使用Oracle存储过程,该过程一直运行良好,直到我们添加了“v_nameurn”变量。PLS-00306:C#中错误的参数数量或类型错误#

这里的Oracle过程:

create or replace procedure stats_By_Date (
    v_SDate IN varchar2, 
    v_EDate IN varchar2, 
    v_user IN number, 
    v_nameurn IN number, 
    p_cursor OUT SYS_REFCURSOR 
) as 
BEGIN 
    OPEN p_cursor FOR 
    select T1.Staff_No, 
      T3.Title, 
      T2.Verno, 
      To_char(T1.Response_dt, 'DD/MM/YYYY'), 
      T5.Response, 
      T6.Forenames||' '||T6.Surname 
     from TOU.Users_version_link T1, 
      TOU.Version T2, 
      TOU.name T3, 
      TOU.Admin_Access T4, 
      Tou.CV_Response T5, 
      [email protected]_DWLive T6 
     where T1.Version_urn=T2.Urn 
     and T1.Name_urn= T3.urn 
     and T3.urn = T4.name_urn 
     and T1.Response_urn=T5.urn 
     and T1.staff_no=T6.Staff_Number 
     and Trunc(T1.Response_dt) >= To_date(v_Sdate, 'DD/MM/YYYY') 
     and Trunc(T1.Response_dt) <= To_date(v_EDate, 'DD/MM/YYYY') 
     and T4.Staff_No = v_user 
     and T3.urn = v_nameurn; 
End; 

这里是C#代码:

this.ConnectToDb(); 
var cmd = new OracleCommand 
{ 
    Connection = cn, 
    CommandText = "TOU.Stats_By_Date", 
    CommandType = CommandType.StoredProcedure 
}; 
var id = HttpContext.Current.User.Identity.Name.Split('\\')[1].ToString(); 
cmd.Parameters.Add("v_SDate", OracleDbType.Varchar2).Value = 
      startdate.ToString("dd-MM-yyyy"); 
cmd.Parameters.Add("v_EDate", OracleDbType.Varchar2).Value = 
      enddate.ToString("dd-MM-yyyy"); 
cmd.Parameters.Add("v_user", OracleDbType.Decimal).Value = int.Parse(id); 
cmd.Parameters.Add("v_nameurn", OracleDbType.Decimal).Value = 3; 
var rc = cmd.Parameters.Add("p_cursor", OracleDbType.RefCursor); 
rc.Direction = ParameterDirection.Output; 
cmd.ExecuteNonQuery(); 
this.DisconnectFromDb(); 

任何建议,什么可能是错误的吗?这两个代码片段中有5个总变量(4入,1出),这很好,所有数据类型似乎都匹配。我也对实际的v_nameurn变量尝试了不同的变体,所以我尝试了3,“3”,并事先将它定义为一个Int变量。

+0

对不起,如果这是一个愚蠢的问题,但你每次关闭连接? –

+0

谢谢,是的,我是,我已经更新了我的代码 – Nick

+1

我不确定为什么你在C#中以''dd-MM-yyyy''格式传递日期,并使用格式''DD/MM/YYYY''在Oracle中。虽然这可能不是错误的原因,但对我来说似乎是错误的。你也可以尝试将3解析为整数,就像你为'id'所做的那样,我的意思是'int.Parse(3)',我不知道它在C#中如何工作,但它值得尝试。 – San

回答

2

Decimal is Oracle NUMBER type ..所以更改为v_user数据类型和 'v_nameurn'

cmd.Parameters.Add("v_user", OracleDbType.Decimal).Value = int.Parse(id); 
cmd.Parameters.Add("v_nameurn", OracleDbType.Decimal).Value = 3; 

OracleDbType Enumeration

+0

非常感谢,我更新了我的代码(和原来的帖子),但不幸的是仍然得到相同的错误。 – Nick

2
cmd.Parameters.Add("v_user", OracleDbType.Decimal).Value = decimal.Parse(id); 
cmd.Parameters.Add("v_nameurn", OracleDbType.Decimal).Value = 3m; 

当你正在处理小数,则必须使用十进制。对于Oracle来说,小数不会很好地转换为整数,反之亦然。

1

这是Oracle证明不成为开发人员友好的RDBMS的错误之一。为什么他们不能告诉你哪两个问题是我不知道的问题。我有一个冗长的list of things to check这归结为以下几点:

  • 缺少逗号
  • 的参数数目错误
  • 秩序的参数和cmd.BindByName错误是假
  • 使用参数两次和cmd.BindByName为假(如果内联sql)
  • 参数上的数据类型匹配。为了避免这个问题,使用所有输入参数的.Add(“paramName”,value)重载,并且让这个类型被推断出来。

但是,从外观来看,我想我会再添加一个到我的列表中:确保你打电话给你认为你打电话的程序。我在程序上看到“TOU”限定符。我必须假设这是一个模式,而不是基于sql脚本的包。你在改变这个模式中的过程吗?如果你删除.net代码中的新参数,它会工作还是会出现同样的错误?你应该得到相同的错误,但是如果你不这样做,你可能会把新的proc加载到错误的模式中。

你可以做的最后一件事情就是从一个proc的shell开始,每次添加一个proc直到你能弄清楚发生了什么。

我会说你的int.Parse(id)有点奇怪 - 你的身份验证用户ID只是ints?但无论如何,我希望有一个.NET错误,而不是甲骨文的错误。