Select 并使用 XMLQUERY 更新 Oracle BLOB 列
Select and Update Oracle BLOB column with XMLQUERY
我必须更新存储在 Oracle 11G 的 BLOB 列中的 XML 值。 BLOB 存储了一个完整的 XML 文件,我必须在其中更新一些值并将其另存为 BLOB。我如何通过 blob 转换和 XMLQUERY AND XMLUPDATE 轻松 SELECT 和更新数据?任何代码示例?
提前致谢。
以下是更多详细信息:
这里是 table:
的 ddl
CREATE TABLE MAPSHEET
(
MAPSHEETID NUMBER (14,0) NOT NULL,
NAME VARCHAR2 (64) NOT NULL,
STRUCTURE BLOB,
)
blob col STRUCTURE 中的 xml 数据
<MapSheet Version="1.0">
<Frame>
<JobId>9022165</JobId>
<LayoutId>24807064</LayoutId>
<Blocks>
<Block MapFieldMask="true" CompressText="false" CombineRaster="false">
<Name>layout</Name>
<StyleId>24808857</StyleId>
<LayoutLayers>0 1</LayoutLayers>
<BlockScale/>
<JobItemIds/>
</Block>
<Block MapFieldMask="true" CompressText="false" CombineRaster="false">
<Name>karto</Name>
<StyleId>24809031</StyleId>
<LayoutLayers>4</LayoutLayers>
<BlockScale/>
<JobItemIds>
<JobItemId>9083675</JobItemId>
<JobItemId>9088148</JobItemId>
</JobItemIds>
</Block>
<Block MapFieldMask="true" CompressText="false" CombineRaster="false">
<Name>hel</Name>
<StyleId>24809032</StyleId>
<LayoutLayers>-</LayoutLayers>
<BlockScale/>
<JobItemIds>
<JobItemId>9022173</JobItemId>
<JobItemId>25403646</JobItemId>
</JobItemIds>
</Block><Block MapFieldMask="true" CompressText="false" CombineRaster="false">
<Name>shade glacier</Name>
<StyleId>24809041</StyleId>
<LayoutLayers>-</LayoutLayers>
<BlockScale/>
<JobItemIds>
<JobItemId>24806040</JobItemId>
</JobItemIds>
</Block>
<Block MapFieldMask="true" CompressText="false" CombineRaster="false">
<Name>shade</Name>
<StyleId>24809040</StyleId>
<LayoutLayers>-</LayoutLayers>
<BlockScale/>
<JobItemIds>
<JobItemId>24806038</JobItemId>
</JobItemIds>
</Block>
</Blocks>
<Offset X="0" Y="0"/>
<Name>DS</Name>
</Frame></MapSheet>
这个简单的SELECT获取数据行不通:
SELECT x.MapSheet
FROM XmlTable('/MapSheet') PASSING XmlType(MAPSHEET.STRUCTURE,1)
COLUMS "XML" VARCHAR2(300) PATH 'MapSheet') AS x;
如何从 blob 列中 select/update 获得所需的 xml 数据?
要从 XML 中选择,您可以使用 ExtractValue(XmlType, XPath)
或 XmlTable
将 Xml clob 转换为 [=54= 的可查询 table ].对于 BLOB 转换,您应该能够用 XmlType(blob_value, 1)
包装它,然后您可以在其上执行任何 XML 相关功能。
SELECT ExtractValue(
XmlType('<test><node1>value1</node1><node2>value2</node2></test>'),
'/test/node1') as Node1
FROM dual;
或使用XmlTable
SELECT xt.Node1, xt.Node2
FROM XmlTable('/test/block'
PASSING XmlType('<test>
<block><node1>value1a</node1><node2>value2a</node2></block>
<block><node1>value1b</node1><node2>value2b</node2></block>
<block><node1>value1c</node1><node2>value2c</node2></block>
</test>')
COLUMNS
"Node1" VARCHAR2(20) PATH 'node1',
"Node2" VARCHAR2(20) PATH 'node2') AS xt;
使用更新Xml,假设我正在更新的记录在一列中有上述XML:
UPDATE MyTable SET xml_data =
UpdateXml(xml_data, '/test/block/node2[text() = "value2b"]/text()', 'value2z')
WHERE data_id = 1;
上面应该将 node2
的值 value2b
更新为 value2z
。然后 returns 新的 XML 并将其分配给匹配 data_id = 1
.
的记录中的列 xml_data
请注意,在上面的查询中,它正在处理一个已经属于 XmlType 类型的列。您正在使用 BLOB
。我会问,它是 BLOB
而不是 CLOB
或 XmlType
是有原因的吗?如果你正在存储 VARCHAR
类型的数据,你真的应该使用后两种类型之一,如果你正在存储各种 VARCHAR
数据, CLOB
和 XmlType
(这是一个更具体的 CLOB
类型)如果你严格存储 XML 数据。
如果您无法使用 BLOB
数据类型,您将需要执行大量转换。使用 XmlType(blob_data, 1)
应该可以让你从 BLOB
到 XmlType
,但返回你可能需要使用 UTL_RAW.CAST_TO_RAW(xml_data)
。所以查询将变为:
UPDATE MyTable SET clob_data =
UTL_RAW.CAST_TO_RAW(
UpdateXml(XmlType(clob_data, 1), '/test/block/node2[text() = "value2b"]/text()', 'value2z').GetClobVal()
)
WHERE data_id = 1;
这是一个独立的工作示例,展示了上述各种方法:
DECLARE varchar_data VARCHAR2(500);
blob_data BLOB;
xml_data XMLType;
node1Val VARCHAR(20);
node2Val VARCHAR(20);
BEGIN
select '<test>
<group><node1>value1a</node1><node2>value2a</node2></group>
<group><node1>value1b</node1><node2>value2b</node2></group>
<group><node1>value1c</node1><node2>value2c</node2></group>
<group><node1>value1d</node1><node2>value2d</node2></group>
</test>' into varchar_data from dual;
select UTL_RAW.CAST_TO_RAW(varchar_data) into blob_data from dual;
select XmlType(blob_data, 1) into xml_data from dual;
dbms_output.put_line(xml_data.getClobVal());
select xt.Node1, xt.Node2
into node1Val, node2Val
from XmlTable('/test/group'
passing XmlType(blob_data, 1)
columns Node1 VARCHAR2(20) path 'node1',
Node2 VARCHAR2(20) path 'node2'
) xt
where xt.Node1 = 'value1c';
dbms_output.put_line('node1Val = ''' || node1Val || ''', node2Val = ''' || node2Val || ''';');
-- Using UpdateXml to update the XML, that will return an XmlType
-- so we call GetClobVal() to let CAST_TO_RAW convert to BLOB.
select UTL_RAW.CAST_TO_RAW(
UpdateXml(
XmlType(blob_data, 1),
'/test/group/node2[../node1/text() = "value1c"]/text()',
'zzzz').GetClobVal()
) into blob_data
from dual;
select XmlType(blob_data, 1) into xml_data from dual;
dbms_output.put_line(xml_data.getClobVal());
select xt.Node1, xt.Node2
into node1Val, node2Val
from XmlTable('/test/group'
passing XmlType(blob_data, 1)
columns Node1 VARCHAR2(20) path 'node1',
Node2 VARCHAR2(20) path 'node2'
) xt
where xt.Node1 = 'value1c';
dbms_output.put_line('node1Val = ''' || node1Val || ''', node2Val = ''' || node2Val || ''';');
END;
create table testxmlBlob (p blob);
将一些 xml 文档插入 table。
insert into testxmlBlob values( utl_raw.cast_to_raw('<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer''s Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
<description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</description>
</book></catalog>')) ;
视图已插入 xml。 xmltype(blob,csid -charset enocoding id '0' is default)
select xmlserialize(document xmltype(p,0)) from testxmlBlob;
使用xml查询将<description>
更改为<descriptionNew>
。
它也可以用于更新语句 update testxmlBlob set p = XMLQuery(....) ...
select XMLQuery('copy $i := $p1
modify
(
for $j in $i/catalog/book/description
let $newn := <descriptionNew>newDescription</descriptionNew>
return replace node $j with $newn)
return $i
' PASSING xmltype(p,0) AS "p1"
RETURNING CONTENT) readable
,xmlserialize(document XMLQuery('copy $i := $p1
modify
(
for $j in $i/catalog/book/description
let $newn := <descriptionNew>newDescription</descriptionNew>
return replace node $j with $newn)
return $i
' PASSING xmltype(p,0) AS "p1"
RETURNING CONTENT) as BLOB) blob_value
from testxmlBlob;
我必须更新存储在 Oracle 11G 的 BLOB 列中的 XML 值。 BLOB 存储了一个完整的 XML 文件,我必须在其中更新一些值并将其另存为 BLOB。我如何通过 blob 转换和 XMLQUERY AND XMLUPDATE 轻松 SELECT 和更新数据?任何代码示例?
提前致谢。
以下是更多详细信息:
这里是 table:
的 ddlCREATE TABLE MAPSHEET
(
MAPSHEETID NUMBER (14,0) NOT NULL,
NAME VARCHAR2 (64) NOT NULL,
STRUCTURE BLOB,
)
blob col STRUCTURE 中的 xml 数据
<MapSheet Version="1.0">
<Frame>
<JobId>9022165</JobId>
<LayoutId>24807064</LayoutId>
<Blocks>
<Block MapFieldMask="true" CompressText="false" CombineRaster="false">
<Name>layout</Name>
<StyleId>24808857</StyleId>
<LayoutLayers>0 1</LayoutLayers>
<BlockScale/>
<JobItemIds/>
</Block>
<Block MapFieldMask="true" CompressText="false" CombineRaster="false">
<Name>karto</Name>
<StyleId>24809031</StyleId>
<LayoutLayers>4</LayoutLayers>
<BlockScale/>
<JobItemIds>
<JobItemId>9083675</JobItemId>
<JobItemId>9088148</JobItemId>
</JobItemIds>
</Block>
<Block MapFieldMask="true" CompressText="false" CombineRaster="false">
<Name>hel</Name>
<StyleId>24809032</StyleId>
<LayoutLayers>-</LayoutLayers>
<BlockScale/>
<JobItemIds>
<JobItemId>9022173</JobItemId>
<JobItemId>25403646</JobItemId>
</JobItemIds>
</Block><Block MapFieldMask="true" CompressText="false" CombineRaster="false">
<Name>shade glacier</Name>
<StyleId>24809041</StyleId>
<LayoutLayers>-</LayoutLayers>
<BlockScale/>
<JobItemIds>
<JobItemId>24806040</JobItemId>
</JobItemIds>
</Block>
<Block MapFieldMask="true" CompressText="false" CombineRaster="false">
<Name>shade</Name>
<StyleId>24809040</StyleId>
<LayoutLayers>-</LayoutLayers>
<BlockScale/>
<JobItemIds>
<JobItemId>24806038</JobItemId>
</JobItemIds>
</Block>
</Blocks>
<Offset X="0" Y="0"/>
<Name>DS</Name>
</Frame></MapSheet>
这个简单的SELECT获取数据行不通:
SELECT x.MapSheet
FROM XmlTable('/MapSheet') PASSING XmlType(MAPSHEET.STRUCTURE,1)
COLUMS "XML" VARCHAR2(300) PATH 'MapSheet') AS x;
如何从 blob 列中 select/update 获得所需的 xml 数据?
要从 XML 中选择,您可以使用 ExtractValue(XmlType, XPath)
或 XmlTable
将 Xml clob 转换为 [=54= 的可查询 table ].对于 BLOB 转换,您应该能够用 XmlType(blob_value, 1)
包装它,然后您可以在其上执行任何 XML 相关功能。
SELECT ExtractValue(
XmlType('<test><node1>value1</node1><node2>value2</node2></test>'),
'/test/node1') as Node1
FROM dual;
或使用XmlTable
SELECT xt.Node1, xt.Node2
FROM XmlTable('/test/block'
PASSING XmlType('<test>
<block><node1>value1a</node1><node2>value2a</node2></block>
<block><node1>value1b</node1><node2>value2b</node2></block>
<block><node1>value1c</node1><node2>value2c</node2></block>
</test>')
COLUMNS
"Node1" VARCHAR2(20) PATH 'node1',
"Node2" VARCHAR2(20) PATH 'node2') AS xt;
使用更新Xml,假设我正在更新的记录在一列中有上述XML:
UPDATE MyTable SET xml_data =
UpdateXml(xml_data, '/test/block/node2[text() = "value2b"]/text()', 'value2z')
WHERE data_id = 1;
上面应该将 node2
的值 value2b
更新为 value2z
。然后 returns 新的 XML 并将其分配给匹配 data_id = 1
.
xml_data
请注意,在上面的查询中,它正在处理一个已经属于 XmlType 类型的列。您正在使用 BLOB
。我会问,它是 BLOB
而不是 CLOB
或 XmlType
是有原因的吗?如果你正在存储 VARCHAR
类型的数据,你真的应该使用后两种类型之一,如果你正在存储各种 VARCHAR
数据, CLOB
和 XmlType
(这是一个更具体的 CLOB
类型)如果你严格存储 XML 数据。
如果您无法使用 BLOB
数据类型,您将需要执行大量转换。使用 XmlType(blob_data, 1)
应该可以让你从 BLOB
到 XmlType
,但返回你可能需要使用 UTL_RAW.CAST_TO_RAW(xml_data)
。所以查询将变为:
UPDATE MyTable SET clob_data =
UTL_RAW.CAST_TO_RAW(
UpdateXml(XmlType(clob_data, 1), '/test/block/node2[text() = "value2b"]/text()', 'value2z').GetClobVal()
)
WHERE data_id = 1;
这是一个独立的工作示例,展示了上述各种方法:
DECLARE varchar_data VARCHAR2(500);
blob_data BLOB;
xml_data XMLType;
node1Val VARCHAR(20);
node2Val VARCHAR(20);
BEGIN
select '<test>
<group><node1>value1a</node1><node2>value2a</node2></group>
<group><node1>value1b</node1><node2>value2b</node2></group>
<group><node1>value1c</node1><node2>value2c</node2></group>
<group><node1>value1d</node1><node2>value2d</node2></group>
</test>' into varchar_data from dual;
select UTL_RAW.CAST_TO_RAW(varchar_data) into blob_data from dual;
select XmlType(blob_data, 1) into xml_data from dual;
dbms_output.put_line(xml_data.getClobVal());
select xt.Node1, xt.Node2
into node1Val, node2Val
from XmlTable('/test/group'
passing XmlType(blob_data, 1)
columns Node1 VARCHAR2(20) path 'node1',
Node2 VARCHAR2(20) path 'node2'
) xt
where xt.Node1 = 'value1c';
dbms_output.put_line('node1Val = ''' || node1Val || ''', node2Val = ''' || node2Val || ''';');
-- Using UpdateXml to update the XML, that will return an XmlType
-- so we call GetClobVal() to let CAST_TO_RAW convert to BLOB.
select UTL_RAW.CAST_TO_RAW(
UpdateXml(
XmlType(blob_data, 1),
'/test/group/node2[../node1/text() = "value1c"]/text()',
'zzzz').GetClobVal()
) into blob_data
from dual;
select XmlType(blob_data, 1) into xml_data from dual;
dbms_output.put_line(xml_data.getClobVal());
select xt.Node1, xt.Node2
into node1Val, node2Val
from XmlTable('/test/group'
passing XmlType(blob_data, 1)
columns Node1 VARCHAR2(20) path 'node1',
Node2 VARCHAR2(20) path 'node2'
) xt
where xt.Node1 = 'value1c';
dbms_output.put_line('node1Val = ''' || node1Val || ''', node2Val = ''' || node2Val || ''';');
END;
create table testxmlBlob (p blob);
将一些 xml 文档插入 table。
insert into testxmlBlob values( utl_raw.cast_to_raw('<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer''s Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
<description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</description>
</book></catalog>')) ;
视图已插入 xml。 xmltype(blob,csid -charset enocoding id '0' is default)
select xmlserialize(document xmltype(p,0)) from testxmlBlob;
使用xml查询将<description>
更改为<descriptionNew>
。
它也可以用于更新语句 update testxmlBlob set p = XMLQuery(....) ...
select XMLQuery('copy $i := $p1
modify
(
for $j in $i/catalog/book/description
let $newn := <descriptionNew>newDescription</descriptionNew>
return replace node $j with $newn)
return $i
' PASSING xmltype(p,0) AS "p1"
RETURNING CONTENT) readable
,xmlserialize(document XMLQuery('copy $i := $p1
modify
(
for $j in $i/catalog/book/description
let $newn := <descriptionNew>newDescription</descriptionNew>
return replace node $j with $newn)
return $i
' PASSING xmltype(p,0) AS "p1"
RETURNING CONTENT) as BLOB) blob_value
from testxmlBlob;