Ошибка HSQLDB «точность или масштаб вне диапазона», когда UCanAccess загружает базу данных - PullRequest
0 голосов
/ 27 декабря 2018

Я пишу инструменты на Java, которые подключаются к различным базам данных доступа.У меня есть особый сценарий, который выдает следующее исключение -5592:UCAExc:::4.0.4 precision or scale out of range

Исключение перечислено в разделе Исключения HSQLDB: 5592=42592 precision or scale out of range (поэтому я знаю, кто его генерирует) и согласно этот ответ , этот другой ответ , и приведенные здесь определения, как точность, так и масштаб, относятся к характеристикам двойного.

Исключение возникает только тогда, когда я использую ucanaccess для подключения кстарый mdb (pre-access 2003) для базы данных внешнего интерфейса со связанными таблицами с mdb.Тем не менее, ucanaccess может подключиться к старому mdb напрямую без каких-либо проблем.

Если я использую интерфейс в Access для изменения базы данных, он работает нормально, поэтому я предполагаю, что MS обошла проблему впо крайней мере в Access.

Я предполагаю, что мое соединение с Ucanaccess пытается обработать базу данных как более современную, будучи обманутым внешним фасадом.Но почему это исключение?

Минимальный завершенный проверяемый пример: Вот минимальный пример для репликации проблемы , содержащей ошибочную базу данных mdb. Это tar-архив gzip, который включает в себя следующееjar, базы данных и полезный файл readme.

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-нарушитель генерирует исключение.

Ответы [ 3 ]

0 голосов
/ 28 декабря 2018
  1. Я позволил себе обновить ваш заголовок.Надеемся, что новая формулировка передает то, что вы имеете в виду.

  2. Пожалуйста, сделайте следующее:

    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) Сравните определения столбцов БД (см. Выше) с соответствующими членами класса Hibernate (например, в вашемлюбимая IDE).

    c) Сравните результаты для "старого" .mdb (который "работает") против "нового" .accdb.

  3. Пожалуйстаобновите ваш пост с результатами.

0 голосов
/ 29 декабря 2018

Как оказалось, эта конкретная проблема не имеет никакого отношения к десятичным числам или числовым столбцам вообще.Это ошибка в UCanAccess, вызванная ошибкой в Jackcess , когда ширина поля TEXT Access_97 ошибочно указывается как половина его фактической ширины.

В рассматриваемой базе данных есть таблицасо столбцом, определенным как TEXT (1), поэтому Jackcess getLengthInUnits сообщает ноль (из-за целочисленного деления).UCanAccess пытается создать таблицу в базе данных HSQLDB как

CREATE  CACHED TABLE DETCAD(SERIE VARCHAR(0), ...

, а VARCHAR(0) вызывает исключение "точность или масштаб вне диапазона".

jackcess-2.2.2.jar исправляет проблему.Вы можете использовать его для замены файла jackcess-2.1.11.jar, который поставляется с UCanAccess 4.0.4.

0 голосов
/ 27 декабря 2018

Точность - это максимальное общее количество цифр в десятичной дроби.Шкала - это число цифр справа от десятичной точки ( 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'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...