Dapper對Oracle資料庫使用IN Operator時發生例外

使用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了。