使用Dapper對Oracle資料庫使用IN Operator,當參數傳入empty list時會發生例外。
同事回報系統出錯,我測試後發現Dapper對Oracle資料庫使用IN Operator,當參數傳入empty list時會發生例外。
原先以為是Oracle Unmanaged Data Access的問題,但交叉測試後發現連Managed Data Access也有相同的問題,換了幾個Dapper的版本也會發生一樣的問題。
以下是用Dapper 2.0.90 + Oracle Unmanaged Data Access 2.112.3.0測試
List<int> idList = new List<int>() { 1, 2 };
List<int> emptyIdList = new List<int>();
sql = "SELECT * FROM ErrorLog WHERE Id IN @ids";
using (var sqlConnection = new SqlConnection(connectionString))
{
datas = sqlConnection.Query(sql, new { ids = idList });
count = datas.Count(); //count=2
datas = sqlConnection.Query(sql, new { ids = emptyIdList });
count = datas.Count(); //count=0
}
sql = "SELECT * FROM ErrorLog WHERE \"Id\" IN :ids";
using (var oracleConnection = new OracleConnection(oracleConnectionString))
{
datas = oracleConnection.Query(sql, new { ids = idList });
count = datas.Count(); //count=2
datas = oracleConnection.Query(sql, new { ids = emptyIdList });
//發生例外:'ORA-00923: 在應出現的位置找不到 FROM 關鍵字'
count = datas.Count();
}
SQL Server在傳入empty list時可以正常運作,但Oracle會報錯。
因此在使用Dapper+Oracle有使用到IN Operator時,須注意傳入empty list時要另外處理。
題外話:
Dapper有個Dapper contrib可以直接進行CRUD,在開發上方便很多,但在搭配Oracle時會出錯,因為目前Dapper contrib並沒有實作Oracle Adapter(參考)。若想搭配Oracle使用Dapper contrib的話,可能要找找第三方的patch了。