2015-06-23 146 views
0

我正在使用Dapper和ODP.Net來調用存儲過程。 我覺得愚蠢沒有發現有什麼錯我的參數,但這裏有雲:Oracle錯誤:PLS-00306:錯誤的參數數量或類型

這裏是存儲過程簽名:

PROCEDURE SP_NETWORK_GETALL(UserLogon IN VARCHAR2, NetworkVersionList OUT refCursor) 

這裏是我的。NET電話:

using (var conn = new OracleConnection(connString)) 
{ 
    var parameters = new List<OracleParameter> 
    { 
     new OracleParameter() 
     { 
      Direction = ParameterDirection.Input, 
      ParameterName = "UserLogon", 
      OracleDbType = OracleDbType.Varchar2, 
      Size = 4000, 
      Value = "TEST" 
     }, 
     new OracleParameter() 
     { 
      Direction = ParameterDirection.Output, 
      OracleDbType = OracleDbType.RefCursor, 
      ParameterName = "NetworkVersionList", 
      Value = DBNull.Value 
     }, 
    }; 

    var results = conn.Query("SDTM.PKG_SP_GET.SP_NETWORK_GETALL", parameters, commandType: CommandType.StoredProcedure); 
} 

我試過這個存儲過程,它的工作原理。我已經使用Dapper處理其他存儲過程,它也可以。我試着改變參數的順序(第一個參考光標),設置VarChar2參數的大小與否,參考光標是否爲DBNull.Value。

我已經看到了成千上萬個問題是這樣一個計算器上或在互聯網上,但我不能在這裏看到的參數不匹配......

+0

是否需要模式名稱? – kevinsky

+0

嗯,我只是嘗試沒有模式名稱,我得到了同樣的錯誤,所以我不認爲這是問題... –

+0

這種錯誤的通常原因是因爲ODP.NET默認綁定的位置,而不是參數名稱。這似乎不是問題,但爲了防止您提供給我們的過程不是真正的過程,請確保按正確順序綁定或將Bindbyname設置爲true。接下來,確保「refcursor」是一個oracle類型。我雖然正確的類型是SYS_Refcursor。如果它實際上是用戶定義的類型,而不是簡單的ref_cursor,則不能像這樣綁定。也許你應該爲程序提供實際的創建聲明。 –

回答

1

的問題是,你發送列表的OracleParameter反對小巧的「參數」變量。 Dapper意味着與提供者無關,並且您正在發送提供者特定類型。

看看在短小精悍代碼的GetCacheInfo方法,你會在方式短小精悍嘗試處理參數,請參閱三種情況:

  1. IDynamicParameters的目的
  2. 的IEnumerable <的目的KeyValuePair <字符串,對象>>
  3. 默認值/否 - 試圖在您的對象中查找與命令中的令牌相匹配的屬性。

您可能會陷入默認情況,但因爲您有一個proc,所以命令中沒有令牌,也沒有添加任何參數。即使他們是,它可能會搜索類型列表<>屬性,它不會找到匹配。

添加IDynamicParameters使您可以控制參數,這就是它工作的原因。這與odp.net無關。

我想這是我所有的ORM中的一員,儘管他們會嘗試一樣艱難,但總是會有提供者特定的東西無法被抽象出來。這就是爲什麼我更喜歡簡單地設置特定於提供者的命令,然後使用只進行映射的實用程序類(而不關心連接/設置/執行)。

+0

所以我的類實現SqlMapper.IDynamicParameters是要走的路。然後奇怪的是,我之前用其他存儲過程(使用refCursors,UDT和其他特定於oracle的東西)通過直接發送OracleParameters列表來使用dapper,並且它工作正常。 –

+0

我想我會有興趣看到一個能像你描述的那樣工作的案例。也許甚至可以調試到精巧的代碼,看看如何添加參數。也許有一個我沒有看到的分支。 –

相關問題