如何使用Kotlin Exposed调用Oracle数据库中的函数/存储过程
Exposed 调用 Oracle 自定义函数与存储过程实操方案
调用自定义函数
Exposed 支持两种常用的函数调用方式,可根据使用场景选择:
- 单次快速调用:直接通过
exec执行原生查询获取返回值
示例:调用入参为用户ID、返回用户年龄的标量函数GET_USER_AGEimport org.jetbrains.exposed.sql.transactions.transaction import org.jetbrains.exposed.sql.exec import org.jetbrains.exposed.sql.VarCharColumnType fun getUserAgeById(userId: String): Int? { return transaction { exec( stmt = "SELECT GET_USER_AGE(?) FROM DUAL", args = listOf(VarCharColumnType() to userId) ) { resultSet -> if (resultSet.next()) resultSet.getInt(1) else null } } } - 封装复用调用:自定义函数表达式,可直接嵌入Exposed查询语法中使用
import org.jetbrains.exposed.sql.CustomFunction import org.jetbrains.exposed.sql.IntegerColumnType import org.jetbrains.exposed.sql.VarCharColumnType // 定义自定义函数映射 fun getUserAge(userId: String) = CustomFunction<Int>( functionName = "GET_USER_AGE", returnType = IntegerColumnType(), VarCharColumnType() to userId ) // 业务代码中直接使用,无需写原生SQL fun queryUserWithAge(userId: String): Pair<String, Int> { return transaction { Users.select(Users.id, getUserAge(Users.id)) .where { Users.id eq userId } .single() .let { it[Users.id] to it[getUserAge(Users.id)] } } }
调用存储过程
存储过程需要处理IN/OUT/INOUT参数,直接通过JDBC预处理语句执行call指令即可:
示例:调用创建用户的存储过程CREATE_USER,入参为用户名、年龄,出参为生成的用户ID
import org.jetbrains.exposed.sql.transactions.transaction import java.sql.Types fun createUser(userName: String, age: Int): String? { return transaction { var newUserId: String? = null connection.prepareStatement("call CREATE_USER(?, ?, ?)", false).use { stmt -> // 绑定IN参数 stmt.setString(1, userName) stmt.setInt(2, age) // 注册OUT参数 stmt.registerOutParameter(3, Types.VARCHAR) // 执行存储过程 stmt.execute() // 读取返回的出参值 newUserId = stmt.getString(3) } newUserId } }
注意事项
- 如果存储过程返回REF CURSOR类型的结果集,注册出参时指定类型为
OracleTypes.CURSOR,获取后转为ResultSet遍历即可 - Exposed 0.40及以上版本提供了更简化的存储过程调用API,可直接调用
transaction.call()方法,无需手动管理预处理语句生命周期 - 所有数据库操作逻辑必须放在
transaction事务块内执行,Exposed会自动处理连接的申请、释放和事务提交回滚
内容的提问来源于stack exchange,提问作者Guy Sirakulphongsa
相关产品推荐
相关产品推荐

