Updating CLOB XML through updatexml - sql

I have one tag in my table having clobe xml data like as below:
I need to update this value to 400. I am doing it as below. But its not updating. Please help.
UPDATE XYZ
SET request_xml = UPDATEXML(xmltype(request_xml),
'Parameters/Parameter[#Name="ABC"]/#Value', 400,'xmlns:n0="http://www.iQWE.com/LKJ"').getClobVal()
where transaction_id = '2017051907471800000000187725';

Your XPath doesn't make much sense. You are looking for a node called Parameter with an attribute called Name, where that attribute value is 'MaxLatenessAllowed'. There is nothing like that in your XMl document.
You can supply the full path to the node you want to change, including namespace info:
UPDATE dfxha_catchup_queue
SET request_xml = UPDATEXML(xmltype(request_xml),
'/n0:CreateOrder/n0:SalesOrders/n0:SalesOrder/n0:SalesOrderLines/n0:SalesOrderLine/n0:MaxLatenessAllowed/#Value',
400,
'xmlns:n0="http://www.i2.com/DFX"').getClobVal()
where transaction_id = '2017051907471800000000187725';
Or to shorten that you can look for that node name anywhere, if that's safe in your schema:
UPDATE dfxha_catchup_queue
SET request_xml = UPDATEXML(xmltype(request_xml),
'//n0:MaxLatenessAllowed/#Value',
400,
'xmlns:n0="http://www.i2.com/DFX"').getClobVal()
where transaction_id = '2017051907471800000000187725';
The updateXML() function is deprecated, so you might want to investigate other ways of achieving this.

Related

Find XML tag which is present several times

I am working with an Oracle database 19c.
I have a table with the blob field "MSG_BODY". This field contains XML's like that:
<Body xmlns = "http://www.finnova.ch/ZV/EHF/021">
<Auftrag>
<Auftragsinformation>
<Auftragsidentifikation>
<AUF_LNR>987987987987</AUF_LNR>
<APPL_ID>9999</APPL_ID>
</Auftragsidentifikation>
<Auftragsreferenz>
<EXT_REF>TEST-2020082109574181</EXT_REF>
<EXT_AUF_REF>BA18081508D86B28</EXT_AUF_REF>
<KD_LNR_ERF>901</KD_LNR_ERF>
</Auftragsreferenz>
</Auftragsinformation>
<Zahlungsliste>
<Zahlung>
<Identifikation>
<ZV_ZLG_SYS_LNR>987987987987</ZV_ZLG_SYS_LNR>
<ZV_ZLG_LNR>1</ZV_ZLG_LNR>
</Identifikation>
<Referenz>
<EXT_REF>ABCD654654654</EXT_REF>
<EXT_REF_AUF>XX-XXX 230/99999/1</EXT_REF_AUF>
<EXT_REF_AUF_IB>BA9999988888</EXT_REF_AUF_IB>
<ZLG_INSTR_ID>BA999988886666</ZLG_INSTR_ID>
<MeldungsRef>
<MSG_TX_ID>123123123123</MSG_TX_ID>
<CS_ZLG_TRACK_ID>d8047b9f-a8c7-4d74-b5c7-470510240b60</CS_ZLG_TRACK_ID>
<CS_SWIFTGPI_SVC_ID>001</CS_SWIFTGPI_SVC_ID>
</MeldungsRef>
<MeldungsRef>
<MSG_TX_ID_DECK>xxxxxxxxxx</MSG_TX_ID_DECK>
</MeldungsRef>
</Referenz>
<Mitteilung>
<MIT_BEGxxx</MIT_BEG>
<MIT_BEG_XML>
<Ustrd>xxx</Ustrd>
</MIT_BEG_XML>
<PURP_CD>SALA</PURP_CD>
</Mitteilung>
</Zahlung>
</Zahlungsliste>
</Auftrag>
The tag "Zahlung" can exist multiple times and that's OK, but into the the tag "Zahlung" is the
tag "MeldungsRef". This tag should exist zero or one time for every tag "Zahlung". That's a fault shown in the XML above. I now need a query to select all rows in the table, which contains an XML, where the tag "MeldungsRef" is multiple times there. How can I do that?
Thanks for helping me!
Regards,
mablaser
You're looking for a second appearance of the MeldungsRef node within a Zahlung node, so you can look directly for that. This query shows you the first and second instances of the node, using xmlquery() and specifying the appearance to find with [1] or [2]:
select id,
xmlquery(
'declare default element namespace "http://www.finnova.ch/ZV/EHF/021"; (: :)
/Body/Auftrag/Zahlungsliste/Zahlung/Referenz/MeldungsRef[1]'
passing xmltype(msg_body)
returning content
) as first,
xmlquery(
'declare default element namespace "http://www.finnova.ch/ZV/EHF/021"; (: :)
/Body/Auftrag/Zahlungsliste/Zahlung/Referenz/MeldungsRef[2]'
passing xmltype(msg_body)
returning content
) as second
from your_table;
You could look for the second being not-null, but it's easier to use the same XPath with xmlexists() to test whether a second child node exists:
select id
from your_table
where xmlexists(
'declare default element namespace "http://www.finnova.ch/ZV/EHF/021"; (: :)
/Body/Auftrag/Zahlungsliste/Zahlung/Referenz/MeldungsRef[2]'
passing xmltype(msg_body)
);
db<>fiddle with one good (single node) and one bad (multiple node) row.
i receive the following error: ORA-32512: type 'xquery external variable'
As your base column is a BLOB you need to tell it which character set it's it, e.g.:
passing xmltype(msg_body, nls_charset_id('UTF8'))
db<>fiddle.

Xquery transformation on text data in response

I want to get a xquery transformation drafted for below data.. here as part of service response fault, I am getting below payload and need to capture the data in ErrorCode element.
challenge that I am having here is, this is not part of a XML structure, its coming as part of CDATA tags.
Could you please suggest how I can get this value in a variable same.
Say I am getting this structure as part of $Fault and now need to assign ErrorCode in a new variable $FaultCode
$FaultCode = $Fault/con:details/con1:ErrorResponseDetail/con1:detail/ ********
I am not sure how I can capture this further detail element
<con:fault xmlns:con="http://www.bea.com/wli/sb/context">
<con:errorCode>382502</con:errorCode>
<con:reason>eceived an error response</con:reason>
<con:details>
<con1:ErrorResponseDetail xmlns:con1="http://www.bea.com/wli/sb/stages/transform/config">
<con1:detail>
<![CDATA[<Error xmlns="http://servic.abcd.net/V1">
<ErrorCode>DATA_AVAILABILITY</ErrorCode>
<ErrorDescription>{"description":"No Cdata for )"}</ErrorDescription>
</Error>]]></con1:detail>
<con1:http-response-code>404</con1:http-response-code>
</con1:ErrorResponseDetail>
</con:details>
<con:location>
<con:node>TestPPNode</con:node>
<con:pipeline>TestPPNode_request</con:pipeline>
<con:stage>Test Stage</con:stage>
<con:path>request-pipeline</con:path>
</con:location>
</con:fault>
Assuming XQuery 3.1 with the parse-xml function (https://www.w3.org/TR/xpath-functions/#func-parse-xml) you can use
declare namespace con="http://www.bea.com/wli/sb/context";
declare namespace con1="http://www.bea.com/wli/sb/stages/transform/config";
declare namespace V1 = "http://servic.abcd.net/V1";
/con:fault/con:details/con1:ErrorResponseDetail/con1:detail!parse-xml(.)/V1:Error/V1:ErrorCode/data()
to get the string value DATA_AVAILABILITY, see https://xqueryfiddle.liberty-development.net/6qM2e27 for demo.
With XQuery 1 there is not XML parsing which is needed to solve this properly but you can of course try to use string functions to extract the data e.g.
/con:fault/con:details/con1:ErrorResponseDetail/con1:detail/substring-before(substring-after(., '<ErrorCode>'), '</ErrorCode>')

SQL Server: Find records where XML is missing tag

I have table named: XMLIndex that contains a column named: XMLRec that holds the structure of an XML file and values.
Some of these records are missing a tag named: <ISO></ISO>
My question is: what type of query do I need to run in order to find all the records in the table XMLIndex, that are missing the <ISO> tag?
This is an example XMLRecord XML that contains the ISO tag:
<XMLRecord>
<pn>0042761</pn>
<SRI>4.40</SRI>
<igm>/images/images/0042761.gif</img>
<ISO>ZW</ISO>
<ListPrice>$5.50</ListPrice>
</XMLRecord>
and one with multiple ISOs (look at the tag small difference):
<XMLRecord>
<pn>0042762</pn>
<SRI>4.40</SRI>
<igm>/images/images/0042762.gif</img>
<ISOs>ZW+NZ+AU+BR</ISOs>
<ListPrice>$5.50</ListPrice>
</XMLRecord>
One record missing the ISO tag is one that the XML structure would not contain such tag.
Any examples are much appreciated.
Thank you.
You can use the XQuery exist method.
Check anywhere in the xml document:
select *
from XMLIndex
where XMLRec.exist('//ISO') = 0
Check a specific location:
where XMLRec.exist('/XMLRecord/ISO') = 0

UPDATE datatype image in SQL-Table

I've a table cSc_Role with a column RoleSettings.
RoleSettings is datatype image.
The Content is something like this: 0x504B030414000000080000000000E637CA2A4
Now I need to update this column for one row.
Like this:
UPDATE cSc_Role
SET RoleSettings = '0x343240000000000E637CA2A430500'
WHERE Naming = 'User X'
But with binary data it seems like this is not possible to do it with a string.
The other option is, I can provide the image in a temporary .bak file.
And then do an INSERT INTO.
But with this solution I've read it is only possible to insert a complete row and not only a column. Or can I insert only a column with insert?
How can I update or insert one image-column in a table?
Thanks in advance.
Try to use convert to varbinary:
UPDATE cSc_Role
SET RoleSettings = convert(VARBINARY(MAX),'0x343240000000000E637CA2A430500')
WHERE Naming = 'User X'
If above all solution did not work then try to update like below by removing '' in following ,
UPDATE cSc_Role
SET RoleSettings = 0x343240000000000E637CA2A430500
WHERE Naming = 'User X'
Also, avoid using these data types (ntext, text, and image) in new development work, and plan to modify applications that currently use them. Use nvarchar(max), varchar(max), and varbinary(max) instead.
Use a hex-literal, x'34....'
UPDATE cSc_Role
SET RoleSettings = x'343240000000000E637CA2A430500'
WHERE Naming = 'User X'
I had a same problem on project, you need to provide binary data as hex value, not string. This tool can make you UPDATE or INSERT that you need
Binary-file-to-sql-hexstring
It has saved me a lot of man hours.

how to call a scalar UDF?

i have created the udf to strip HTML from sql fields from here:
link text
i am trying to run an update on my table where the defects_from_oracle.Description field has html
my sql is:
update defects_from_oracle
set Description = udf_StripHTML(Description)
where did i go wrong?
i get error:
'udf_StripHTML' is not a recognized
built-in function name.
you missed the dbo. prefex
update defects_from_oracle
set Description = dbo.udf_StripHTML(Description)