SQL Oracle如何在Blob列中提取XML标签内容

发布于 2025-02-12 04:27:48 字数 964 浏览 4 评论 0原文

有一个XML在类型Blob(In Oracle)中,我需要从该XML访问某个标签。在此之前,我可以以这种方式检索列:

SELECT TRIM(UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(my_column_blob, 1024))) as tag_name_xml
FROM my_table

返回就是这样:

在这里我留下XML内容的一部分:

我如何返回CUF或CCT标签的值/内容? 我希望有更多知识的人的帮助。

提出的解决方案非常优雅,但是就我而言,使用此XML结构访问CUF标签的内容会是什么样?

<?xml version="1.0" encoding="UTF-8"?>
<cteProc xmlns="http://www.example.com" version="3.00">
   <CTe>
      <infCte version="3.00">
         <ide>
            <cUF>15</cUF>
         </ide>
      </infCte>
   </CTe>
</cteProc>

There is an xml that is in a column of type BLOB (in oracle) and I need to access a certain tag from that xml. Until then I can retrieve the column this way:

SELECT TRIM(UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(my_column_blob, 1024))) as tag_name_xml
FROM my_table

the return is like this:
enter image description here

Here I leave part of the xml content:
enter image description here

How do I return the value/content of the cUF or cCT tag?
I would like the help of people with more knowledge, please.

the proposed solutions are very elegant, but for my case what would it be like to access with this xml structure to access the contents of the cUF tag?

<?xml version="1.0" encoding="UTF-8"?>
<cteProc xmlns="http://www.example.com" version="3.00">
   <CTe>
      <infCte version="3.00">
         <ide>
            <cUF>15</cUF>
         </ide>
      </infCte>
   </CTe>
</cteProc>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风吹雨成花 2025-02-19 04:27:48

使用xmltypexmltable

SELECT x.c
FROM   table_name t
       CROSS JOIN XMLTABLE(
         '/a/b/c'
         PASSING XMLTYPE(t.value, 1)
         COLUMNS
           c VARCHAR2(200) PATH './text()'
       ) x;

xmlquery

SELECT XMLQUERY('/a/b/c/text()' PASSING XMLTYPE(value, 1) RETURNING CONTENT) AS c
FROM   table_name

对于示例数据:

CREATE TABLE table_name (value BLOB);

INSERT INTO table_name (value)
VALUES ( UTL_RAW.CAST_TO_RAW( '<a><b><c>something</c></b></a>' ) );

两者都输出:输出:

c

db&lt;&gt; fiddle

Use XMLTYPE and XMLTABLE:

SELECT x.c
FROM   table_name t
       CROSS JOIN XMLTABLE(
         '/a/b/c'
         PASSING XMLTYPE(t.value, 1)
         COLUMNS
           c VARCHAR2(200) PATH './text()'
       ) x;

Or XMLQUERY:

SELECT XMLQUERY('/a/b/c/text()' PASSING XMLTYPE(value, 1) RETURNING CONTENT) AS c
FROM   table_name

Which, for the sample data:

CREATE TABLE table_name (value BLOB);

INSERT INTO table_name (value)
VALUES ( UTL_RAW.CAST_TO_RAW( '<a><b><c>something</c></b></a>' ) );

Both output:

C
something

db<>fiddle here

拔了角的鹿 2025-02-19 04:27:48

您可以首先将BLOB数据转换为CLOB类型,然后提取所需的标签。希望以下两个功能可以解决您的问题:

FUNCTION BLOB2CLOB(mBLOB IN BLOB) 
    RETURN CLOB IS
BEGIN
    Declare
        mCLOB   CLOB;
        mDestOffSet     INTEGER;
        mSrcOffSet      INTEGER;
        mBLOBCSID       INTEGER;
        mLangCntx       INTEGER;
        mWarn           INTEGER;
    Begin
        mDestOffSet := 1;
        mSrcOffSet := 1;
        mBLOBCSID := 0;
        mLangCntx := 0;
        mWarn := 0;
        DBMS_LOB.CreateTemporary(mCLOB, TRUE);
        DBMS_LOB.ConvertToClob(mCLOB, mBLOB, DBMS_LOB.GetLength(mBLOB), mDestOffSet, mSrcOffSet, mBLOBCSID, mLangCntx, mWarn);
        RETURN(mCLOB);
    End;
END BLOB2CLOB;
--
FUNCTION Get_SOAP_PartCLOB(mCLOB IN CLOB, mTag IN VARCHAR2) RETURN CLOB 
  IS
BEGIN
    Declare
        wrkCLOB         CLOB;
    myStart       NUMBER(10) := 0;
    myEnd         NUMBER(10) := 0;
    myLength      NUMBER(10) := 0;
    toErase       NUMBER(10) := 0;
    Begin
    DBMS_LOB.CreateTemporary(wrkCLOB, True);
    DBMS_LOB.COPY(wrkCLOB, mCLOB, DBMS_LOB.GETLENGTH(mCLOB));
    --
    myStart := DBMS_LOB.InStr(wrkCLOB, mTag, 1, 1) + Length(mTag) - 1;
    myEnd := DBMS_LOB.InStr(wrkCLOB, SubStr(mTag, 1, 1) || '/' || SubStr(mTag, 2));
    myLength := DBMS_LOB.GetLength(wrkCLOB);
    
    DBMS_LOB.ERASE(wrkCLOB, myStart, 1);
    toErase := myLength - myEnd + 1;

    DBMS_LOB.ERASE(wrkCLOB, toErase, myEnd);
    
    wrkCLOB := REPLACE(wrkCLOB, ' ', '');

        RETURN(wrkCLOB);
    End;
END Get_SOAP_PartCLOB;

您可以这样使用它:

SELECT 
    Get_SOAP_PartCLOB(BLOB2CLOB(YOUR_BLOB_COL), 'your_tag_in_clob') as "TAG_COL_ALIAS"
FROM
    YOUR_TABLE

我使用第二个功能get_soap_partclob()从某些Web服务的SOAP信封响应中获取一些很大的B64数据。这就是为什么返回类型是clob的原因。您可以将返回的值投放到其他方面,也可以对功能进行自己的调整。

You can first convert your BLOB data into CLOB type, and then extract the tags you need. Here are two functions that will, hopefully, solve your problem:

FUNCTION BLOB2CLOB(mBLOB IN BLOB) 
    RETURN CLOB IS
BEGIN
    Declare
        mCLOB   CLOB;
        mDestOffSet     INTEGER;
        mSrcOffSet      INTEGER;
        mBLOBCSID       INTEGER;
        mLangCntx       INTEGER;
        mWarn           INTEGER;
    Begin
        mDestOffSet := 1;
        mSrcOffSet := 1;
        mBLOBCSID := 0;
        mLangCntx := 0;
        mWarn := 0;
        DBMS_LOB.CreateTemporary(mCLOB, TRUE);
        DBMS_LOB.ConvertToClob(mCLOB, mBLOB, DBMS_LOB.GetLength(mBLOB), mDestOffSet, mSrcOffSet, mBLOBCSID, mLangCntx, mWarn);
        RETURN(mCLOB);
    End;
END BLOB2CLOB;
--
FUNCTION Get_SOAP_PartCLOB(mCLOB IN CLOB, mTag IN VARCHAR2) RETURN CLOB 
  IS
BEGIN
    Declare
        wrkCLOB         CLOB;
    myStart       NUMBER(10) := 0;
    myEnd         NUMBER(10) := 0;
    myLength      NUMBER(10) := 0;
    toErase       NUMBER(10) := 0;
    Begin
    DBMS_LOB.CreateTemporary(wrkCLOB, True);
    DBMS_LOB.COPY(wrkCLOB, mCLOB, DBMS_LOB.GETLENGTH(mCLOB));
    --
    myStart := DBMS_LOB.InStr(wrkCLOB, mTag, 1, 1) + Length(mTag) - 1;
    myEnd := DBMS_LOB.InStr(wrkCLOB, SubStr(mTag, 1, 1) || '/' || SubStr(mTag, 2));
    myLength := DBMS_LOB.GetLength(wrkCLOB);
    
    DBMS_LOB.ERASE(wrkCLOB, myStart, 1);
    toErase := myLength - myEnd + 1;

    DBMS_LOB.ERASE(wrkCLOB, toErase, myEnd);
    
    wrkCLOB := REPLACE(wrkCLOB, ' ', '');

        RETURN(wrkCLOB);
    End;
END Get_SOAP_PartCLOB;

You can use it like this:

SELECT 
    Get_SOAP_PartCLOB(BLOB2CLOB(YOUR_BLOB_COL), 'your_tag_in_clob') as "TAG_COL_ALIAS"
FROM
    YOUR_TABLE

I use the second function Get_SOAP_PartCLOB() to get some pretty big B64 data out of the soap envelope response from certain web services. That's why the return type is CLOB. You can cast the returned value to something else or make your own adjustments to the function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文