Oracle ResultSetMetaData getPrecision/getScale
我正在使用 Oracle 的 JDBC 瘦驱动程序 (10.2.0.3) 连接到 Oracle 10g 数据库。我想获取有关数据库列的信息,因此我使用 结果集元数据。我需要的最重要的信息是列的类型和长度,因此我使用 getColumnType, getPrecision 和 getScale 方法。
如果列类型是“简单”,如 VARCHAR2(50)、NUMBER(5)、NUMBER(6,2),则它适用于简单查询 (select * from tablename
) >。如果我有一个更复杂的查询(select count(*) from tablename
)或基于包含一些复杂计算的视图的查询,这些方法会给出奇怪的结果,例如:
getScale
: -127getPrecision
和getScale
均为 0getPrecision
: -1
设置 oracle.jdbc.J2EE13Compliant
连接属性设置为 true
(如几个网页所建议的)消除了 getScale=-127 但仍返回 0/0 结果。
我很可能必须为这些奇怪的结果创建一个解决方法,但首先我至少需要一份有关 Oracle ResultSetMetaData 行为的综合文档。例如,对于所有 SQL 类型来说,一个具有 getPrecision/getScale 含义的巨大表会很棒。某处有类似的文档吗?
I'm using Oracle's JDBC thin driver (10.2.0.3) for connecting to an Oracle 10g database. I'd like to get information about the database columns, so I use ResultSetMetaData. The most important information I need is the type of the column and the length, so I use getColumnType, getPrecision, and getScale methods.
It works for a simple query (select * from tablename
) if the column type is "simple" like VARCHAR2(50), NUMBER(5), NUMBER(6,2)
. If I have a more complex query (select count(*) from tablename
) or a query based on a view which contains some complex calculation, the methods give weird results like:
getScale
: -127- both
getPrecision
andgetScale
is 0 getPrecision
: -1
Setting the oracle.jdbc.J2EE13Compliant
connection property to true
(as suggested by several webpages) eliminates getScale=-127 but still returns 0/0 result.
Most likely I have to create a workaround for these weird results, but first I need at least a comprehensive documentation about the behavior of Oracle's ResultSetMetaData. For instance a huge table with the meaning of getPrecision/getScale for all the SQL types would be great. Is there a documentation like this somewhere?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
Oracle 无法返回基于视图或 count(*) 的类型,因为它未显式声明。您的视图可以返回任何精度或比例,具体取决于视图的底层表。
为了克服这个问题,您需要在查询或视图中转换类型,如下所示:
Oracle can not return a type based on a view or the
count(*)
as it was not explicitly declared. Your view could return any precision or scale depending on the underlaying tables of the view.To overcome this you would need to cast the type in your query or view like this:
另一种方法是查询
user_tab_columns
或all_tab_columns
。An alternative is to query
user_tab_columns
orall_tab_columns
.可接受小数位数 0:NUMBER(5) 与 NUMBER(5,0) 相同。
但是,定义精度时,精度必须是 1 到 38 之间的整数。当它未定义时,如 NUMBER 中,驱动程序必须返回一些内容,因为它不能返回 null。在这种情况下,驱动程序选择返回 0。
A scale of 0 is acceptable: a NUMBER(5) is the same as a NUMBER(5,0)
The precision however must be an integer between 1 and 38 when it is defined. When it is undefined, as in NUMBER, the driver has to return something since it cannot return null. In that case the driver chooses to return 0.
在我看来,没有关于 ResultSetMetaData 的全面文档。
Oracle® 数据库 JDBC 开发人员指南和参考 10g 第 2 版 ( 10.2) 和 11g 版本 2 (11.2 ) 给出了有关列名称和类型的示例 这里,他们不涉及其他方面。
几年前,有人在 PostgreSQL 上遇到了类似的问题,他做了一个补丁。也许 Oracle 在这里使用相同的代码库。
您可以尝试使用 ojdbc14_g.jar 而不是 ojdbc14.jar,因为它的类是使用“javac -g”编译的并且包含一些跟踪信息。
您还可以尝试较新的驱动程序。
It seems to me that there is no comprehensive documentation on ResultSetMetaData.
Oracle® Database JDBC Developer's Guide and Reference 10g Release 2 (10.2) and 11g Release 2 (11.2) gives example about column name and type here, they does not deal with other aspects.
Someone had a similar problem with PostgreSQL years ago and he made a patch. Maybe Oracle uses the same codebase here.
You may try to use the ojdbc14_g.jar instead of ojdbc14.jar as its classes were compiled with "javac -g" and contain some tracing information.
You may also try newer drivers.
您可以使用 rs.getBigDecimal(columnIndex) 并从大十进制中获取特定列的精度/小数位数值。
You can use the
rs.getBigDecimal(columnIndex)
and from the big decimal you can get the precision / scale values of the specific columns.不是对您的问题的直接答复,而是您提到的解决方法:
如果您所要做的就是检查或比较数据库模式,则不要使用 ResultSetMetaData 并查询所有表,而是使用 Oracle 模式信息,如 对数据模型进行逆向工程。我在我的实用程序中使用它来将此类信息导出为文本
Not a direct reply to your question, but a workaround you mentioned:
If all you have to do is check or compare db schemas, then instead of ResultSetMetaData and querying all the tables use Oracle schema information as described in Reverse Engineering a Data Model. I used it in my utility to export such information to text