You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MyBatis调用Oracle自定义函数遇ORA-00904错误的解决咨询

解决MyBatis调用Oracle带命名空间函数的ORA-00904错误

问题背景

存在Oracle包函数secureUser.collection.getExampleId,该函数可根据传入的keyId返回Example Id。在PL/SQL中直接执行调用该函数的SQL语句可正常返回结果,但在MyBatis Mapper中调用时触发ORA-00904错误,提示"SECUREUSER"."COLLECTION"."GETEXAMPLEID": 无效标识符,推测是MyBatis自动给函数名添加引号导致解析错误。

解决方案

方法1:使用CDATA块包裹函数调用

MyBatis解析SQL时会对包含特殊字符(如点号)的内容进行错误转义,使用CDATA块可以让函数调用部分直接原样传递给Oracle执行,避免MyBatis的自动引号添加。修改后的Mapper代码如下:

<mapper namespace="core.namespace.dao.mybatis.MyMapper">
   <resultMap id="Data" type="core.model.impl.table">
      <result column="column1" property="one" />
      <result column="column2" property="two" />
      <result column="column3" property="three" />
      <result column="secure" property="sec" />
   </resultMap>

   <select id="getSecure" parameterType="java.lang.Long" resultMap="Data">
      select column1, column2, column3, 
      <![CDATA[ secureUser.collection.getExampleId(#{id}) ]]> secure
      from mytable mt
      where mt.keyId = #{id}
   </select>
</mapper>

方法2:严格匹配对象大小写(若对象创建时使用双引号)

如果Oracle中的包和函数是通过双引号指定大小写创建的(如CREATE PACKAGE "secureUser"."collection"),则调用时必须用双引号包裹每个命名空间部分,确保Oracle能识别正确的对象:

<select id="getSecure" parameterType="java.lang.Long" resultMap="Data">
  select column1, column2, column3, 
  "secureUser"."collection"."getExampleId"(#{id}) secure
  from mytable mt
  where mt.keyId = #{id}
</select>

原理说明

MyBatis默认会对SQL中的标识符进行解析,当遇到包含点号的内容时,可能误将其识别为表-列结构并自动添加引号,导致Oracle无法识别包函数的完整路径。CDATA块会屏蔽MyBatis的解析逻辑,让函数调用语句原封不动发送到数据库执行;而严格匹配大小写则是保证Oracle能找到正确的大小写敏感对象。

内容的提问来源于stack exchange,提问作者David Hash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 02:52:53