简体   繁体   中英

UPDATEXML throws SQL Error: ORA-00927: missing equal sign when attempting to convert and update CLOB datatype

I worked through the example through the Oracle documentation page for the UPDATEXML function: https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions205.htm

Now, I'm trying to apply this to the data in my database. The column in my database is CLOB (used for multiple things), so I need to convert my data to the xmltype before performing xml related operations. However, my attempt is returning the following error SQL Error: ORA-00927: missing equal sign .

Is there a way to update the clob-stored xml without modifying the column data type?


Attempt

Reusing the Oracle example with datatypes of my database.
1. Creating table

CREATE TABLE xwarehouses
(  
  MSD_ID INTEGER,
  CDATA CLOB
);

2. Adding data

INSERT INTO xwarehouses VALUES 
  (1,
  ('<?xml version="1.0"?>
   <Warehouse>
    <WarehouseId>1</WarehouseId>
    <WarehouseName>Southlake, Texas</WarehouseName>
    <Building>Owned</Building>
    <Area>25000</Area>
    <Docks>2</Docks>
    <DockType>Rear load</DockType>
    <WaterAccess>true</WaterAccess>
    <RailAccess>N</RailAccess>
    <Parking>Street</Parking>
    <VClearance>10</VClearance>
   </Warehouse>'));

3. Converting CLOB to XMLTYPE to extract value from specified tag

SELECT EXTRACTVALUE(XMLTYPE(cdata),'/Warehouse/WaterAccess') as VAL from xwarehouses;

VAL | true

4. Attempt to update value using same conversion in UPDATE

update XWAREHOUSES
set XMLTYPE(cdata) = 
    updatexml(XMLTYPE(cdata),'/Warehouse/WaterAccess/text()','false')
where msd_id = 1;

**5. This returns the error: SQL Error: ORA-00927: missing equal sign

Ok, I solved this 2 different ways, both basically the same way, but one is query and one is a script.

Solution 1

load the data as xmltype, then perform xml operation, and finally convert back to clob before executing the update

update xwarehouses
set cdata =
(
  select updatexml(xmltype(cdata),'/Warehouse/WaterAccess/text()','true').getclobval() 
  from xwarehouses where msd_id = 1
)
where msd_id = 1;
commit;

Solution 2

This isn't the tidiest version, as I could probably make due with the query from solution 1 and just add some variables. This essentially does the same thing with all the conversions listed out.

DECLARE
  p_msg_id number := 1;
  p_cdata xmltype;  
  p_value varchar(50) :='false';
  p_data clob;

BEGIN
  select cdata into p_data from xwarehouses;
  p_cdata := xmltype(p_data);
  select updatexml(p_cdata,'/Warehouse/WaterAccess/text()',p_value) into p_cdata from dual;
  p_data := p_cdata.getclobval();
  update xwarehouses
  set cdata = p_data
  where msd_id = p_msg_id;
  commit;

END;

From ORACLE 11

All Oracle SQL functions for updating XML data are deprecated. Oracle recommends that you use XQuery Update instead. These are the deprecated XML updating functions:

Migration from Oracle Functions for Updating XML Data to XQuery Update

Example:

UPDATE xwarehouses SET cdata =
  xmlserialize(document XMLQuery('copy $tmp := $source  modify
            (for $i in $tmp/Warehouse/WaterAccess/text()  
             return replace value of node $i
                    with "false") 
            return $tmp'
           PASSING xmltype(cdata) as "source"  RETURNING CONTENT))
  WHERE cdata IS NOT NULL;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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