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
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"');
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.
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.
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)
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