Запросы JSON одновременно в БД Oracle с помощью JSON_TABLE и Java

2

Я действительно хочу запросить JSON-String, который хранится в базе данных Oracle, используя конструкцию JSON_TABLE. Это работает очень хорошо.

SQL-запрос

SELECT f.val 
from JSON, 
     JSON_TABLE(json,'$' COLUMNS(val VARCHAR(4000) PATH '$.glossary.GlossDiv.GlossList.GlossEntry.GlossTerm')) as f

JSON-String в БД

(Это, кстати, пример JSON от json.org/example.html)

{"glossary":{"title":"example glossary","GlossDiv":{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}}}

Теперь я хочу выполнить запрос в обычном Java-приложении. Я использую его одновременно в пяти потоках. Вот как я могу воспроизвести проблему. В моем первоначальном варианте использования я нажимаю кнопку очень быстро на веб-сайте, который выполняет этот запрос.

JsonRunnable.java

public class JsonRunnable implements Runnable {

    public void run() {

    try {

        List<String> list = new ArrayList<String>();

        java.util.Properties connProperties = new java.util.Properties();
        connProperties.put("user", "");
        connProperties.put("password", "");

        Class.forName("oracle.jdbc.driver.OracleDriver");
        String database =
                "jdbc:oracle:thin:@myserver.com:1521/DB";
        Connection conn = DriverManager.getConnection(database, connProperties);

        String sql = "SELECT f.val from JSON, JSON_TABLE(json,'$' COLUMNS(val VARCHAR(4000) PATH '$.glossary.GlossDiv.GlossList.GlossEntry.GlossTerm')) as f";
        PreparedStatement s1 = conn.prepareStatement(sql);

        s1.execute(sql);
        ResultSet rs = s1.getResultSet();

        while (rs.next()) {
            list.add(rs.getString(1));
        }

        s1.close();
        conn.close();

        System.out.println(list.get(0));

    } catch (Exception ex) {
        System.out.println(ex);
    }
}

}

Main.java

public class Main {
public static void main(String[] args) {
    for(int i = 0;i < 5;i++){
        new Thread(new JsonRunnable()).start();
    }
}
}

Теперь я получаю эту ошибку, которая говорит мне, что что-то не удалось во время разбора и обработки XML (сообщение об ошибке находится на немецком языке, но вы можете увидеть сообщение об ошибке ORA):

java.sql.SQLException: ORA-19114: XPST0003 - Fehler beim Parsen des XQuery Ausdrucks: 
ORA-19202: Fehler bei XML-Verarbeitung 
jzntSCV1:invState2 aufgetreten

Драйвер Oracle: OJDBC 7 12.1.0.1

Java: 1.8

Oracle DB: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64-битное производство

Может ли кто-нибудь помочь мне в этом случае? На самом деле я действительно потерял решение этой проблемы. Спасибо, ребята, много!

Теги:
database

2 ответа

1
Лучший ответ

Установили ли вы последний набор исправлений (Patch 24968615: DATABASE PROACTIVE BUNDLE PATCH 12.1.0.2.170117). Это должно решить проблему.

  • 2
    Извините за задержку с ответом. Наши системы были обновлены до Выпуска 2 (Oracle Database 12c Enterprise Edition Выпуск 12.2.0.1.0 - 64-разрядная версия). Теперь работает нормально. Я не пробовал патч, который вы упомянули. Но, вероятно, это правильное решение. Спасибо за вашу помощь.
1

Я запустил sql:

select f.val from (
    select '{"glossary":{"title":"example glossary","GlossDiv":{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}}}'
        as json from dual) v
   ,JSON_TABLE(json,'$' COLUMNS(val VARCHAR(4000) PATH '$.glossary.GlossDiv.GlossList.GlossEntry.GlossTerm')) as f

И это правильно. Тогда я сделал приложение, как и вы. И попробуйте 12.0.1.1 и 12.0.1.2 драйверы. Оба работают хорошо. Приложение правильно, а также sql.

Единственная идея, которую я имею о проблеме, заключается в том, что ваша json-таблица имеет разные json-схемы или нули в разных строках. Попробуйте изменить sql для фильтрации по rowid, где строка имеет строку, как показано выше, и тестовое приложение снова. Вероятно, когда вы проверяете sql в IDE (скажем, разработчик Pl/SQl), он выбирает только первые строки, поэтому он работает, но когда вы запускаете его в приложении, попробуйте выбрать сразу все строки и выбрать другие (или нулевые) строки схем,

  • 1
    Привет, Иван. Спасибо за Ваш быстрый ответ. Я попробовал ваш sql в моем коде Java также. Таким образом, я обращаюсь к JSON напрямую без моей таблицы базы данных JSON. Странно то, что иногда это работает, а иногда не работает. Я попробовал это пару раз, и исключение иногда появляется как три раза, один раз или даже не вызывается исключение. Я также попытался отфильтровать его с ROWNUM = 1, поэтому он просто выбирает одну строку. Такое же поведение ... Кажется, это действительно случайно. Может быть, ошибка?
  • 0
    Да, интересно. Я не дал значение этому, но у меня также есть исключения в выполнении: java.sql.SQLRecoverableException: No more data to read from socket . Это может произойти три, два, один или ни разу. Об этой ошибке я нашел ответы, которые являются проблемой водителя. Возможно, это ошибка многопоточного драйвера.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню