繁体   English   中英

从 Oracle DB 中提取 VBA 中的 XML

[英]Extracting XML in VBA from Oracle DB

我有一个 Oracle DB,其中包含一个名为CONTENT的 XML 列:

<?xml version="1.0"?>
<PAGE>
  <INFO>
    <ID>324374</ID>
    <PAGE>ANE_CSC</PAGE>
  </INFO>
  <CAMPS>
    <CAMP KEY_CAMP="ACCESS_CONTROL">456675</CAMP>
    <CAMP KEY_CAMP="IDEN_ANAG">1458</CAMP>...
  </CAMPS>
</PAGE>

我正在尝试在 Excel 单元格中提取IDEN_ANAG值(因此: 1458 ),但是我不知道如何在 Z6E3EC7E6A9F6007B4838FC0EEZA 中正确详细说明 XML 数据。

我已经尝试了一些东西( getStringVal(), getClob(), EXTRACT()等命令),但无法找到可行的解决方案。

这就是我目前正在尝试做的事情:

Cmd.CommandText = "select XMLTYPE('<CAMP>'||CONTENT||'</CAMP>').getStringVal() from table WHERE ID = 324374
Set rs = Cmd.Execute()

Do While Not rs.EOF
    WSP1.Cells(CellWrite, 1).Value = rs.Fields(0).Value
    
    CellWrite = CellWrite + 1
    rs.MoveNext
Loop

我知道上面的代码实际上并没有提取特定的 ID,但我非常绝望,至少从提取整个 XML 开始,然后尝试为其中的特定部分找到解决方案。

虽然我几乎可以肯定我只是在代码中犯了一个错误,但我已经根据互联网搜索尝试了几种不同的结果,使用不同的功能等,我总是遇到像Runtime error或上面的代码给出的错误我的错误是Runtime error: Character string buffer too small

任何有关如何提取特定数据的建议将不胜感激。

使用正确的 XML 解析器。 您可以使用以下查询:

SELECT iden_anag
FROM   table_name t
       CROSS APPLY XMLTABLE(
         '/PAGE/CAMPS'
         PASSING XMLTYPE( t.content )
         COLUMNS
           iden_anag NUMBER PATH './CAMP[@KEY_CAMP="IDEN_ANAG"]'
       )
WHERE  id = 324374

或者

SELECT XMLQUERY(
         '/PAGE/CAMPS/CAMP[@KEY_CAMP="IDEN_ANAG"]/text()'
         PASSING XMLTYPE( content )
         RETURNING CONTENT
       ) AS iden_anag
FROM   table_name
WHERE  id = 324374

其中,对于您的示例数据:

CREATE TABLE table_name ( id NUMBER, content CLOB );

INSERT INTO table_name ( id, content ) VALUES (
  324374,
'<?xml version="1.0"?>
<PAGE>
  <INFO>
    <ID>324374</ID>
    <PAGE>ANE_CSC</PAGE>
  </INFO>
  <CAMPS>
    <CAMP KEY_CAMP="ACCESS_CONTROL">456675</CAMP>
    <CAMP KEY_CAMP="IDEN_ANAG">1458</CAMP>...
  </CAMPS>
</PAGE>'
);

output:

  |  IDEN_ANAG |  |  --------: |  | 第1458章

db<> 在这里摆弄

这是一个 Oracle 错误,当您尝试将一些大字符串放入VARCHAR数据类型时出现。

您可以查看此文档文章,“使用 XMLType 方法选择 XML 数据”部分:

您可以使用 PL/SQL、C 或 Java 来 select XMLType 数据。 您还可以使用 XMLType 方法getClobVal()getStringVal()getNumberVal()getBlobVal(csid)将 XML 数据分别检索为CLOBVARCHARNUMBERBLOB值。

因此,看起来您的数据太大而无法放入getStringVal()返回的VARCHAR中,您需要使用getClobVal()

此外,无需通过串联创建 XML 数据,因为它无法处理所有序列化细节(如 XML 中使用的符号应转换),并且您也可能面临串联时VARCHAR长度的相同限制。 为此,您需要XMLElement function:

 select xmlelement("Current_date", sysdate) as date_xml, xmlelement("SpecialSymbols", 'Symbols > and < need conversion') as spec_symbols_xml from dual
  DATE_XML |  SPEC_SYMBOLS_XML:-------------------------- |:-------- -------------------------------------------------- ----------- <Current_date>2021-03-05</Current_date> |  <特殊符号>符号 &gt; 和 &lt; 需要转换</SpecialSymbols>

db<> 在这里摆弄

您可以检查一堆XML 操作函数来构建 XML,因此请使用它们而不是字符串操作。 例如,查询结果为 XML:

 select dbms_xmlgen.getxml('select object_name, object_type from all_objects where rownum < 3') as result_clob from dual
  | 结果_CLOB |  |:------------------------------------------------ -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- |  |  <?xml version="1.0"?><br><ROWSET><br> <ROW><br> <OBJECT_NAME>ORA$BASE</OBJECT_NAME><br> <OBJECT_TYPE>版本</OBJECT_TYPE><br> < /ROW><br> <ROW><br> <OBJECT_NAME>DUAL</OBJECT_NAME><br> <OBJECT_TYPE>TABLE</OBJECT_TYPE><br> </ROW><br></ROWSET><br> |

db<> 在这里摆弄

但最好在数据库中执行所有 MXL 操作并将纯结果检索到 VBA。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM