有这样一段 SQL 代码:
通过 C# 获取查询结果:
SQL 代码中有两个参数,且都是字符串类型,以上的 C# 代码是生成 Oracle SQL 代码所需要的参数。运行结果如下:
居然发生这样的错误!苦思冥想外加多次尝试,均无果!
该错误的诡异之处在于:phdLevel 的值为 "%%" 时,运行正常,而为某一状态值(平衡,欠平衡,过平衡) 时,运行出错!如果说 SQL 语句有问题,将上述 SQL 语句参数代入,在 PL/SQL 中运行,一切正常!如果说是 p_phdlevel 的参数有问题,p_company 参数却没有任何问题!两个参数是同样的字符串类型!
继续苦苦思索……
p_company 参数没有问题,那就是说,b.COMPANY = :p_company 这一条件没有问题,也就是说,等号两边的数据类型是一致的!p_phdlevel 有问题,那就是说,a.PHDLEVEL LIKE :p_phdlevel 这一条件有问题,而且从错误信息来看,这一条件存在着 不合理的类型转换(unreasonable conversion)!
b.COMPANY 是实体表中的一个字段,类型为 varchar2,p_company 参数也是 varchar2(OracleDbType.Varchar2) 类型!a.PHDLVEL 不是实体表的字段,而是 SELECT 语句生成的字段,其类型是什么?p_phdlevel 参数的类型是 varchar2(OraclDbType.Varchar2)!如此看来,a.PHDLEVEL 的参数必不是 varchar2 类型!也不是 NVarchar2 类型(p_phdlevel 参数类型改成 NVarchar2 类型之后,错误如常)!难道是 Char 类型?将 p_phdlevel 参数类型改成 Char:
运行正常!
此时,问题虽然解决了,但并没有消除 Oracle 的诡异:如果说 a.PHDLEVEL 的类型是 Char,导致出错是因为 p_phdlevel 参数的类型错误(Varchar2) ,那为什么在 p_phdlevel 取值为 "%%" 时运行正常,而在取值为中文("欠平衡")时却出错?
可能的解释是:
条件 a.PHDLEVEL LIKE :p_phlevel 存在着一个类型转换:将 Varchar2 类型的 p_phdlevel 参数转换为 Char 类型,这个转换在 p_phdlevel 取值为 "%%" 时,可以正常转换;而当p_phdlevel 取值为中文时,则不能正常转换! 若果如此,则更加令人匪夷所思。Char 是固定长度的字符串类型,而 Varchar2 是可变长度的字符串类型,二者并没有本质区别!
笨拙而诡异的 Oracle!