2017-02-13 146 views
0

我實際上想使用構造JSON_TABLE來查詢存儲在Oracle數據庫中的JSON字符串。這工作得很好。使用JSON_TABLE和Java同時在Oracle數據庫上查詢JSON

SQL查詢

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

JSON字符串在DB

(它是由從方式的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"}}}}} 

現在我想在普通的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數據庫: Oracle數據庫12c的企業版發行12.1.0.2.0 - 64位生產

燦有人在這種情況下幫助我?其實我真的很失落如何解決這個問題。非常感謝你們!

回答

0

您是否安裝了最新的補丁集(補丁24968615:DATABASE PROACTIVE BUNDLE PATCH 12.1.0.2.170117)。 這應該解決這個問題。

+1

對不起,延遲迴復。我們的系統已更新到第2版(Oracle Database 12c企業版版本12.2.0.1.0 - 64位生產版)。現在它工作正常。我沒有嘗試你提到的補丁。但可能這是正確的解決方案。謝謝你的幫助。 – Evoltafreak

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-schemas或nulls。嘗試改變你的SQL以通過rowid進行過濾,其中row在上面顯示時具有字符串,然後再次測試應用程序。可能當你在IDE中檢查sql(比方說Pl/SQl開發人員)時,它只選擇第一行,爲什麼它可以工作,但是當你在應用程序中運行它時,嘗試一次選擇所有行並選擇其他(或空值)模式行。

+0

嘿伊萬。謝謝你們的快速響應。我也在我的Java代碼中嘗試了你的sql。所以我直接訪問JSON而不使用我的JSON數據庫表。奇怪的是,它有時會起作用,有時不起作用。我試了幾次,這個異常有時看起來像三次,一次甚至沒有異常被調用。我也嘗試用ROWNUM = 1來過濾它,所以它只選擇一行。同樣的行爲......它似乎真的是隨機的。也許是一個錯誤? – Evoltafreak

+0

是的,有趣。我沒有給出這個值,但我也有執行異常:'java.sql.SQLRecoverableException:沒有更多的數據從套接字'讀取。它可能發生三次,兩次,一次或沒有一次。關於這個錯誤,我確實找到了驅動程序問題的答案。可能可能是這是多目標驅動程序錯誤。 –

+0

看起來像JSON_TABLE結構,它以關係方式映射JSON結構導致問題。我將爲此做一個解決方法,並使用JSON_VALUE和JSON_QUERY函數來選擇特定的值。這些功能在我同時使用它們時不會產生任何問題。不過謝謝你的貢獻。 – Evoltafreak