編輯:使用Execute
方法而不是Query
/ QueryMultiple
方法,我的OUT_SUCCESS
參數現在有一個AttachedParam
其中包含一個具有返回值的OracleParameter
。因此,如果我只需要檢索非游標參數,那麼這將起作用。然後,我可以將Execute
用於具有所有非游標輸出參數的過程,並將Query
/ QueryMultiple
用於僅具有游標輸出參數的過程。但是,如果我需要調用同時具有光標和非游標輸出參數的存儲過程,這是常有的情況?
使用Dapper.NET
和OracleDynamicParameters
類我已經成功返回並映射了多個IN OUT
REF CURSOR
,但我無法獲得單個OUT
參數的值。
例如,我試圖使用以下規範調用存儲過程:
PROCEDURE DO_SOMETHING (
OUT_SUCCESS OUT VARCHAR2
)
為此我創建了一個相應的C#類來為它建模,其中包含獲取OracleDynamicParameters
, CommandText
等的方法,還包括每個參數的自動實現屬性
public class DO_SOMETHING {
... //code to return parameters, etc
public string OUT_SUCCESS { get; set; }
...
}
我嘗試了以下所有語法:
using (var gridReader = Connection.QueryMultiple(nModel.CommandText(), param: nModel.DynamicParameters(), commandType: nModel.CommandType()))
{
OUT_SUCCESS = ((OracleDynamicParameters)Model.DynamicParameters()).Get<string>("OUT_SUCCESS"); // 1
OUT_SUCCESS = gridReader.Read<string>().Single(); //2
OUT_SUCCESS = gridReader.Read<DO_SOMETHING>().Single().OUT_SUCCESS; //3
}
但它們都不起作用:
"OUT_SUCCESS"
的參數, AttachedParam
為null
(儘管我可以看到該參數存在) gridReader
報告“序列不包含任何元素”,可能是因為它不知道如何從響應中讀取字符串。 InvalidArgumentException
:在gridReader
建議我說:“當使用多地圖API確保您設置的splitOn PARAM如果你有多個id其他鍵”,但我真的不知道這是怎麼中肯我問題。 順便說一句,我知道該過程正在成功執行,因為ODP.NET不會產生異常,我看到結果行在數據庫中持久存在。
我不知道如何繼續,但我真的很想使用Dapper,因為這是最後一次攀登的障礙。任何幫助總是受到讚賞。
我知道這是非常晚的,除了我之外,對大多數人來說可能是常識,但不久之前原始消息中有一條評論,所以我將描述如何解決光標輸出參數的問題以及非光標輸出參數。
由於我的示例只有一個Oracle游標,我可以使用Query方法。其他out參數的結果在參數本身中,可以使用OracleDynamicParameters類中的Get <>方法檢索。
對我來說另一個重要的部分是為我的out參數添加一個大小,否則它們將返回null或空字符串。
下面是我正在使用的代碼示例。
using (IDbConnection db = new OracleConnection(connectionString)) {
var p = new OracleDynamicParameters();
p.Add("p_first_parameter", someParameter, OracleDbType.Varchar2, ParameterDirection.Input);
p.Add("o_cursr", dbType: OracleDbType.RefCursor, direction: ParameterDirection.Output);
p.Add("o_sqlerrm", dbType: OracleDbType.Varchar2, direction: ParameterDirection.Output, size: 200);
p.Add("o_sqlcode", dbType: OracleDbType.Varchar2, direction: ParameterDirection.Output, size: 200);
dynamic csr = db.Query("myStoredProcedure", p, commandType: CommandType.StoredProcedure).ToList().First();
string code = p.Get<OracleString>("o_sqlcode").ToString();
if (code != "0") {
string errm = p.Get<OracleString>("o_sqlerrm").ToString();
throw new Exception($"{code} - {errm}");
}
}