【问题标题】:Oracle driver REALLY compatible with JDBC4与 JDBC4 真正兼容的 Oracle 驱动程序
【发布时间】:2011-05-14 06:18:12
【问题描述】:

我有一个使用普通 JDBC 代码从数据库访问不同属性的应用程序。这与下面的数据库无关。

但是,它使用的其中一项功能要求驱动程序与 JDBC4 兼容(特别是,它试图确定列是否自动递增,访问连接元数据上的 getColumns 结果的 IS_AUTOINCREMENT 值)

见:http://download.oracle.com/javase/6/docs/api/java/sql/DatabaseMetaData.html#getColumns%28java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String%29

问题是,即使使用声称符合 JDBC 4 的 ojdbc6.jar 中包含的 Oracle 的 oracle.jdbc.OracleDriver,它也不会返回添加到 JDBC 4 规范中的 IS_AUTOINCREMENT 列。这会产生 SQLException未知列,并使应用程序无法用于 Oracle dbs。

Oracle的驱动执行的sql查询如下:

SELECT NULL AS table_cat, t.owner AS table_schem, t.table_name AS 表名, t.column_name AS column_name, 解码(t.data_type,'CHAR',1,'VARCHAR2',12,'NUMBER',3, 'LONG', -1, 'DATE', 93, 'RAW', -3, 'LONG RAW', -4,
'BLOB', 2004, 'CLOB', 2005, 'BFILE', -13, 'FLOAT', 6, 'TIMESTAMP(6)', 93, 'TIMESTAMP(6) WITH TIME ZONE', -101, '带有本地时区的时间戳(6)',-102, '间隔年(2)到月',-103, '间隔天(2)到秒(6)',-104, 'BINARY_FLOAT', 100, 'BINARY_DOUBLE', 101, 'XMLTYPE', 2007, 1111) 作为数据类型, t.data_type AS type_name, DECODE (t.data_precision, null, DECODE (t.data_type, 'CHAR', t.char_length,
'VARCHAR', t.char_length,
'VARCHAR2', t.char_length,
'NVARCHAR2', t.char_length,
'NCHAR', t.char_length,
'NUMBER', 0, t.data_length), t.data_precision) 作为列大小, 0 AS 缓冲区长度, 解码(t.data_type,'NUMBER',解码(t.data_precision,
空,-127,
t.data_scale),
t.data_scale) AS decimal_digits, 10 AS num_prec_radix, DECODE (t.nullable, 'N', 0, 1) AS 可以为空, NULL AS 备注, t.data_default AS column_def, 0 AS sql_data_type, 0 AS sql_datetime_sub, t.data_length AS char_octet_length, t.column_id AS ordinal_position, DECODE (t.nullable, 'N', 'NO', 'YES') AS is_nullable FROM all_tab_columns t WHERE t.owner LIKE :1 ESCAPE '/' AND t.table_name LIKE :2 ESCAPE '/' AND t.column_name LIKE :3 ESCAPE '/' ORDER BY table_schem, table_name, ordinal_position

是否有任何驱动程序/替代/解决方法?

【问题讨论】:

  • SQLException 是否包含任何细节?
  • 该列不存在于结果集中。我正在添加执行的查询来说明。

标签: java oracle jdbc oracle10g


【解决方案1】:

这可能是因为IS_AUTOINCREMENT 属性与Oracle 数据库无关。

当然,如果所有 JDBC 驱动程序都真正符合规范会更容易,但通常情况并非如此。如 API 规范中所述,Resultset.getString("IS_AUTOINCREMENT") 在无法确定列是否自动递增时至少应返回一个空字符串。

如果您想模拟这种行为,我建议您使用以下代码:

字符串 isAutoincrement = ""; 尝试 { isAutoincrement = rset.getString("IS_AUTOINCREMENT"); } 捕捉(SQLException sql){ log.warn("IS_AUTOINCREMENT 属性无法检索", sqle); }

如果您打算开发一个与数据库无关的应用程序,您还应该考虑将此技巧用于其他属性,例如“REMARKS”或“COLUMN_DEF”。更一般地说,您的代码应该真正具有防御性,因为不同供应商之间的 JDBC 实现确实不同。

【讨论】:

  • 重点是Oracle不做自动增量列。您必须创建一个序列并使用触发器将其连接到列。
  • @Tom,这就是为什么我说它与 Oracle 无关,但你是对的,我的回答应该更具体。
  • 我应该更具体一点,我只是在扩展你的好答案!
猜你喜欢
  • 1970-01-01
  • 2019-01-10
  • 1970-01-01
  • 1970-01-01
  • 2021-09-22
  • 1970-01-01
  • 2012-03-05
  • 2023-02-13
  • 2016-01-30
相关资源
最近更新 更多