2017-02-13 7 views
0

実際には、JSON_TABLE構成を使用して、Oracle Databaseに格納されているJSON-Stringを照会します。これはかなりうまくいく。JSON_TABLEとJavaでOracle DB上でJSONを同時に照会する

SQLクエリ

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

DB

でJSONストリング(これは、方法によって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アプリケーションでクエリを実行します。私は5つのスレッドで同時に使用します。それが私が問題を再現できる方法です。私のオリジナルのユースケースでは、このクエリーを実行するWebサイト上で本当にすばやくボタンを押します。 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

オラクルDB:のOracle Database 12cのEnterprise Editionのリリース12.1.0.2.0 - 64ビットの生産

ことができますこの場合、誰かが私を助けますか?私は実際にこの問題を解決する方法が本当に失われています。皆さんありがとう!

答えて

0

最新のパッチ・セット(パッチ24968615:データベース・プロアクティブ・バンドル・パッチ12.1.0.2.170117)をインストールしましたか? これで問題は解決します。

+1

遅く返事を申し訳ありません。当社のシステムは、リリース2(Oracle Database 12c Enterprise Editionリリース12.2.0.1.0 - 64bit Production)にアップデートされました。今それは正常に動作します。あなたが言いましたパッチを試しませんでした。しかしおそらくそれは正しい解決策です。ご協力いただきありがとうございます。 – 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またはnullを持つことです。 rowidでフィルタリングするSQLを変更してみてください。上の例のように行に文字列があり、再度アプリケーションをテストしてください。おそらくIDEでsqlをチェックするとき(それはPl/SQl開発者と言う)最初の行だけを選択し、それがなぜ機能するのかをアプリで実行すると、一度にすべての行を選択してこの他の(またはnulls) 。

+0

Hey Ivan。迅速なご回答をありがとうございました。私はJavaコードでもあなたのSQLを試しました。だから私はJSONデータベース・テーブルなしで直接JSONにアクセスします。奇妙なことは時にはうまくいくということで、時にはうまくいかないことがあります。私はそれを数回試してみましたが、時には3回、1回、例外なく呼び出されるような例外が表示されます。 ROWNUM = 1でフィルタリングしようとしたので、ただ1つの行が選択されています。同じ行動...それは本当にランダムに見える。バグかもしれない? – Evoltafreak

+0

はい、面白いです。私はこれに値を付けませんでしたが、実行時に例外があります: 'java.sql.SQLRecoverableException:ソケットから読み取るデータがもうありません '。それは3回、2回、1回または1回起こることがあります。このエラーについて私はドライバの問題である答えを見つけました。おそらくこれはマルチスレッドドライバのバグかもしれません。 –

+0

JSON構造体をリレーショナルな方法でマッピングするJSON_TABLE構造体のように思えます。これに対する回避策を行い、JSON_VALUEおよびJSON_QUERY関数を使用して特定の値を選択します。これらの関数は同時に使用しても問題は発生しません。しかし、とにかくあなたの貢献に感謝します。 – Evoltafreak

関連する問題