Я действительно хочу запросить 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-битное производство
Может ли кто-нибудь помочь мне в этом случае? На самом деле я действительно потерял решение этой проблемы. Спасибо, ребята, много!
Установили ли вы последний набор исправлений (Patch 24968615: DATABASE PROACTIVE BUNDLE PATCH 12.1.0.2.170117). Это должно решить проблему.
Я запустил 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), он выбирает только первые строки, поэтому он работает, но когда вы запускаете его в приложении, попробуйте выбрать сразу все строки и выбрать другие (или нулевые) строки схем,
java.sql.SQLRecoverableException: No more data to read from socket
. Это может произойти три, два, один или ни разу. Об этой ошибке я нашел ответы, которые являются проблемой водителя. Возможно, это ошибка многопоточного драйвера.