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

如何使用Kotlin Exposed调用Oracle数据库中的函数/存储过程

Exposed 调用 Oracle 自定义函数与存储过程实操方案

调用自定义函数

Exposed 支持两种常用的函数调用方式,可根据使用场景选择:

  • 单次快速调用:直接通过 exec 执行原生查询获取返回值
    示例:调用入参为用户ID、返回用户年龄的标量函数GET_USER_AGE
    import 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 02:45:03