【问题标题】:java.sql.SQLException: Unrecognized SQL type -102 while connecting to Oracle Database from Apache Sparkjava.sql.SQLException:从 Apache Spark 连接到 Oracle 数据库时无法识别 SQL 类型 -102
【发布时间】:2019-10-30 08:49:27
【问题描述】:

我正在尝试将远程 Oracle 数据库表加载到 Apache Spark shell。

这就是我启动 spark-shell 的方式。

./spark-shell --driver-class-path ../jars/ojdbc6.jar --jars ../jars/ojdbc6.jar --master local

然后我得到一个 Scala 提示,我尝试加载如下所示的 Oracle 数据库表。 (我使用自定义 JDBC URL)

val jdbcDF = spark.read.format("jdbc").option("url", "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=WHATEVER)(HOST=myDummyHost.com)(PORT=xxxx)))(CONNECT_DATA=(SERVICE_NAME=dummy)(INSTANCE_NAME=dummyKaMummy)(UR=A)(SERVER=DEDICATED)))").option("dbtable", "THE_DUMMY_TABLE").option("user", "DUMMY_USER").option("password", "DUMMYPASSWORD").option("driver", "oracle.jdbc.driver.OracleDriver").load()

(用虚拟变量替换雇主数据)

然后我得到这个错误。

java.sql.SQLException: Unrecognized SQL type -102
  at org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$.org$apache$spark$sql$execution$datasources$jdbc$JdbcUtils$$getCatalystType(JdbcUtils.scala:246)
  at org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$$anonfun$8.apply(JdbcUtils.scala:316)
  at org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$$anonfun$8.apply(JdbcUtils.scala:316)
  at scala.Option.getOrElse(Option.scala:121)
  at org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils$.getSchema(JdbcUtils.scala:315)
  at org.apache.spark.sql.execution.datasources.jdbc.JDBCRDD$.resolveTable(JDBCRDD.scala:63)
  at org.apache.spark.sql.execution.datasources.jdbc.JDBCRelation$.getSchema(JDBCRelation.scala:210)
  at org.apache.spark.sql.execution.datasources.jdbc.JdbcRelationProvider.createRelation(JdbcRelationProvider.scala:35)
  at org.apache.spark.sql.execution.datasources.DataSource.resolveRelation(DataSource.scala:318)
  at org.apache.spark.sql.DataFrameReader.loadV1Source(DataFrameReader.scala:223)
  at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:211)
  at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:167)
  ... 49 elided

我试着看看引号是否有问题,但不是这样。

有人可以救我吗?

【问题讨论】:

  • 考虑尝试更新的 Oracle JDBC 驱动程序。 ojdbc6 表示它是为 Java 6 编写的,所以它已经很老了。
  • @MarkRotteveel 来自https://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html,ojdbc6 适用于 Oracle 11g,这就是我们使用的。
  • 同样来自 Oracle JDBC FAQ,在What are the Oracle JDBC releases Vs JDK versions? 部分,JDK6、JDK7 和 JDK8 支持 ojdbc6.jar。 https://www.oracle.com/technetwork/topics/jdbc-faq-090281.html
  • ojdbc14 适用于 Java 1.4,甚至比 ojdbc6 还要早。如果更新的驱动程序也出现错误,这可能意味着问题出在 Spark 不支持的非标准 Oracle 数据类型上(JDBC 标准中未定义类型代码 -102)。
  • 尝试用问题表的一半列创建一个表,如果没有出现错误,尝试用另一半创建一个表。继续执行此操作,直到您确定存在问题的一列(或多列),然后考虑使用minimal reproducible example 更新您的问题。

标签: sql oracle scala apache-spark jdbc


【解决方案1】:

问题是数据库中的字段不兼容。如果您无法修改数据库,但仍想阅读它,则解决方案是忽略特定列(在我的情况下,它是一个类型为 geography 的字段)。在How to select specific columns through Spack JDBC? 的帮助下,pyspark 中有一个解决方案(scala 解决方案类似):

df = spark.read.jdbc(url=connectionString, table="(select colName from Table) as CompatibleTable", properties=properties)

【讨论】:

  • 上述sql查询中我们也可以使用TO_CHAR()将带有本地时区列的时间戳转换为字符串。
猜你喜欢
  • 1970-01-01
  • 2017-08-27
  • 2017-09-04
  • 1970-01-01
  • 1970-01-01
  • 2018-12-28
  • 1970-01-01
  • 2013-10-03
  • 2020-02-12
相关资源
最近更新 更多