I am trying to move some data over a dblink and one of the columns is an XMLType column. The code looks like this:
begin
delete from some_schema.some_remote_tab@src_2_trg_dblink;
INSERT INTO some_schema.some_remote_tab@src_2_trg_dblink(id, code, gen_date, xml_data)
SELECT id, code, gen_date, xml_data
FROM local_table;
end;
Oracle returns these errors:
ORA-02055: distributed update operation failed; rollback required ORA-22804: remote operations not permitted on object tables or user-defined type columns
Some research on ORA-22804 shows that I am probably getting this error because of the XMLType column, but I am not sure how to resolve this.
(Oracle 10g)
Instead Perform a Data PULL.
(Meanwhile .. wait for oracle to find some solution to perform the PUSH of XML over dblink in the future)
Create a procedure at Remote site Database B
Call the procedure from Database A
I was facing the same issue with an heterogeneous DB link to SQL server.
Ended up using
xmltype.getStringVal()
to insert in a VARCHAR column on SQL Server side as the data was under 4000 characters.There is also
xmltype.getClobVal()
if over 4000 characters but I haven't tested it.We get ORA-22804 because every instance of a Type in our Oracle database has an OID, which is unique within the database. We cannot transfer that OID to another database; this has caused me grief before when trying to import schemas which have User-Defined Types. I hadn't realised that it also affected XMLType, but it is an Object so it is not surprising.
The solution is icky: you will have to unload the XML into text on your local database and then convert it back into XML in the remote database.
I don't have a distributed DB set-up to test this right now, but if you're lucky it may work:
If the
asClobVal()
method doesn't work you may need to use the SQL function XMLSERIALIZE() instead.If you're really unlucky you won't be able to do this in a single SQL statement, and you'll have to solve it using PL/SQL. To a certain extent this will depend on which version of the database you are using; the more recent the version, the more likely you'll be able to it in SQL rather than PL/SQL.
The "xml->text->xml" chain might be complicated, but could help in some cases (for example when inserting is not on option but updating only). You can try with "n" peaces of varchar columns (in the destination table or in a differnet one, perheaps in different schema on the remote DB), where "n" is: ceil(max(dbms_lob.getlength(MyXmlColumn)) / 4000)
Then you can transfer these fragments to remote temporary fields:
XmlType can be re-composed from fragments like this:
Finally use the result to update any other table in the remothe schema like:
Try to do this the other way around. That is log into the remote db, create a dblink to the local db, and do an insert like this