2011-12-22 30 views
1

我正在參數化針對Oracle 10gR2的一些JDBC查詢。嘗試用sys_xmlagg替換dbms_xmlgen.xmlget

大多數查詢的格式爲:

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而不是一個空文件。

回答

1

我目前無法訪問Oracle數據庫,因此請原諒不準確。

DBMS_XMLGEN調用的參數化似乎是目標。這是通過使用一點PL/SQL來完成的。 The Oracle Docs for the DBMS_XMLGEN package描述了一些應該有所幫助的操作。首先,使用這種形式的創建從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; 
相關問題