2016-11-15 77 views
2

我試圖通過XML循環並提取UUID。我有以下幾點,它循環正確的次數並每次打印一個空行。爲什麼不提取UUID節點的文本值?嘗試通過XML循環以提取PLSQL中的值

DECLARE 
     X XMLTYPE := XMLTYPE('<?xml version="1.0" ?> 
     <StatusUp> 
      <G_UUIDs> 
       <UUID>1 test 1</UUID> 
       <UUID>2 test 2</UUID> 
       <UUID>3 test 3 </UUID> 
       <UUID>4 test 4 </UUID> 
      </G_UUIDs> 
     </StatusUp>'); 
    BEGIN 
     FOR r IN (SELECT EXTRACTVALUE(VALUE(p), 'StatusUp/G_UUIDs/UUID/text()') AS uuid 

        FROM TABLE(XMLSEQUENCE(EXTRACT(X, '//StatusUp/G_UUIDs/UUID'))) p) 
     LOOP 
      DBMS_OUTPUT.PUT_LINE('UUID' || r.uuid); 
     END LOOP; 
    END; 

回答

1

如果你將其轉換爲SQL語句並運行它,就像這樣:

WITH sample_data AS (SELECT XMLTYPE('<?xml version="1.0" ?> 
     <StatusUp> 
      <G_UUIDs> 
       <UUID>1 test 1</UUID> 
       <UUID>2 test 2</UUID> 
       <UUID>3 test 3 </UUID> 
       <UUID>4 test 4 </UUID> 
      </G_UUIDs> 
     </StatusUp>') x FROM dual) 
SELECT p.*, 
     EXTRACTVALUE(VALUE(p), 'StatusUp/G_UUIDs/UUID/text()') AS uuid 
FROM sample_data sd, 
     TABLE(XMLSEQUENCE(EXTRACT(sd.x, '//StatusUp/G_UUIDs/UUID'))) p; 

這將是很容易發現的問題:

COLUMN_VALUE    UUID 
------------------------ ---------- 
<UUID>1 test 1</UUID> 
<UUID>2 test 2</UUID> 
<UUID>3 test 3 </UUID> 
<UUID>4 test 4 </UUID> 

即您正嘗試從僅包含節點UUID的xml中提取節點StatusUp/G_UUIDs/UUID。相反,如果你糾正你要查詢的節點,你會得到正確的結果:

DECLARE 
    X XMLTYPE := XMLTYPE('<?xml version="1.0" ?> 
    <StatusUp> 
     <G_UUIDs> 
      <UUID>1 test 1</UUID> 
      <UUID>2 test 2</UUID> 
      <UUID>3 test 3 </UUID> 
      <UUID>4 test 4 </UUID> 
     </G_UUIDs> 
    </StatusUp>'); 
BEGIN 
    FOR r IN (SELECT EXTRACTVALUE(VALUE(p), 'UUID/text()') AS uuid 
       FROM TABLE(XMLSEQUENCE(EXTRACT(X, '//StatusUp/G_UUIDs/UUID'))) p) 
    LOOP 
     DBMS_OUTPUT.PUT_LINE('UUID' || r.uuid); 
    END LOOP; 
END; 
/

UUID1 test 1 
UUID2 test 2 
UUID3 test 3 
UUID4 test 4 

然而,提取和extractValue一起被棄用 - 你應該使用XMLTABLE來代替:

DECLARE 
    X XMLTYPE := XMLTYPE('<?xml version="1.0" ?> 
    <StatusUp> 
     <G_UUIDs> 
      <UUID>1 test 1</UUID> 
      <UUID>2 test 2</UUID> 
      <UUID>3 test 3 </UUID> 
      <UUID>4 test 4 </UUID> 
     </G_UUIDs> 
    </StatusUp>'); 
BEGIN 
    FOR r IN (SELECT * 
      FROM XMLTABLE('//StatusUp/G_UUIDs/UUID' 
          PASSING x 
          COLUMNS uuid varchar2(10) PATH '.')) 
    LOOP 
     DBMS_OUTPUT.PUT_LINE('UUID' || r.uuid); 
    END LOOP; 
END; 
/

UUID1 test 1 
UUID2 test 2 
UUID3 test 3 
UUID4 test 4 

等效的查詢,你應該試着運行:

WITH sample_data AS (SELECT XMLTYPE('<?xml version="1.0" ?> 
     <StatusUp> 
      <G_UUIDs> 
       <UUID>1 test 1</UUID> 
       <UUID>2 test 2</UUID> 
       <UUID>3 test 3 </UUID> 
       <UUID>4 test 4 </UUID> 
      </G_UUIDs> 
     </StatusUp>') x FROM dual) 
SELECT * 
FROM sample_data sd, 
     XMLTABLE('//StatusUp/G_UUIDs/UUID' 
       PASSING sd.x 
       COLUMNS uuid varchar2(10) PATH '.'); 
+0

感謝我剛剛想出這個問題與extractValue一起節點錯了,正要回答我自己的問題。我不知道XMLTABLE,並會看看。 – HardLeeWorking

+0

我得到一個錯誤,當我運行xmltable建議,具體如下:錯誤第1行 ORA-19114:解析XQuery表達式時出現錯誤:java.lang.NoClassDefFoundError ORA-06512:在第12行 – HardLeeWorking

+0

您是否收到該錯誤我給你的代碼?因爲這對我來說沒有任何錯誤。如果是這樣,你在運行什麼版本的Oracle? – Boneist

0

你已經提取UUID從XML在FRO中號聲明,並在選定的,形象地說,你現在只有四排

<UUID> n test n </UUID> 

所以正確的方法來提取數據:

DECLARE 
    X XMLTYPE := XMLTYPE(
    '<?xml version="1.0" ?> 
    <StatusUp> 
     <G_UUIDs> 
     <UUID>1 test 1</UUID> 
     <UUID>2 test 2</UUID> 
     <UUID>3 test 3 </UUID> 
     <UUID>4 test 4 </UUID> 
     </G_UUIDs> 
    </StatusUp>'); 
BEGIN 
    FOR r IN (SELECT 
       EXTRACTVALUE(
       VALUE(p), 
       --'StatusUp/G_UUIDs/UUID/text()') AS uuid 
       '/UUID/text()') AS uuid 
      FROM 
       TABLE(
       XMLSEQUENCE(
        EXTRACT(
        X, 
        '//StatusUp/G_UUIDs/UUID') 
       ) 
      ) p 
      ) 
    LOOP 
    DBMS_OUTPUT.PUT_LINE(r.uuid); 
    END LOOP; 
END;