简体   繁体   English

使用JSON_TABLE和Java在Oracle DB上同时查询JSON

[英]Querying JSON simultaneously on Oracle DB with JSON_TABLE and Java

I actually want to query a JSON-String which is stored in an Oracle Database, using the construct JSON_TABLE. 我实际上想要使用构造JSON_TABLE查询存储在Oracle数据库中的JSON-String。 This works pretty well. 这非常有效。

SQL Query SQL查询

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

JSON-String in DB DB中的JSON-String

(It is by the way the example JSON from json.org/example.html) (顺便提一句,来自json.org/example.html的JSON示例)

{"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"}}}}}

Now I want execute the query in a normal Java Application. 现在我想在普通的Java应用程序中执行查询。 I use it simultaneously in five Threads. 我在五个线程中同时使用它。 That is how I can reproduce the problem. 这就是我如何重现这个问题。 In my original use case I press a button really quickly on a website which executes this query. 在我的原始用例中,我在执行此查询的网站上快速按下按钮。

JsonRunnable.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 Main.java

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

Now, I get this error, which tells me that something failed during parsing and processing the XML (The error message is in german but you can see the ORA Error Message): 现在,我收到此错误,它告诉我在解析和处理XML期间出现了错误(错误消息是德语但您可以看到ORA错误消息):

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

Oracle Driver: OJDBC 7 12.1.0.1 Oracle驱动程序: OJDBC 7 12.1.0.1

Java: 1.8 Java: 1.8

Oracle DB: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production Oracle DB: Oracle Database 12c企业版12.1.0.2.0版 - 64位生产

Can someone help me in this case? 在这种情况下,有人可以帮助我吗? I am actually really lost how to solve this problem. 我其实真的失去了如何解决这个问题。 Thank you guys a lot! 非常感谢你们!

Have you installed the latest patch set (Patch 24968615: DATABASE PROACTIVE BUNDLE PATCH 12.1.0.2.170117). 您是否安装了最新的补丁集(Patch 24968615:DATABASE PROACTIVE BUNDLE PATCH 12.1.0.2.170117)。 This should fix the issue. 这应该解决问题。

I did run sql: 我确实运行了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

And it is correct. 这是正确的。 Then I did make app, as well as you do. 然后我做了app,就像你做的那样。 And try 12.0.1.1 and 12.0.1.2 drivers. 并尝试12.0.1.1和12.0.1.2驱动程序。 Both working well. 两者都运作良好。 App is correct as well as sql. 应用程序和sql一样正确。

The only idea that I have about problem is that your json table has different json-schemas or nulls in different rows. 我对问题的唯一想法是你的json表在不同的行中有不同的json-schemas或null。 Try change you sql to filter by rowid, where row has string as you show above and test app again. 尝试更改你的sql以按rowid进行过滤,其中row具有上面显示的字符串并再次测试应用程序。 Probably when you check sql in IDE (let say Pl/SQl developer) it select only first rows, that why it works, but when you run it in app it try select all rows at once and select this other (or nulls) schemas rows. 可能当您在IDE中检查sql(比如说Pl / SQl开发人员)时,它只选择第一行,这就是它的工作原理,但是当你在app中运行它时,尝试一次选择所有行并选择其他(或空)模式行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM