UCanAccess 加载数据库时出现 HSQLDB "precision or scale out of range" 错误
HSQLDB "precision or scale out of range" error when UCanAccess loads database
我正在 java 中编写连接到不同访问数据库的工具。我有一个特定的场景会抛出以下异常 -5592:UCAExc:::4.0.4 precision or scale out of range
异常列在 HSQLDB 异常下:
5592=42592 precision or scale out of range
(所以我知道是谁生成的)
并且根据 this answer, this other answer 和此处的定义,精度和小数位都指的是双精度的特征。
仅当我使用 ucanaccess 连接到旧的 mdb(pre-access 2003)通过前端数据库与 mdb 的链接表时才会发生异常。然而,ucanaccess 可以直接连接到旧的 mdb,没有任何问题。
如果我使用 Access 中的前端修改数据库,它工作正常,所以我假设 MS 至少在 Access 中解决了这个问题。
我的猜测是我的 ucanaccess 连接试图将数据库视为更现代的数据库,被前端外观所愚弄。但是为什么会出现这个异常?
最小的完整可验证示例:
这是一个包含有问题的 mdb 的 minimal example to replicate the issue,是一个 gzip tarball,其中包括以下 jar、涉及的数据库和一个有用的自述文件。
public static void main(String[] args) {
String query= "SELECT nombre FROM encemp where cveemp=1";
try {
Connection frontEndToAccdb = DriverManager.getConnection("jdbc:ucanaccess://FrontEndPointingToAccdb.accdb");
PreparedStatement statement = frontEndToAccdb.prepareStatement(query);
ResultSet resultSet = statement.executeQuery();
if (resultSet.next()) System.out.println("Querying Accdb BackEnd through front end OK");
Connection directConnectionToMdb = DriverManager.getConnection("jdbc:ucanaccess://X:/BackendOld.mdb");
statement = directConnectionToMdb.prepareStatement(query);
resultSet = statement.executeQuery();
if (resultSet.next()) System.out.println("Querying mdb BackEnd directly OK");
//This is the one that will generate the exception
Connection frontEndToMdb = DriverManager.getConnection("jdbc:ucanaccess://FrontEndPointingToMdb.accdb");
statement = frontEndToMdb.prepareStatement(query);
resultSet = statement.executeQuery();
if (resultSet.next()) System.out.println("Querying mdb BackEnd through front end OK");
} catch (SQLException ex) {
System.out.printf("%s:%s\n", ex.getErrorCode(),ex.getMessage());
}
我一直在努力浏览 DatabaseMetaData,但仍然不知道为什么有问题的 mdb 会生成异常。
精度是小数的最大总位数。小数位数是小数点右边的位数 (ref)。因此,如果您有 decimal(20,10)
那么它将是小数点左侧 10 位数字和小数点右侧 10 位数字,总共 20 位数字。即 1234567890.1234567890
。最大精度为38,默认为18。
例子
decimal(38,0): '12345678912345678912345678912345678900'
decimal(38,1): '1234567891234567891234567891234567890.0'
decimal(38,2): '123456789123456789123456789123456789.00'
decimal(38,3): '12345678912345678912345678912345678.900'
decimal(10,8): '12.12345678'
我冒昧地更新了你的标题。希望新的措辞表达了你的意思。
请执行以下操作:
a) 直接查询有问题的列定义。例如:
// GetMetaData():
try (ResultSet rsMD = connChem.getMetaData().getTables(null, null, null, null)) {
while (rsMD.next()) {
String tblName = rsMD.getString("TABLE_NAME");
System.out.println(tblName);
}
}
...或...
-- SQL "select" from MSysObjects
SELECT Name
FROM MSysObjects
WHERE Left([Name],1)<>"~"
AND Left([Name],4)<>"MSys"
AND Type In (1,4,6)
ORDER BY Name;
b) 将 DB 列定义(上面)与相应的 Hibernate class 成员(例如,在您最喜欢的 IDE 中)进行比较。
c) 比较 "old" .mdb("works")与 "new" .accdb.
的结果
请用结果更新您的 post。
事实证明,这个特定问题与 DECIMAL 数字或数字列完全无关。这是 UCanAccess 中的一个错误,由 bug in Jackcess 导致 Access_97 TEXT 字段的宽度被错误报告为其实际宽度的一半。
有问题的数据库有一个 table,其列定义为 TEXT(1),因此 Jackcess getLengthInUnits
报告零(因为整数除法)。 UCanAccess 尝试在 HSQLDB 后备数据库中创建一个 table 作为
CREATE CACHED TABLE DETCAD(SERIE VARCHAR(0), ...
并且 VARCHAR(0)
正在触发 "precision or scale out of range" 异常。
jackcess-2.2.2.jar 修复了这个问题。您可以使用它来替换 UCanAccess 4.0.4.
附带的 jackcess-2.1.11.jar 文件
我正在 java 中编写连接到不同访问数据库的工具。我有一个特定的场景会抛出以下异常 -5592:UCAExc:::4.0.4 precision or scale out of range
异常列在 HSQLDB 异常下:
5592=42592 precision or scale out of range
(所以我知道是谁生成的)
并且根据 this answer, this other answer 和此处的定义,精度和小数位都指的是双精度的特征。
仅当我使用 ucanaccess 连接到旧的 mdb(pre-access 2003)通过前端数据库与 mdb 的链接表时才会发生异常。然而,ucanaccess 可以直接连接到旧的 mdb,没有任何问题。
如果我使用 Access 中的前端修改数据库,它工作正常,所以我假设 MS 至少在 Access 中解决了这个问题。
我的猜测是我的 ucanaccess 连接试图将数据库视为更现代的数据库,被前端外观所愚弄。但是为什么会出现这个异常?
最小的完整可验证示例: 这是一个包含有问题的 mdb 的 minimal example to replicate the issue,是一个 gzip tarball,其中包括以下 jar、涉及的数据库和一个有用的自述文件。
public static void main(String[] args) {
String query= "SELECT nombre FROM encemp where cveemp=1";
try {
Connection frontEndToAccdb = DriverManager.getConnection("jdbc:ucanaccess://FrontEndPointingToAccdb.accdb");
PreparedStatement statement = frontEndToAccdb.prepareStatement(query);
ResultSet resultSet = statement.executeQuery();
if (resultSet.next()) System.out.println("Querying Accdb BackEnd through front end OK");
Connection directConnectionToMdb = DriverManager.getConnection("jdbc:ucanaccess://X:/BackendOld.mdb");
statement = directConnectionToMdb.prepareStatement(query);
resultSet = statement.executeQuery();
if (resultSet.next()) System.out.println("Querying mdb BackEnd directly OK");
//This is the one that will generate the exception
Connection frontEndToMdb = DriverManager.getConnection("jdbc:ucanaccess://FrontEndPointingToMdb.accdb");
statement = frontEndToMdb.prepareStatement(query);
resultSet = statement.executeQuery();
if (resultSet.next()) System.out.println("Querying mdb BackEnd through front end OK");
} catch (SQLException ex) {
System.out.printf("%s:%s\n", ex.getErrorCode(),ex.getMessage());
}
我一直在努力浏览 DatabaseMetaData,但仍然不知道为什么有问题的 mdb 会生成异常。
精度是小数的最大总位数。小数位数是小数点右边的位数 (ref)。因此,如果您有 decimal(20,10)
那么它将是小数点左侧 10 位数字和小数点右侧 10 位数字,总共 20 位数字。即 1234567890.1234567890
。最大精度为38,默认为18。
例子
decimal(38,0): '12345678912345678912345678912345678900'
decimal(38,1): '1234567891234567891234567891234567890.0'
decimal(38,2): '123456789123456789123456789123456789.00'
decimal(38,3): '12345678912345678912345678912345678.900'
decimal(10,8): '12.12345678'
我冒昧地更新了你的标题。希望新的措辞表达了你的意思。
请执行以下操作:
a) 直接查询有问题的列定义。例如:
// GetMetaData(): try (ResultSet rsMD = connChem.getMetaData().getTables(null, null, null, null)) { while (rsMD.next()) { String tblName = rsMD.getString("TABLE_NAME"); System.out.println(tblName); } }
...或...
-- SQL "select" from MSysObjects SELECT Name FROM MSysObjects WHERE Left([Name],1)<>"~" AND Left([Name],4)<>"MSys" AND Type In (1,4,6) ORDER BY Name;
b) 将 DB 列定义(上面)与相应的 Hibernate class 成员(例如,在您最喜欢的 IDE 中)进行比较。
c) 比较 "old" .mdb("works")与 "new" .accdb.
的结果
请用结果更新您的 post。
事实证明,这个特定问题与 DECIMAL 数字或数字列完全无关。这是 UCanAccess 中的一个错误,由 bug in Jackcess 导致 Access_97 TEXT 字段的宽度被错误报告为其实际宽度的一半。
有问题的数据库有一个 table,其列定义为 TEXT(1),因此 Jackcess getLengthInUnits
报告零(因为整数除法)。 UCanAccess 尝试在 HSQLDB 后备数据库中创建一个 table 作为
CREATE CACHED TABLE DETCAD(SERIE VARCHAR(0), ...
并且 VARCHAR(0)
正在触发 "precision or scale out of range" 异常。
jackcess-2.2.2.jar 修复了这个问题。您可以使用它来替换 UCanAccess 4.0.4.
附带的 jackcess-2.1.11.jar 文件