2015-12-08 100 views
1

任何人都知道我是否可以從遊標生成XMLType而無需手動指定每行的名稱?從遊標獲取XMLType

我希望能夠遍歷我的查詢,併爲每一行獲取單獨的XML。

我無法使用DBMS_XMLGEN.getXMLType獲得解決方案,但也許我沒有正確使用它。

CREATE OR REPLACE PROCEDURE "MY_SCHEMA"."TEST" AS 

CURSOR mySelectCursor is 
    SELECT '1a' as "column1", '1b' as "column2" FROM DUAL 
    UNION ALL 
    SELECT '2a' as "column1", '2b' as "column2" FROM DUAL; 

myXMLType XMLType; 
BEGIN 

FOR mySelect in mySelectCursor 
    LOOP 
     -- I would like to replace the following line of code 
     myXMLType := XMLType('<row><column1>' || mySelect."column1" || '</column1><column2>' || mySelect."column2" || '</column2></row>'); 
     -- by something similar to this (not working) one 
     --myXMLType := mySelect.getXMLType(); 
     dbms_output.put_line(myXMLType.getClobVal()); 
    END LOOP; 
END; 

--The following code outputs 
--<row><column1>1a</column1><column2>1b</column2></row> 
--<row><column1>2a</column1><column2>2b</column2></row> 

回答

0

以下是使用XMLTABLE而不是XMLSEQUENCE的解決方案。

CREATE OR REPLACE PROCEDURE "MY_SCHEMA"."TEST" AS 

CURSOR mySelectCursor IS 
    SELECT 
     VALUE(table_temp) AS "XMLTYPE" 
    FROM 
     XMLTABLE('/ROWSET/ROW' PASSING 
      DBMS_XMLGEN.GETXMLTYPE(' 
       SELECT ''1a'' as "column1", ''1b'' as "column2" FROM DUAL 
       UNION ALL 
       SELECT ''2a'' as "column1", ''2b'' as "column2" FROM DUAL 
      ') 
     ) table_temp; 
BEGIN 

FOR mySelect IN mySelectCursor 
    LOOP 
     dbms_output.put_line(mySelect."XMLTYPE".getClobVal()); 
    END LOOP; 
END; 

-- Output is : 

--<ROW><column1>1a</column1><column2>1b</column2></ROW> 
--<ROW><column1>2a</column1><column2>2b</column2></ROW> 
0

這裏是代碼片段,你需要使用DBMS_XMLGEN.getxml:

DECLARE 
    v_xml CLOB; 
    v_more BOOLEAN := TRUE; 
BEGIN 
    v_xml := DBMS_XMLGEN.getxml('select * from dual'); 
    dbms_output.put_line(v_xml); 
END; 
/

這裏是代碼片段,循環中的光標

CREATE OR REPLACE TYPE test_type AS OBJECT (
    col1 CHAR(2), 
    col2 CHAR(2) 
); 
/

create or replace view test_view 
as SELECT '1a' as column1, '1b' as column2 FROM DUAL 
    UNION ALL 
    SELECT '2a' as column1, '2b' as column2 FROM DUAL; 

DECLARE 
    CURSOR c_xml IS 
    SELECT SYS_XMLAGG(
       SYS_XMLGEN(
       test_type(column1, column2), 
       sys.xmlgenformatType.createFormat('TABLE') 
      ), 
       sys.xmlgenformatType.createFormat('TEST_VIEW') 
      ).getStringVal() AS xml_row 
    FROM test_view; 
BEGIN 
    FOR cur_rec IN c_xml LOOP 
dbms_output.put_line(cur_rec.xml_row); 
    END LOOP; 
end; 
/
+0

不要忘記我想循環查詢我的查詢,併爲每行獲取單獨的xml。 – fop6316

+0

@ fop6316 - 添加了代碼片段以循環通過光標。您需要使用sys_xmlagg和sys_xmlgen。 –

0

這是否適合查詢你需要:

WITH t AS 
    (SELECT '1a' AS c1, '1b' AS c2 FROM DUAL 
    UNION ALL 
    SELECT '2a' AS c1, '2b' AS c2 FROM DUAL) 
SELECT XMLELEMENT("row", 
      XMLELEMENT("column1", c1), 
      XMLELEMENT("column2", c2) 
     ) AS myXMLType 
FROM t; 

另一種方式w應該是這一個:

CREATE OR REPLACE TYPE "row" AS OBJECT (
"column1" VARCHAR2(100), 
"column2" VARCHAR2(100)) 
/

WITH t AS 
    (SELECT '1a' AS c1, '1b' AS c2 FROM DUAL 
    UNION ALL 
    SELECT '2a' AS c1, '2b' AS c2 FROM DUAL) 
SELECT XMLTYPE("row"(c1,c2)) AS myXMLType 
FROM t; 
1

我終於找到了解決方案。

謝謝你的幫助。

CREATE OR REPLACE PROCEDURE "MY_SCHEMA"."TEST" AS 

CURSOR mySelectCursor is 
    SELECT 
     VALUE(table_temp) as "XMLTYPE" 
    FROM 
     table(
      XMLSequence(
       Cursor(
        SELECT '1a' as "column1", '1b' as "column2" FROM DUAL 
        UNION ALL 
        SELECT '2a' as "column1", '2b' as "column2" FROM DUAL 
       ) 
      ) 
     ) table_temp; 

BEGIN 

FOR mySelect in mySelectCursor 
    LOOP 
     dbms_output.put_line('==='); 
     dbms_output.put_line(mySelect."XMLTYPE".getClobVal()); 
    END LOOP; 
END; 


-- Output is : 

--=== 
-- <ROW> 
-- <column1>1a</column1> 
-- <column2>1b</column2> 
-- </ROW> 
-- 
--=== 
-- <ROW> 
-- <column1>2a</column1> 
-- <column2>2b</column2> 
-- </ROW> 
+0

不要使用XMLSEQUENCE,它已被棄用。 –

+0

如何在此查詢上通過XMLTABLE更改XMLSequence? – fop6316

+0

如果您的要求是循環,然後看我使用SYS_XMLAGG和SYS_XMLGEN的答案 –