簡體   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