COALESCE 發生字元設定不符合錯誤

同事報案,Dapper 查詢 ORACLE 時使用 COALESCE() 遇到 ORA-12704: character set mismatch(字元設定不符) 錯誤。

我用以下程式成功重現問題:(jefftest2.t 欄位為 NVARCHAR2)

        static void Main(string[] args)
        {
            using (var cn = new OracleConnection(csStr))
            {
                var list = cn.Query(
                    "select 1 from jefftest2 where coalesce(t, :text) like '%'",
                    new { text = "ABC" });
                Console.Write(list.Count());
                Console.Read();
            }
        }

執行結果如下:

有趣的是,將 COALESCE(t, :text) 改成 NVL(t, :text) 就不會出錯。爬文查到應是 COALESCE(NVARCHAR2, VARCHAR2) 前後字串型別不一致,有人想出 N'' || :text 鋸箭小密技。試了一下,還真的有效!

問題來了,為什麼 :text 會變成 VARCHAR2?想起以前遇過類似問題-Dapper+ODP.NET無法寫入Unicode問題,莫非是相同原因?改用 ODP.NET OracleCommand 測試,指定 OracleDbType.NVarchar2,執行正常:

由此推測,八九不離十又是 Dapper 踩中 ODP.NET Bug 的老問題,搬出上回的 Hacking 修補大法

static void FixOdpNetDbTypeStringMapping()
{
    Assembly asm = typeof(OracleConnection).Assembly;
    Type tOraDb_DbTypeTable = asm.GetType("Oracle.ManagedDataAccess.Client.OraDb_DbTypeTable");
    var fldDbTypeMapping = tOraDb_DbTypeTable.GetField("dbTypeToOracleDbTypeMapping",
        BindingFlags.Static | BindingFlags.NonPublic);
    int[] mappings = (int[])fldDbTypeMapping.GetValue(null);
    mappings[(int)System.Data.DbType.String] = (int)OracleDbType.NVarchar2;
    fldDbTypeMapping.SetValue(null, mappings);
}
 
static void Main(string[] args)
{
    FixOdpNetDbTypeStringMapping();
    using (var cn = new OracleConnection(csStr))
    {
        var list = cn.Query(
            "select 1 from jefftest2 where coalesce(t, :text) like '%'",
            new { text = "ABC" });
        Console.Write(list.Count());
        Console.Read();
    }
}

問題排除~

依上次研究中,原以為要集滿「Oracle資料庫未採AL32UTF8編碼 + OracleParameter參數型別指定DbType + 內容剛好有ANSI/BIG5難字」三項條件才會踩坑,但依這回經驗,參數用於 COALESCE() 不一定要有難字也會出錯,看起來,未來應該將這個 Hacking 修補納入 Dapper + ODP.NET 開發的 SOP 比較保險。

歡迎推文分享:
Published 18 July 2017 10:35 PM 由 Jeffrey
Filed under: , ,
Views: 1,699



意見

沒有意見

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<July 2017>
SunMonTueWedThuFriSat
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication