2016-11-15 41 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;