Oracle 10 xmltype extract where clause - sql

I'm trying to extract a given set of values from an xmlfield blob data type.
The Xml structure looks like
<?xml version="1.0" encoding="UTF-8"?>
<ItemParameters type="**XYZ" version="000000000">
<Attribute name="Item ID" elementaryType="Numeric">
<Value value="12"></Value>
</Attribute>
<Attribute name="A" elementaryType="B">
<Value value="50"></Value>
</Attribute>
</ItemParameters>
<Scales>
</Scales>
where I'd like to check if attribute name = A and elementryType = B and extract the value beneeth in this case 50.
I tried doing like
select xmltype (dynamic_data).EXTRACT ('//ItemParameters/Attribute/Value()').getVal ()
Which is not working

Related

How to replace values in xml from sql?

I have an xml in my SQL Server table like this:
<Category>
<Attributes>
<Attribute>
<Name>GeneratorOnBoard1</Name>
<Value>Yes</Value>
</Attribute>
<Attribute>
<Name>GeneratorOnBoard2</Name>
<Value>Yes</Value>
</Attribute>
</Attributes>
</Category>
I want to replace the value of GeneratorOnBoard1 from 'yes' to 'yes please'
but should not change the value of GeneratorOnBoard2.
If I use this:
declare #xml xml=''
select cast (replace (cast(#xml as nvarchar(max)), 'yes','yes please') as xml)
it might replace all the yes values.
What should I do?
Bit easy and alternative way is to use STUFF with PATINDEX as below
SELECT
STUFF(CAST(#xml AS NVARCHAR(MAX)),
PATINDEX('%Yes%', CAST(#xml AS NVARCHAR(MAX))), 3, 'Yes Please');
Have a look at using replace value of (XML DML).
declare #xml xml = '<Category>
<Attributes>
<Attribute>
<Name>GeneratorOnBoard1</Name>
<Value>Yes</Value>
</Attribute>
<Attribute>
<Name>GeneratorOnBoard2</Name>
<Value>Yes</Value>
</Attribute>
</Attributes>
</Category>';
set #xml.modify('replace value of (/Category
/Attributes
/Attribute[(Name/text())[1] = "GeneratorOnBoard1" and
(Value/text())[1] = "Yes"]
/Value/text())[1]
with "yes please"');

Export sql query results to xml data file in oracle

I have an SQL query which returns two columns with data like this:.
State Name
------- ---------
Online Terminal1
Offline Terminal2
Online Terminal3
Online Terminal4
Now I want to create an XML file with a SQL query runs. XML file structure must be like this:
<?xml version="1.0" encoding="utf-8" ?>
<Terminallist name="xml data">
<Value id="0">
<Terminal>Terminal1</Terminal>
<State>Online</State>
</Value>
<Value id="1">
<Terminal>Terminal2</Terminal>
<State>Offline</State>
</Value>
<Value id="2">
<Terminal>Terminal3</Terminal>
<State>Online</State>
</Value>
<Value id="3">
<Terminal>Terminal4</Terminal>
<State>Online</State>
</Value>
</Terminallist>
I want to save XML file to a directory like this c:/file.xml.
Answer:-
Table name: temptable
Data in table :
Query :-
SELECT XMLElement("Terminallist ", XMLAttributes('xml data' AS "name"),XMLAgg(XMLElement("value ", XMLAttributes(rownum AS "id"),XMLForest(Terminal,state))))
FROM temptable ;
output :-
<Terminallist name = "xml data">
<value id = "1">
<TERMINAL>Terminal2</TERMINAL>
<STATE>Offline</STATE>
</value>
<value id = "2">
<TERMINAL>Terminal3</TERMINAL>
<STATE>Online</STATE>
</value>
<value id = "3">
<TERMINAL>Terminal4</TERMINAL>
<STATE>Online</STATE>
</value>
</Terminallist>
Thanks
Narendar
This solution uses a WITH clause to generate the ID as you want, starting from 0. Using the analytic row_number() function provides a guaranteed sort order in the result set.
NB: XMLRoot() is deprecated as part of the XML/SQL standard but generates the version header you asked for. Find out more.
with cte as (
select row_number() over (order by name) - 1 as id
, name
, state
from terminals
)
SELECT xmlroot (
XMLElement(
"Terminallist",
XMLAttributes( 'xml data' as "name"),
XMLAgg(XMLElement("Value",
XMLAttributes(cte.id as "id"),
XMLElement("Terminal",cte.name),
XMLElement("State",cte.state)
)
)
)
, version '1.0' )
FROM cte
order by cte.id
/
Here is the output:
<?xml version="1.0"?>
<Terminallist name="xml data">
<Value id="0">
<Terminal>Terminal1</Terminal>
<State>Online</State>
</Value>
<Value id="1">
<Terminal>Terminal2</Terminal>
<State>Offline</State>
</Value>
<Value id="2">
<Terminal>Terminal3</Terminal>
<State>Online</State>
</Value>
<Value id="3">
<Terminal>Terminal4</Terminal>
<State>Online</State>
</Value>
</Terminallist>
As for writing the output to a file, that depends on how you want to call the SQL. Use SPOOL if you're running it from SQL*Plus and want to save it to a local file. If running from PL/SQL you'll need to use UTL_FILE and write to a directory on the database server.
Using the Oracle XE database as source data I'm able to export the employees table as XML as follows...
SELECT SYS_XMLAGG(
SYS_XMLGEN(
XMLFOREST(employee_id, first_name, last_name, email, phone, hire_date, manager_id, job_title)
)
) FROM employees;
The XML will look like...
<?xml version="1.0"?>
<ROWSET>
<ROW>
<EMPLOYEE_ID>107</EMPLOYEE_ID>
<FIRST_NAME>Summer</FIRST_NAME>
<LAST_NAME>Payne</LAST_NAME>
<EMAIL>summer.payne#example.com</EMAIL>
<PHONE>515.123.8181</PHONE>
<HIRE_DATE>2016-06-07</HIRE_DATE>
<MANAGER_ID>106</MANAGER_ID>
<JOB_TITLE>Public Accountant</JOB_TITLE>
</ROW>
<ROW>
<EMPLOYEE_ID>...
The CSV list of column names for XMLForest can be obtained thus...
SELECT LISTAGG(column_name, ',') FROM user_tab_columns WHERE table_name = 'EMPLOYEES';
Luck.

Extract values from XML String in oracle

How do you extract the value of an xml string in oracle e.g.
XML Example
<?xml version="1.0" encoding="UTF-8"?>
<node>
<key label="name">Test</key>
<key label="lastname">Test</key>
</node>
So far this is what I have tried to extract the values
SELECT <COLUMN>, EXTRACTVALUE(xmltype(<COLUMN>),'/node/lastname') AS TEST FROM <TABLE>;
But it always returns a null value.

How can I query a value in SQL Server TEXT column that contains XML (not xml column type)

I have table DOCUMENTS with:
DOCUMENTS
____________________
DOCUMENTID int
USERID int
CONTENT text
I have following XML stored in TEXT column with name CONTENT in a SQL Server database
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<IDMSDocument>
<DocumentContent>
<Attribute Name="Number" GUID="{FFFFFFFF-0000-0000-0000-000000000001}">
<IDMSType>3060</IDMSType>
<Value Type="Integer">
<Value>122</Value>
</Value>
</Attribute>
<Attribute Name="Date" GUID="{FFFFFFFF-0000-0000-0000-000000000002}">
<IDMSType>3061</IDMSType>
<Value Type="DateTime">
<Date>10-09-2014</Date>
</Value>
</Attribute>
<Attribute Name="Публикуване" GUID="{CA646F55-5229-4FC5-AA27-494B25023F4E}">
<IDMSType>3062</IDMSType>
<Value Type="String">
<Value>Да</Value>
</Value>
</Attribute>
<Attribute Name="Дата" GUID="{AC0465B0-4FB4-49E2-B4FA-70901068FD9B}">
<IDMSType>3063</IDMSType>
<Value Type="DateTime">
<Date>01-10-2014</Date>
</Value>
</Attribute>
<Attribute Name="Предмет на поръчка" GUID="{04A4EC72-6F33-461F-98DD-D8D271997788}">
<IDMSType>3065</IDMSType>
<Value Type="String">
<Value>Избор на консултанти</Value>
</Value>
</Attribute>
</DocumentContent>
</IDMSDocument>
I find a way how to query dingle XML attribute in a single row from table, with heavy conversion :
DECLARE #strContent NVARCHAR(MAX);
DECLARE #xmlContent XML;
SET #strContent = (select content from DOCUMENTS where DocumentID=24);
SET #xmlContent = CAST(REPLACE(CAST(#strContent AS NVARCHAR(MAX)),'utf-8','utf-16') AS XML)
SELECT #xmlContent.query('/IDMSDocument/DocumentContent/Attribute[5]/Value/Value')
where #xmlContent.value('(/IDMSDocument/DocumentContent/Attribute[5]/Value/Value)[1]', 'nvarchar(max)') like '%search%'
I need to make query like "select all rows in table that in fifth attribute in XML have value 'search' "
For me the general problem is that column type is not XML, but I have text column with stored xml inside. when I try cast, query, value directly server return that I can use it Only with XML column.
I would be very grateful if someone suggest how to do this!
Thanks!
Kamen
SQL Server doesn't allow inline XML conversion to have functions applied, i.e.: no CAST(...).query(), use a CTE to handle the conversion:
;WITH cte AS (
SELECT DocumentID, UserID, CAST(Content AS XML) AS XMLContent
FROM Documents
)
SELECT XMLContent.query('/IDMSDocument/DocumentContent/Attribute[5]/Value/Value')
FROM cte
WHERE XMLContent.value('(/IDMSDocument/DocumentContent/Attribute[5]/Value/Value)[1]', 'nvarchar(max)') like '%search%'
One thing though: I saw Unicode (Russian?) characters in the Content column. It may be better to use utf-16 in your XML and ntext for column type.
text and ntext are also on the way out. If this is new code, use nvarchar(max)

SQL 2008 SP1 XML Value from ntext Column

I have a column that contains the following xml:
<obj xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:vim25" versionId="5.1" xsi:type="ArrayOfKeyAnyValue">
<KeyAnyValue xsi:type="KeyAnyValue">
<key>1</key>
<value xsi:type="xsd:string">naa.6019cbc1a09e175d370df5320b00803a</value>
</KeyAnyValue>
<KeyAnyValue xsi:type="KeyAnyValue">
<key>2</key>
<value xsi:type="xsd:string">6215</value>
</KeyAnyValue>
<KeyAnyValue xsi:type="KeyAnyValue">
<key>3</key>
<value xsi:type="xsd:string">1291898</value>
</KeyAnyValue>
</obj>
I wish to return each of the key values as a separate column. I have tried:
SELECT [table].[column1]
,CONVERT(xml, [table].[column1]).value('(/obj/KeyAnyValue[1]/value)[1]', 'nvarchar(max)') As KeyValue
from [table]
This just returns NULL. Have I got the XML path right?
Sure something simple I am doing wrong and much appreciate any help.
Thanks
Your XPath expression has to say what namespace it's working with:
declare #data xml = '<obj xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:vim25" versionId="5.1"
xsi:type="ArrayOfKeyAnyValue">
<KeyAnyValue xsi:type="KeyAnyValue">
<key>1</key>
<value xsi:type="xsd:string">naa.6019cbc1a09e175d370df5320b00803a</value>
</KeyAnyValue>
<KeyAnyValue xsi:type="KeyAnyValue">
<key>2</key>
<value xsi:type="xsd:string">6215</value>
</KeyAnyValue>
<KeyAnyValue xsi:type="KeyAnyValue">
<key>3</key>
<value xsi:type="xsd:string">1291898</value>
</KeyAnyValue>
</obj>'
select #data.value('declare namespace a="urn:vim25";
(/a:obj/a:KeyAnyValue[1]/a:value)[1]', 'nvarchar(max)')
Produces:
naa.6019cbc1a09e175d370df5320b00803a