1

Oracle 10gR2 に対するいくつかの JDBC クエリのパラメータ化に取り組んでいます。

ほとんどのクエリは次の形式です。

String value = "somevalue";
String query = "select dbms_xmlgen.xmlget('select c1, c2 from t1 where c1 = ''"
    + somevalue + "'' ') xml from dual;";

実際の選択はxmlget内の引用符で囲まれた文字列にあり、パラメーターは文字列内で展開されないため、そのままパラメーター化することはできません。JDBC は、そのクエリをパラメータがないものとして認識します。

私は次の動作をエミュレートすることにかなり成功していますdbms_xmlgen.xmlget

String query = "SELECT xmltype.getclobval(sys_xmlagg(xmlelement(\"ROW\","                                                                                        
    + "xmlforest(c1, c2)))) xml from t1 where c1 = ?";

私が解決できなかった唯一の問題は、クエリが行を返さない場合です。

ではdbms_xmlgen.xmlget、空の CLOB を返す行はありません。ただし、 を使用するとsys_xmlagg、次のもので構成される CLOB になる行はありません。

<?xml version="1.0"?><ROWSET></ROWSET>

空のドキュメントではなく、空の CLOB を提供するソリューションを探しています。

4

1 に答える 1

1

現在、Oracle DBにアクセスできませんので、誤りはご容赦ください。

呼び出しのパラメーター化がDBMS_XMLGEN目標のようです。これは、少しのPL/SQLを使用することで実現されます。DBMS_XMLGENパッケージのOracleDocsには、役立つはずのいくつかの操作が記述されています。まず、次の形式を使用してSYS_REFCURSORからコンテキストを作成します。

DBMS_XMLGEN.NEWCONTEXT (
  queryString  IN SYS_REFCURSOR)
RETURN ctxHandle;

次に、次の別の形式でコンテキストを使用しますGetXML

DBMS_XMLGEN.GETXML (
   ctx          IN ctxHandle, 
   tmpclob      IN OUT NCOPY CLOB,
   dtdOrSchema  IN number := NONE)
RETURN BOOLEAN;

この方法を使用すると、CLOBを再利用する可能性がある(新しい一時的なものを作成しない)という利点もあり、パフォーマンスに役立つ可能性があります。例で使用していたものに似ているが、このプロパティを失う別のフォームがあります。

もう1つ...この例のreturnはGETXML、行が返されたかどうかを示しているはずです。これは、操作の完了時にCLOBの内容をチェックするよりも信頼性が高いはずです。または、コンテキストで関数を使用してNumRowsProcessed、CLOBに含まれる行の数を取得することもできます。

大まかに言って、コードは次のようになります。

DECLARE
  srcRefCursor SYS_REFCURSOR;
  ctxHandle ctxHandle;
  somevalue VARCHAR2(1000);
  myClob CLOB;
  hasRows boolean;
BEGIN
  OPEN srcRefCursor FOR
      SELECT c1, c2 
      FROM t1 
      WHERE c1 = somevalue; --Note parameterized value

  ctxHandle := DBMS_XMLGEN.NEWCONTEXT(srcRefCursor);

  hasRows := DBMS_XMLGEN.GETXML(
      ctxHandle,
      myClob -- XML stored in myCLOB
  );

  IF (hasRows) THEN
    /* Do work on CLOB here */
  END IF;


  DBMS_XMLGEN.CLOSECONTEXT(ctxHandle);
END;
于 2012-01-27T19:11:41.450 に答える