using System;
using System.IO;
using System.Threading;
using System.Data;
using System.Data.OracleClient;
//REFDLL System.Data.OracleClient;System.Data;System.Xml
public class CSharpLab
{ public static void Test()
{ using (OracleConnection cn = new OracleConnection("Data Source=....")) { string strSQL =
@"
SELECT
p.DRKCORPID, q.DRKQuoteTIME
FROM DRKPRODUCT p LEFT JOIN DRKQuote q
ON q.DRKPRODID=p.DRKPRODID AND p.DRKCORPID='6666'
";
OracleCommand cmd = new OracleCommand(strSQL, cn);
cn.Open();
try { OracleDataReader dr = cmd.ExecuteReader();
dr.Read();
Console.WriteLine(dr["DRKCORPID"]);
} catch (Exception ex) { Console.WriteLine(ex.ToString());
}
cn.Close();
}
}
}
System.Data.OracleClient.OracleException: ORA-01405: fetched column value is NULL
at System.Data.OracleClient.OracleConnection.CheckError(OciErrorHandle errorHandle, Int32 rc)
at System.Data.OracleClient.OracleDataReader.ReadInternal()
at System.Data.OracleClient.OracleDataReader.Read()
at CSharpLab.Test()
大致推斷的原因是這個LEFT JOIN在某些情況下,q.DRKQuoteTIME可能為NULL。我發現調整SQL的語法,會產生不同的結果,於是做了一連串有趣的測試。
要克服這個問題,除了改用ODP.NET之外,在可能產生NULL的欄位上加上NVL保護,例如: NVL(q.DRKQuoteTIME, '0000'),也不失為一個好的解決方法。(試了一下,若真的希望傳回NULL,可以寫成有點好笑的NVL(q.DRKQuoteTIME, NULL),也可避開這個Bug)