使用Dapper调用含to_date的Oracle查询触发ORA-00932错误求助
问题解答
错误原因
你把to_date('8/4/2023','MM/dd/yyyy')作为字符串参数传给Dapper,Dapper的参数绑定机制会把这个值当作普通字符串常量发送给Oracle,而非将其解析成可执行的SQL日期函数。
Oracle执行时,会把trunc(trans_date)(DATE类型)和这个字符串值做比较,类型不匹配,因此抛出ORA-00932错误。记住:Dapper的参数绑定是用来传值的,不是用来拼接SQL片段的。
修复方法
有两种可靠的修复方式:
方式1:在C#中转换为DateTime类型传入
直接把日期字符串转成C#的DateTime对象,Dapper会自动完成和Oracle DATE类型的映射,无需在参数里写SQL函数:
DateTime transDate = DateTime.ParseExact("8/4/2023", "MM/dd/yyyy", CultureInfo.InvariantCulture); string customerProfileId = "5464232"; string query = " update customer_bundle set modified_date = sysdate where cust_prof_id = :customerProfileId and trunc(trans_date) = trunc(:transDate)"; using (OracleConnection dbConn = new OracleConnection("...")) { DefaultTypeMap.MatchNamesWithUnderscores = true; dbConn.Open(); dbConn.Execute(query, new { customerProfileId, transDate}); }
方式2:拆分日期字符串和格式为独立参数
如果一定要在SQL里使用to_date函数,把日期值和格式分别作为参数传入,避免拼接SQL片段:
string transDateStr = "8/4/2023"; string dateFormat = "MM/dd/yyyy"; string customerProfileId = "5464232"; string query = " update customer_bundle set modified_date = sysdate where cust_prof_id = :customerProfileId and trunc(trans_date) = trunc(to_date(:transDateStr, :dateFormat))"; using (OracleConnection dbConn = new OracleConnection("...")) { DefaultTypeMap.MatchNamesWithUnderscores = true; dbConn.Open(); dbConn.Execute(query, new { customerProfileId, transDateStr, dateFormat}); }
追踪应用传入查询的工具
DBeaver的Query Manager只能记录自身执行的查询,无法追踪外部C#应用发送给Oracle的请求,你需要用Oracle端的工具:
- Oracle SQL Trace:在数据库端执行
ALTER SESSION SET SQL_TRACE=TRUE;开启追踪,应用执行的所有SQL都会被记录到追踪文件中,再用tkprof工具解析文件查看详细内容。 - Oracle Enterprise Manager (OEM):通过OEM的性能页面可以查看实时的SQL执行情况,包括外部应用发送的查询。
- 第三方工具如TOAD、PL/SQL Developer也带有SQL追踪功能,可捕获应用端发送的SQL语句。
内容的提问来源于stack exchange,提问作者Yener
相关产品推荐
相关产品推荐

