[英]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.