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

如何使用Scala连接Oracle读取大量数据及字符集报错问题求助

问题排查

你的错误分为两类:字符集依赖缺失,以及代码本身的逻辑错误。

1. 字符集依赖问题

异常提示已经明确说明:你连接的Oracle库使用了AR8MSWIN1256(阿拉伯语Windows编码)字符集,Oracle官方JDBC默认只包含常用字符集支持,这类小众字符集需要额外引入orai18n.jar扩展包才能正常解析。

2. 代码逻辑错误

  • 你将创建函数的DDL语句和查询语句拼接在一起执行,executeQuery方法仅支持执行单条查询语句,无法同时执行DDL+查询逻辑
  • ResultSet遍历顺序错误:当前使用do-while会先尝试读取第一行数据再判断是否存在下一行,首次读取就会抛出空结果异常
  • 数据库连接、Statement、ResultSet使用完成后未主动释放,会造成连接资源泄漏
  • 直接拼接SQL存在SQL注入风险,且拼接过程容易出现语法错误

修复方案

1. 补充字符集依赖

根据你使用的构建工具添加对应依赖,注意orai18n的版本必须和你当前使用的ojdbc驱动版本完全一致:

  • SBT配置:
libraryDependencies += "com.oracle.database.nls" % "orai18n" % "你的ojdbc版本号"
  • 无构建工具的项目,直接下载对应版本的orai18n.jar放入项目依赖目录,添加到运行时classpath即可。

2. 修复代码逻辑

建议直接将自定义函数的逻辑整合到查询语句中,无需每次执行都创建临时函数,同时优化资源管理和遍历逻辑:

import java.sql.Connection
import oracle.jdbc.pool.OracleDataSource
import scala.util.Using

object ReadTable extends App {
  val num = 4
  val tableName = "table"
  val colName = "col"
  val oracleUser = "orcl"
  val oraclePassword = "******"
  val oracleURL = "jdbc:oracle:thin:@//x.x.x.x:1521/orcldb"

  // 提前初始化数据源,无需每次调用方法都创建
  private val ods = new OracleDataSource()
  ods.setUser(oracleUser)
  ods.setURL(oracleURL)
  ods.setPassword(oraclePassword)

  def readData(groupId: Int): Unit =  {
    // 函数逻辑直接写到查询条件中,用?占位符避免注入
    val query = s"""
      select * from $tableName 
      where MOD(TO_NUMBER(substr($colName, -LEAST(2, LENGTH($colName)))), $num) = ?
    """

    // 使用Using自动管理资源,无需手动关闭
    Using.Manager { use =>
      val con = use(ods.getConnection())
      val statement = use(con.prepareStatement(query))
      statement.setInt(1, groupId)
      statement.setFetchSize(1000)
      val resultSet = use(statement.executeQuery())

      while (resultSet.next()) {
        val cst = resultSet.getString("cst")
        val name = resultSet.getString("name")
        println(s"cst = $cst, name = $name")
      }
    }.recover {
      case e: Exception => e.printStackTrace()
    }
  }

  readData(1)
}

如果你确实需要创建自定义函数,单独用statement.execute(ddl语句)执行创建逻辑即可,不要和查询语句拼接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:45:00