【发布时间】:2021-03-19 18:29:40
【问题描述】:
我有一个存储的 Oracle 过程,我这样调用:
CALL MY_PROC(
p_arg => #{arg, jdbcType=INTEGER, mode=IN},
p_var => #{var, jdbcType=VARCHAR, mode=IN},
p_date => #{date, jdbcType=DATE, mode=IN}
)
我使用MyBatis 写了它,如下所示:
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.MyMapper">
<update id="callMyProc" statementType="CALLABLE">
CALL MY_PROC(
p_arg => #{arg, jdbcType=INTEGER, mode=IN},
p_var => #{var, jdbcType=VARCHAR, mode=IN},
p_date => #{date, jdbcType=DATE, mode=IN}
)
</update>
</mapper>
该过程本身做了一些FOR UPDATE,因为我必须在更新它们之前锁定行。代码完成了它的工作,但我现在想编写一些集成测试,我使用 H2 作为数据库。我知道在这种情况下,我应该编写用户定义的函数来处理这种情况。我很确定写一个例如(为了问题,简化了 sql 查询):
CREATE ALIAS IF NOT EXISTS MY_PROC AS $$
import java.net.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.UUID;
import java.time.LocalDateTime;
@CODE
void callMyProc(Connection conn, Integer p_arg, String p_var, LocalDateTime p_date) throws Exception {
String sqlStatement = String.format("UPDATE mytable SET myvar = '%s', mydate = '%t' WHERE myarg = %d", p_var, p_date, p_arg);
PreparedStatement ps = conn.prepareStatement(sqlStatement);
ps.execute();
}
$$;
可以解决问题,但不幸的是,由于 MyBatis 格式,我遇到了语法错误:
### The error may exist in com.example/MyMapper.xml
### The error may involve com.example.MyMapper.callMyProc
### The error occurred while executing an update
### SQL: CALL MY_PROC( p_arg => ?, p_var => ?, p_date => ? )
### Cause: org.h2.jdbc.JdbcSQLSyntaxErrorException: Błąd składniowy w wyrażeniu SQL "CALL MY_PROC(
P_ARG[*] => ?,
P_VAR[*] => ?,
P_DATE[*] => ?
)"
Syntax error in SQL statement "CALL MY_PROC(
P_ARG[*] => ?,
P_VAR[*] => ?,
P_DATE[*] => ?
CALL MY_PROC(
p_arg => ?,
p_var[*] => ?,
p_date[*] => ?
) [42000-200]
我的问题是,我应该如何为该过程编写我的 H2 别名,以便同时满足 MyBatis 和 H2 的要求?
【问题讨论】:
-
H2 似乎不支持
p_x => ?语法,即使是MODE=Oracle。尝试将参数引用从p_x => #{y}更改为#{y}。
标签: java oracle stored-procedures h2 mybatis