2014-02-25 91 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錯誤,而不是甲骨文的錯誤。