SQL 2008 SP1 XML Value from ntext Column - sql

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

Related

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.

How to parse SOAP XML in SQL Server and show as table

I need to parser a SOAP xml in SQL Server and convert it to table
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<ExecCommandResponse xmlns="http://tempuri.org/">
<ExecCommandResult>
<Result xmlns="">
<row>
<LOT>VERL5B3002PL</LOT>
<ID>115</ID>
<WH>710</WH>
<STPL>12</STPL>
</row>
<row>
<LOT>VERL68804EVN</LOT>
<ID>3716</ID>
<WH>771</WH>
<STPL>6</STPL>
</row>
</Result>
</ExecCommandResult>
</ExecCommandResponse>
</soap:Body>
</soap:Envelope>
I need to parser a SOAP xml in sql server and convert it to table
LOT | ID | WH | STPL
VERL68804EVN | 3716 | 771 | 6
Use the up-to-date functions to query XML.
Your XML is not very clean looking on the namespaces. There are two default namespaces, one of them empty... Therefore I would avoid (mask) them entirely.
DECLARE #xml XML=
'<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<ExecCommandResponse xmlns="http://tempuri.org/">
<ExecCommandResult>
<Result xmlns="">
<row>
<LOT>VERL5B3002PL</LOT>
<ID>115</ID>
<WH>710</WH>
<STPL>12</STPL>
</row>
<row>
<LOT>VERL68804EVN</LOT>
<ID>3716</ID>
<WH>771</WH>
<STPL>6</STPL>
</row>
</Result>
</ExecCommandResult>
</ExecCommandResponse>
</soap:Body>
</soap:Envelope>';
SELECT r.value('LOT[1]','varchar(max)') AS LOT
,r.value('ID[1]','int') AS ID
,r.value('WH[1]','int') AS WH
,r.value('STPL[1]','int') AS STPL
FROM #xml.nodes('/*:Envelope/*:Body/*:ExecCommandResponse/*:ExecCommandResult/*:Result/*:row') AS A(r)
--or even simpler (would even work without the *:):
SELECT r.value('LOT[1]','varchar(max)') AS LOT
,r.value('ID[1]','int') AS ID
,r.value('WH[1]','int') AS WH
,r.value('STPL[1]','int') AS STPL
FROM #xml.nodes('//*:row') AS A(r)
In general I'd say: Be as specific as possible, therefore rather suggest the first...
Try Below. See if it works.
declare #xmldata xml = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<ExecCommandResponse>
<ExecCommandResult>
<Result xmlns="">
<row>
<LOT>VERL5B3002PL</LOT>
<ID>115</ID>
<WH>710</WH>
<STPL>12</STPL>
</row>
<row>
<LOT>VERL68804EVN</LOT>
<ID>3716</ID>
<WH>771</WH>
<STPL>6</STPL>
</row>
</Result>
</ExecCommandResult>
</ExecCommandResponse>
</soap:Body>
</soap:Envelope>'
declare #readdoc as INT
EXEC sp_xml_preparedocument #readdoc OUTPUT, #xmldata , '<root xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />'
select LOT,ID,WH,STPL
from OPENXML(#readdoc,'soap:Envelope/soap:Body/ExecCommandResponse/ExecCommandResult/Result/row')
with
(
LOT [varchar](50) 'LOT',
ID [varchar](50) 'ID',
WH [varchar](50) 'WH',
STPL [varchar](50) 'STPL'
)
EXEC sp_xml_removedocument #readdoc
GO
Below is the output.

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)

Oracle 10 xmltype extract where clause

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

SQL server XML type

I have an XML type column in SQL server:
<LogMessage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LogMessageBusinessServiceRequest">
<Application>Services.Business.myapp</Application>
<Time>2013-05-30T15:01:38.932Z</Time>
<Level>Info</Level>
<Message>MultiQuery Biz Request</Message>
<MachineName>Machine1</MachineName>
<ThreadId>16084</ThreadId>
<Callsite>BLAH</Callsite>
<CreatedBy>Machine1\svc_biz_myapp</CreatedBy>
<Context>
<myappExtraInfo xmlns="http://services.somedomain.com/myapp/logging/extraInfo" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<CallType>MultiProcessQuery</CallType>
<RequestId>r163505508498822282742</RequestId>
<FirmId>160</FirmId>
<PMFirmId>203</PMFirmId>
<SubscriptionId>0</SubscriptionId>
<Token />
<LastClientSvcTimeMs>0</LastClientSvcTimeMs>
<ResultCode>0</ResultCode>
<ResultCodeDescription>OK</ResultCodeDescription>
<ElapsedTimeTotalMs>110</ElapsedTimeTotalMs>
<ElapsedTimeMtMs>110</ElapsedTimeMtMs>
<ElapsedTimeDacMs>109</ElapsedTimeDacMs>
<ElapsedTimePMSSMs>-1</ElapsedTimePMSSMs>
</myappExtraInfo>
</Context>
I want to get the FirmID from there. But I am not able with the following section of my select statement:
select
[Body].value('(/LogMessage/Context/myappExtraInfo/FirmId)[1]', 'varchar(max)') FirmID
What am I doing wrong?
Thanks for your time.
Shiyam
Try this - you need to respect the XML namespace that's defined on your <myappExtraInfo> node (and thus applies to all subnodes, too):
DECLARE #Test TABLE (ID INT NOT NULL, XmlContent XML)
INSERT INTO #Test VALUES(1,
'<LogMessage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LogMessageBusinessServiceRequest">
<Application>Services.Business.myapp</Application>
<Time>2013-05-30T15:01:38.932Z</Time>
<Level>Info</Level>
<Message>MultiQuery Biz Request</Message>
<MachineName>Machine1</MachineName>
<ThreadId>16084</ThreadId>
<Callsite>BLAH</Callsite>
<CreatedBy>Machine1\svc_biz_myapp</CreatedBy>
<Context>
<myappExtraInfo xmlns="http://services.somedomain.com/myapp/logging/extraInfo" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<CallType>MultiProcessQuery</CallType>
<RequestId>r163505508498822282742</RequestId>
<FirmId>160</FirmId>
<PMFirmId>203</PMFirmId>
<SubscriptionId>0</SubscriptionId>
<Token />
<LastClientSvcTimeMs>0</LastClientSvcTimeMs>
<ResultCode>0</ResultCode>
<ResultCodeDescription>OK</ResultCodeDescription>
<ElapsedTimeTotalMs>110</ElapsedTimeTotalMs>
<ElapsedTimeMtMs>110</ElapsedTimeMtMs>
<ElapsedTimeDacMs>109</ElapsedTimeDacMs>
<ElapsedTimePMSSMs>-1</ElapsedTimePMSSMs>
</myappExtraInfo>
</Context>
</LogMessage>')
;WITH XMLNAMESPACES('http://services.somedomain.com/myapp/logging/extraInfo' AS ns)
SELECT
XmlContent.value('(/LogMessage/Context/ns:myappExtraInfo/ns:FirmId)[1]', 'int')
FROM #Test
WHERE ID = 1
This returns the value 160 to me.