0

バックエンドで Oracle データベースを使用するアプリケーションを継承しました。データベースはもともと Oracle のフル バージョンを使用していましたが、Oracle XE に移行しました。Oracle XE は Oracle XML SQL Utility (DBMS_XMLSave を含む) をサポートしていないようです。少なくとも、インストール方法がわかりません。

このリンクによると ( http://ellebaek.wordpress.com/2011/01/27/converting-between-oracle-data-and-xml/ ):

DBMS_XMLQUERY と同様に、DBMS_XMLSAVE は Java で実装されているため、Oracle Database Express Edition ではサポートされていません。

データベースのストアド プロシージャは DBMS_XMLSave を使用しますが、このリンク ( https://forums.oracle.com/forums/thread.jspa?threadID=530048 ) から、DBMS_XMLSave が DBMS_XMLStore に置き換えられたように見えます。

DBMS_XMLSTORE PL/SQL パッケージは、Oracle Database 10g リリース 1 で導入されました。このパッケージは、XML ドキュメントの内容に基づいて、データベース内のリレーショナル テーブルまたはオブジェクト テーブルに対して DML 操作を実行します。

Oracle Database 10g より前は、この機能は DBMS_XMLSAVE という別の PL/SQL パッケージに存在していたことに注意してください。

リンクで解決策を試しました:

CREATE OR REPLACE PUBLIC SYNONYM DBMS_XMLSAVE FOR DBMS_XMLSTORE;
GRANT EXECUTE ON DBMS_XMLSAVE TO PUBLIC;

これにより、エラーの大部分が修正されましたが、いくつかの問題行が残っていました。

DBMS_XMLSave.setDateFormat(v_insCtx, 'MM/dd/yyyy');
DBMS_XMLSave.setBatchSize(v_updCtx, -1);
DBMS_XMLSave.setDateFormat(v_updCtx, 'MM/dd/yyyy');

DBMS_XMLStore はこれらのメソッドをサポートしていないようです。掘り下げてみると、setDateFormat を回避する方法を見つけたと思います。このリンク ( http://ellebaek.wordpress.com/2011/01/27/converting-between-oracle-data-and-xml/ ) によると、DBMS_XMLStore は日付/時刻の値に NLS 設定を使用します。このリンク ( http://www.tiplib.com/231/nls-parameter-session-logon-trigger ) は、次のようなストアド プロシージャで NLS 設定を変更できることを指摘しています。

BEGIN
    DBMS_SESSION.SET_NLS('NLS_DATE_FORMAT','YYYYMMDD');
    COMMIT;
END;

したがって、setDateFormat の行を次のように置き換えられることを願っています。

-DBMS_XMLSave.setDateFormat(v_insCtx, 'MM/dd/yyyy');  -- remove
+DBMS_SESSION.SET_NLS('NLS_DATE_FORMAT','MM/dd/yyyy');  -- insert

setBatchSize の代わりが見つかりませんでした。

だから私の質問は:

  1. 私はこれに正しい方法で取り組んでいますか、それともより良いアプローチがありますか?

  2. DBMS_XMLSave.setDateFormat(v_insCtx, 'MM/dd/yyyy') -> DBMS_SESSION.SET_NLS('NLS_DATE_FORMAT','MM/dd/yyyy') の変更は機能しますか?

  3. setBatchSize に代わるものはありますか? setBatchSize を置き換える必要がありますか?

通常、誰かが上記の質問 2 のような質問をした場合、私はそれを試して教えてくれるように伝えますが、現在、コードをコンパイルすることができず、既知の動作ベースラインもありません。問題のある行を削除すると、おそらく何らかの結果が得られるでしょうが、結果が正しいかどうかはわかりません。問題のある行を削除して結果を確認しようとするのが、ここからの私のアプローチになります。

元のコードは次のとおりです。

    procedure insert_xml(p_xmlDoc in clob, p_tableName in varchar2) is
        v_insCtx DBMS_XMLSave.ctxType;
        v_rows number;
    begin
      v_insCtx := DBMS_XMLSave.newContext(p_tableName); -- get the context handle
      DBMS_XMLSave.setDateFormat(v_insCtx, 'MM/dd/yyyy'); -- set date format
      v_rows := DBMS_XMLSave.insertXML(v_insCtx, p_xmlDoc); -- this inserts the document
      DBMS_XMLSave.closeContext(v_insCtx); -- this closes the handle
    exception
      when OTHERS then
        raise_application_error(-20001,'An error was encountered. - '||SQLCODE||' -ERROR- '||SQLERRM);
    end insert_xml;

    procedure update_xml(p_xmlDoc in clob, p_tableName in varchar2, p_key in varchar2) is
            v_updCtx DBMS_XMLSave.ctxType;
            v_rows number;
        begin
            v_updCtx := DBMS_XMLSave.newContext(p_tableName); -- get the context
            DBMS_XMLSave.setBatchSize(v_updCtx, -1);
            DBMS_XMLSave.setDateFormat(v_updCtx, 'MM/dd/yyyy'); -- set date format
            DBMS_XMLSave.clearUpdateColumnList(v_updCtx); -- clear the update settings..
            DBMS_XMLSave.setKeyColumn(v_updCtx, p_key); -- set EMPNO as key column
            v_rows := DBMS_XMLSave.updateXML(v_updCtx, p_xmlDoc); -- update the table.
            DBMS_XMLSave.closeContext(v_updCtx); -- close the context..!
      exception
        when OTHERS then
          raise_application_error(-20001,'An error was encountered. - '||SQLCODE||' -ERROR- '||SQLERRM);
        end update_xml;

ご協力ありがとうございます。

4

1 に答える 1

0

私は質問に半分答えました。私が試したとき:

DBMS_SESSION.SET_NLS('NLS_DATE_FORMAT','MM/DD/YYYY');

これらのエラーが発生したことがわかりました:

ORA-31011: XML parsing failed
ORA-19202: Error occurred in XML processing
LPX-00222: error received from SAX callback function
ORA-01843: not a valid month

掘り下げた後、私は見つけました:

EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_DATE_FORMAT = "MM/DD/YYYY"';

これにより、日付処理が文句を言わないように見えました。問題は修正されたと思いますが、この段階では100%確信が持てません。

DBMS_XMLSave.setBatchSize(); を置き換えませんでした。これがパフォーマンスに影響するかどうかはわかりません。

パブリック シノニムを使用するのではなく、コードを直接変更したところ、現在は次のようになっています。

    procedure insert_xml(p_xmlDoc in clob, p_tableName in varchar2) is
        v_insCtx DBMS_XMLStore.ctxType;
        v_rows number;
    begin
        v_insCtx := DBMS_XMLStore.newContext(p_tableName); -- get the context handle
        EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_DATE_FORMAT = "MM/DD/YYYY"';
        v_rows := DBMS_XMLStore.insertXML(v_insCtx, p_xmlDoc); -- this inserts the document
        DBMS_XMLStore.closeContext(v_insCtx); -- this closes the handle
    exception
        when OTHERS then
          raise_application_error(-20001,'An error was encountered. - '||SQLCODE||' -ERROR- '||SQLERRM);
    end insert_xml;
    procedure update_xml(p_xmlDoc in clob, p_tableName in varchar2, p_key in varchar2) is
        v_updCtx DBMS_XMLStore.ctxType;
        v_rows number;
    begin
        v_updCtx := DBMS_XMLStore.newContext(p_tableName); -- get the context
        EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_DATE_FORMAT = "MM/DD/YYYY"';
        DBMS_XMLStore.clearUpdateColumnList(v_updCtx); -- clear the update settings..
        DBMS_XMLStore.setKeyColumn(v_updCtx, p_key); -- set EMPNO as key column
        v_rows := DBMS_XMLStore.updateXML(v_updCtx, p_xmlDoc); -- update the table.
        DBMS_XMLStore.closeContext(v_updCtx); -- close the context..!
    exception
        when OTHERS then
          raise_application_error(-20001,'An error was encountered. - '||SQLCODE||' -ERROR- '||SQLERRM);
        end update_xml;
于 2012-10-09T00:11:02.847 に答える