簡體   English   中英

嘗試將dbms_xmlgen.xmlget替換為sys_xmlagg

[英]Trying to replace dbms_xmlgen.xmlget with sys_xmlagg

我正在針對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而不是一個空的文檔。

我目前無法訪問Oracle數據庫,所以請原諒。

目標是DBMS_XMLGEN調用的參數化。 這是通過使用一些PL / SQL來完成的。 DBMS_XMLGEN軟件包的Oracle文檔描述了一些應該有用的操作。 首先,使用以下形式從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(而不是創建新的臨時對象)的好處,這可能有助於提高性能。 還有另一種形式更像您在示例中使用的形式,但是失去了此屬性。

還有一件事...在此示例中返回的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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM