I'm trying to extract XML data from feedback table consist of message column; below is the XML code:
<?xml version="1.0" encoding="UTF-8"?>
<message>Hi Hello</message>
<channel>XYZ</channel>
<sentiment-score>5.0</sentiment-score>
<structured-fields>
<structured-filed><name>NA_score</name><value>5</value></structured-filed>
<structured-filed><name>NPS_score</name><value>10</value></structured-filed>
<structured-fields>
I need to extract the above XML code from message column.
Your XML document needs to have a single XML element as the document root:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<message>Hi Hello</message>
<channel>XYZ</channel>
<sentiment-score>5.0</sentiment-score>
<structured-fields>
<structured-field><name>NA_score</name><value>5</value></structured-field>
<structured-field><name>NPS_score</name><value>10</value></structured-field>
</structured-fields>
</root>
Once that is fixed then just use an XMLTable and XPath:
SELECT *
FROM XMLTABLE(
'/root'
PASSING XMLType( '<?xml version="1.0" encoding="UTF-8"?><root><message>Hi Hello</message><channel>XYZ</channel><sentiment-score>5.0</sentiment-score><structured-fields><structured-field><name>NA_score</name><value>5</value></structured-field><structured-field><name>NPS_score</name><value>10</value></structured-field></structured-fields></root>' )
COLUMNS
MESSAGE VARCHAR2(200) PATH '//message',
CHANNEL VARCHAR2(200) PATH '//channel',
SENTIMENT_SCORE NUMBER(3,1) PATH '//sentiment-score',
NA_SCORE NUMBER(3,0) PATH '//structured-fields/structured-field[name/text()="NA_score"]/value',
NPS_SCORE NUMBER(3,0) PATH '//structured-fields/structured-field[name/text()="NPS_score"]/value'
);
Output:
MESSAGE | CHANNEL | SENTIMENT_SCORE | NA_SCORE | NPS_SCORE
:------- | :------ | --------------: | -------: | --------:
Hi Hello | XYZ | 5 | 5 | 10
db<>fiddle here
Related
I have a XML file that has a series of attributes. The attributes look something like the list below:
<Summary>
<MyAttributes AT001="ABC" AT002="123" AT003="456" AT004="DEF" ... />
</Summary>
I need to iterate over the attributes and add them into a SQL table that looks something like this:
Name
Value
AT001
ABC
AT002
123
AT003
456
AT004
DEF
...
...
Because the attribute list isn't fixed, I need to iterate over all the attributes to ensure each attribute gets added.
I typically can figure out how to do things in SQL, but this one has me stumped!
It is not clear what SQL you are using.
Here is how to do it in MS SQL Server by using its T-SQL and XQuery methods.
SQL
DECLARE #xml XML =
N'<Summary>
<MyAttributes AT001="ABC" AT002="123" AT003="456" AT004="DEF" />
</Summary>';
SELECT c.value('local-name(.)', 'VARCHAR(30)') AS attr_name
, c.value('.', 'VARCHAR(30)') AS attr_value
FROM #xml.nodes('/Summary/MyAttributes/#*') AS t(c);
Output
+-----------+------------+
| attr_name | attr_value |
+-----------+------------+
| AT001 | ABC |
| AT002 | 123 |
| AT003 | 456 |
| AT004 | DEF |
+-----------+------------+
I have a table as following
table 1
=======
ID | XMLcol
----------------------------
1 <?xml version="...</users>
2 <?xml version="...</users>
In my each xml data in the XMLcol contains informations about severel users.
As a example firs row 1 contain three users. row 2 contains two users.
row 1 xml data
<?xml version="1.0"?>
<users>
<user>
<name>user1</name>
</user>
<user>
<name>user2</name>
</user>
<user>
<name>user3</name>
</user>
</users>
row 2 xml data
<?xml version="1.0"?>
<users>
<user>
<name>user4</name>
</user>
<user>
<name>user5</name>
</user>
</users>
I want to create a view by allow to repeating the ID and show the each user name in another column as follows.
so final view should be like this,
ID | name
----------------------------
1 user1
1 user2
1 user3
2 user4
2 user5
Is there anyway to do such a kind of thing?
Use an XMLTABLE:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE table1 ( id, xml ) AS
SELECT 1, '<?xml version="1.0"?>
<users>
<user><name>user1</name></user>
<user><name>user2</name></user>
<user><name>user3</name></user>
</users>' FROM DUAL UNION ALL
SELECT 2, '<?xml version="1.0"?>
<users>
<user><name>user4</name></user>
<user><name>user5</name></user>
</users>' FROM DUAL
Query 1:
SELECT t.id,
x.name
FROM table1 t
CROSS JOIN
XMLTABLE(
'/users/user'
PASSING XMLType( t.xml )
COLUMNS name VARCHAR2(200) PATH 'name'
) x
Results:
| ID | NAME |
|----|-------|
| 1 | user1 |
| 1 | user2 |
| 1 | user3 |
| 2 | user4 |
| 2 | user5 |
I am new to XML stuff. I've figured out how to query and return the values from the XML file (example below). However, I run into a problem that it only capture the first node of 'SerialNo' tag because the tag has the same node name "SerialNo" repeated. In the XML file, it has 4 serial numbers for SKU#TT234343, but it only gives me the first Serial11111. I am totally stuck and don't know how to list all of those serial#.
I would like the query result for SKU#TT234343, listing all 4 serial numbers if possible.
Please help. Thanks!
The XML File looks like:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<ROOT>
<ShipNotice version="1" >
<InvoiceDate>01/01/2015</InvoiceDate>
<InvoiceNumber>6868686</InvoiceNumber>
<ShipDate>02/02/2015</ShipDate>
<ShipTime>2306</ShipTime>
<PONumber>P444444</PONumber>
<PODate>03/03/2015</PODate>
<ShipCode>XXX</ShipCode>
<ShipDescription>FedEx Economy</ShipDescription>
<ShipTo>
<AddressName>ShipABC</AddressName>
<AddressContact>Name1</AddressContact>
<AddressLine1>2222 Street Name</AddressLine1>
<AddressLine2> </AddressLine2>
<City>AUSTIN</City>
<State>TX</State>
<ZipCode>78111</ZipCode>
</ShipTo>
<BillTo>
<AddressName>BillABC</AddressName>
<AddressContact>Name1</AddressContact>
<AddressLine1>1234 Street Name</AddressLine1>
<AddressLine2>-SUITE 111</AddressLine2>
<City>Los Angeles</City>
<State>CA</State>
<ZipCode>95136</ZipCode>
</BillTo>
<TotalWeight>324</TotalWeight>
<EmptyCartonWGT>0</EmptyCartonWGT>
<NumberOfCarton>1</NumberOfCarton>
<DirectShipFlag>D</DirectShipFlag>
<ShipFromWarehouse>88</ShipFromWarehouse>
<ShipFromZip>94538</ShipFromZip>
<ShipTrackNo>33333333</ShipTrackNo>
<EndUserPONumber>55555555</EndUserPONumber>
<CustomerSONumber/>
<Package sequence="1" >
<TrackNumber>666666666</TrackNumber>
<PackageWeight>324</PackageWeight>
<Item sequence="1" >
<SOLineNo>1</SOLineNo>
<MfgPN>XYZ1111111</MfgPN>
<SKU>TT234343</SKU>
<ShipQuantity>4</ShipQuantity>
<CustPOLineNo>1</CustPOLineNo>
<CustSOLineNo/>
<Description>Server1234</Description>
<CustPN/>
<UPC/>
<UnitPrice>1000</UnitPrice>
<EndUserPOLineNo>0</EndUserPOLineNo>
<SerialNo>Serial11111</SerialNo>
<SerialNo>Serial22222</SerialNo>
<SerialNo>Serial33333</SerialNo>
<SerialNo>Serial44444</SerialNo>
</Item>
<Item sequence="2" >
<SOLineNo>2</SOLineNo>
<MfgPN>XYZ222222</MfgPN>
<SKU>TT8848788</SKU>
<ShipQuantity>4</ShipQuantity>
<CustPOLineNo>2</CustPOLineNo>
<CustSOLineNo/>
<Description>GGG localization</Description>
<CustPN/>
<UPC/>
<UnitPrice>0.00</UnitPrice>
<EndUserPOLineNo>0</EndUserPOLineNo>
<SerialNo/>
</Item>
</Package>
</ShipNotice>
</ROOT>
The SQL Query:
DECLARE #XML AS XML, #hDoc AS INT, #SQL NVARCHAR (MAX)
EXEC sp_xml_preparedocument #hDoc OUTPUT, #xmlData
SELECT
InvoiceNumber, PONumber, PODate
, AddressName
, MfgPN, SerialNo
--, AddressContact, AddressLine1, AddressLine2, City, State, ZipCode
FROM OPENXML(#hDoc, '/ROOT/ShipNotice/Package/Item')
WITH
(
--- ################# Level 1 #################
InvoiceNumber [varchar](50) '../../InvoiceNumber',
PONumber [varchar](100) '../../PONumber',
PODate [varchar](100) '../../PODate',
--- ################# Level 2 #################
AddressName [varchar](100) '../../ShipTo/AddressName',
--- ################# Level 3 #################
MfgPN [varchar](100) 'MfgPN',
SerialNo [varchar](100) 'SerialNo'
)
You can try using the newer technology XQuery instead of OPENXML(). Using XQuery, you can use nodes() method to shred the XML on elements that will correspond to the rows in the output, and use value() to extract the element value :
SELECT
shipnotice.value('InvoiceNumber[1]','varchar(20)') InvoiceNumber
, shipnotice.value('PONumber[1]','varchar(20)') PONumber
, shipnotice.value('PODate[1]','varchar(20)') PODate
, shipnotice.value('(ShipTo/AddressName)[1]','varchar(100)') AddressName
, item.value('MfgPN[1]','varchar(100)') MfgPN
, serialno.value('.','varchar(100)') SerialNo
FROM #XML.nodes('/ROOT/ShipNotice') as t(shipnotice)
OUTER APPLY shipnotice.nodes('Package/Item') as t2(item)
OUTER APPLY item.nodes('SerialNo') as t3(serialno)
Sqlfiddle Demo
output :
| InvoiceNumber | PONumber | PODate | AddressName | MfgPN | SerialNo |
|---------------|----------|------------|-------------|------------|-------------|
| 6868686 | P444444 | 03/03/2015 | ShipABC | XYZ1111111 | Serial11111 |
| 6868686 | P444444 | 03/03/2015 | ShipABC | XYZ1111111 | Serial22222 |
| 6868686 | P444444 | 03/03/2015 | ShipABC | XYZ1111111 | Serial33333 |
| 6868686 | P444444 | 03/03/2015 | ShipABC | XYZ1111111 | Serial44444 |
| 6868686 | P444444 | 03/03/2015 | ShipABC | XYZ222222 | |
I'm trying to extract data in tabular format from an XML field in an Oracle database.
Please see sample xml field below:
<?xml version='1.0' encoding='UTF-8'?>
<root>
<element1>
<Header Client_ID="100" Sent_date_time="2015-03-02T9:30:43.808-06:00"/>
<element2>
<element3 UnitPrice="3.2" ItemID="njh1"/>
<element3 UnitPrice="4.1" ItemID="ole5"/>
<element3 UnitPrice="4.6" ItemID="usd3"/>
<element3 UnitPrice="8.2" ItemID="eor9"/>
<element3 UnitPrice="2.9" ItemID="abc8"/>
<element3 UnitPrice="5.1" ItemID="gfd3"/>
<element3 UnitPrice="4.9" ItemID="kdu0"/>
<element3 UnitPrice="6.1" ItemID="uso8"/>
</element2>
</element1>
</root>
My aim is to query the itemID and UnitPrice fields from the xml field above in the format shown below:
ItemID UnitPrice
njh1 3.2
ole5 4.1
usd3 4.6
eor9 8.2
abc8 2.9
gfd3 5.1
kdu0 4.9
uso8 6.1
I'm fairly new to querying data from xml fields. I have tried using the getStringVal, but all I get is one single long string.
Please advise on a solution. Please note that I don't have dba rights to this database.
Thank you
You have to use XMLTABLE function for this.
SQL Fiddle
Oracle 11g R2 Schema Setup:
create table xml_test(
xml_col varchar2(2000)
);
insert into xml_test values(
'<?xml version=''1.0'' encoding=''UTF-8''?>
<root>
<element1>
<Header Client_ID="100" Sent_date_time="2015-03-02T9:30:43.808-06:00"/>
<element2>
<element3 UnitPrice="3.2" ItemID="njh1"/>
<element3 UnitPrice="4.1" ItemID="ole5"/>
<element3 UnitPrice="4.6" ItemID="usd3"/>
<element3 UnitPrice="8.2" ItemID="eor9"/>
<element3 UnitPrice="2.9" ItemID="abc8"/>
<element3 UnitPrice="5.1" ItemID="gfd3"/>
<element3 UnitPrice="4.9" ItemID="kdu0"/>
<element3 UnitPrice="6.1" ItemID="uso8"/>
</element2>
</element1>
</root>'
);
Query:
select cols.ItemID, cols.UnitPrice
from xml_test x,
xmltable('root/element1/element2/element3'
passing xmltype(x.xml_col)
columns ItemID varchar2(10) path '#ItemID',
UnitPrice varchar2(10) path '#UnitPrice'
) cols;
Results:
| ITEMID | UNITPRICE |
|--------|-----------|
| njh1 | 3.2 |
| ole5 | 4.1 |
| usd3 | 4.6 |
| eor9 | 8.2 |
| abc8 | 2.9 |
| gfd3 | 5.1 |
| kdu0 | 4.9 |
| uso8 | 6.1 |
I am trying to learn XQuery and Xpath in SQL Server
I created a sample file and uploaded it to a Table with 2 columns ID, XMLDoc. The below code is within the document in the XMLDoc column so it is the only record in the column.
I am trying to query the file so it will show all the results in a table like a normal select statement would. How would you construct the select statement to select all the information like a select * ? How would you select one field like all suppliers? I would like to select the supplier, requestor for each item.
Here is the xml:
<tst:Document xmlns:tst ="http://www.w3.org/2001/XMLSchema" SchemaVersion="0.1" Classification="Test" UniqueIdentifier="1234" Title="Test">
<tst:Revision RevNumber="0" TimeStamp="2013-01-21T12:56:00">
<tst:Author Name="Me" Guid="1234" />
</tst:Revision>
<tst:Formats>
<tst:A12 Item="1">
<tst:Requestor Name="ADC" />
<tst:Supplier Name="BBC" />
<tst:Code>B</tst:Code>
<tst:IsRequirement>true</tst:IsRequirement>
<tst:IsNotRequired>false</tst:IsInformation>
<tst:Remarks>ADC (Random Input Section)</tst:Remarks>
<tst:Notes>Next Round.</tst:Notes>
<tst:Events>
<tst:SubTest Item="0">
<tst:BLDG>BLDG1</tst:BLDG>
<tst:BLDG2>BLDG2</tst:BLDG2>
<tst:Function>Testing</tst:Function>
<tst:Desciption>Normal Flow</tst:Desciption>
</tst:SubTest>
</tst:Events>
<tst:IsReady>true</tst:IsReady>
<tst:IsNotReady>false</tst:IsNotReady>
</tst:A12>
<tst:A12 Item="2">
<tst:Requestor Name="ADC" />
<tst:Supplier Name="BBC" />
<tst:Code>A</tst:Code>
<tst:IsRequirement>true</tst:IsRequirement>
<tst:IsInformation>false</tst:IsInformation>
<tst:Remarks>Requirement Not yet met.</tst:Remarks>
<tst:Notes>Ready.</tst:Notes>
<tst:Events>
<tst:SubTest Item="0">
<tst:BLDG>BLDG3</tst:BLDG>
<tst:BLDG2>BLDG4</tst:BLDG2>
<tst:TotalEvents>1</tst:TotalEvents>
<tst:Function>Development</tst:Function>
<tst:Desciption>Process Flow</tst:Desciption>
</tst:SubTest>
</tst:Events>
<tst:IsReady>true</tst:IsReady>
<tst:IsNotReady>false</tst:IsNotReady>
</tst:A12>
</tst:Formats>
</tst:Document>
Query I ran
I just got a return, but it is still showing it in xml form:
Select XMLDoc.query('/*/*/*/*[local-name()=("Requestor", "Supplier")]')
From XMLLoad
I Updated the xml snippet, sry had a typo! It will load now
INSERT INTO TableName(ColumnName)
SELECT * FROM OPENROWSET(
BULK 'C:\Users\Filepath.xml',
SINGLE_BLOB) AS x;
SQL Fiddle
MS SQL Server 2008 Schema Setup:
create table XMLDoc (XMLLoad xml);
insert into XMLDoc(XMLLoad) values('
<tst:Document xmlns:tst ="http://www.w3.org/2001/XMLSchema" SchemaVersion="0.1" Classification="Test" UniqueIdentifier="1234" Title="Test">
<tst:Revision RevNumber="0" TimeStamp="2013-01-21T12:56:00">
<tst:Author Name="Me" Guid="1234" />
</tst:Revision>
<tst:Formats>
<tst:A12 Item="1">
<tst:Requestor Name="ADC" />
<tst:Supplier Name="BBC" />
<tst:Code>B</tst:Code>
<tst:IsRequirement>true</tst:IsRequirement>
<tst:IsInformation>false</tst:IsInformation>
<tst:Remarks>ADC (Random Input Section)</tst:Remarks>
<tst:Notes>Next Round.</tst:Notes>
<tst:Events>
<tst:SubTest Item="0">
<tst:BLDG>BLDG1</tst:BLDG>
<tst:BLDG2>BLDG2</tst:BLDG2>
<tst:Function>Testing</tst:Function>
<tst:Desciption>Normal Flow</tst:Desciption>
</tst:SubTest>
</tst:Events>
<tst:IsReady>true</tst:IsReady>
<tst:IsNotReady>false</tst:IsNotReady>
</tst:A12>
<tst:A12 Item="2">
<tst:Requestor Name="ADC" />
<tst:Supplier Name="BBC" />
<tst:Code>A</tst:Code>
<tst:IsRequirement>true</tst:IsRequirement>
<tst:IsInformation>false</tst:IsInformation>
<tst:Remarks>Requirement Not yet met.</tst:Remarks>
<tst:Notes>Ready.</tst:Notes>
<tst:Events>
<tst:SubTest Item="0">
<tst:BLDG>BLDG3</tst:BLDG>
<tst:BLDG2>BLDG4</tst:BLDG2>
<tst:TotalEvents>1</tst:TotalEvents>
<tst:Function>Development</tst:Function>
<tst:Desciption>Process Flow</tst:Desciption>
</tst:SubTest>
</tst:Events>
<tst:IsReady>true</tst:IsReady>
<tst:IsNotReady>false</tst:IsNotReady>
</tst:A12>
</tst:Formats>
</tst:Document>');
Query 1:
with xmlnamespaces('http://www.w3.org/2001/XMLSchema' as tst)
select A12.X.value('#Item', 'int') as A12,
A12.X.value('tst:Requestor[1]/#Name', 'varchar(25)') as Requestor,
A12.X.value('tst:Supplier[1]/#Name', 'varchar(25)') as Supplier,
A12.X.value('(tst:Code/text())[1]', 'varchar(25)') as Code,
A12.X.value('(tst:IsRequirement/text())[1]', 'bit') as IsRequirement,
A12.X.value('(tst:IsInformation/text())[1]', 'bit') as IsInformation,
A12.X.value('(tst:Remarks/text())[1]', 'varchar(50)') as Remarks,
A12.X.value('(tst:Notes/text())[1]', 'varchar(50)') as Notes,
ST.X.value('#Item', 'int') as SubTest,
ST.X.value('(tst:BLDG/text())[1]', 'varchar(25)') as BLDG,
ST.X.value('(tst:BLDG2/text())[1]', 'varchar(25)') as BLDG2,
ST.X.value('(tst:TotalEvents/text())[1]', 'int') as TotalEvents,
ST.X.value('(tst:Function/text())[1]', 'varchar(25)') as [Function],
ST.X.value('(tst:Desciption/text())[1]', 'varchar(50)') as Desciption
from XMLDoc as X
cross apply X.XMLLoad.nodes('/tst:Document/tst:Formats/tst:A12') as A12(X)
cross apply A12.X.nodes('tst:Events/tst:SubTest') as ST(X)
Results:
| A12 | REQUESTOR | SUPPLIER | CODE | ISREQUIREMENT | ISINFORMATION | REMARKS | NOTES | SUBTEST | BLDG | BLDG2 | TOTALEVENTS | FUNCTION | DESCIPTION |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 1 | ADC | BBC | B | 1 | 0 | ADC (Random Input Section) | Next Round. | 0 | BLDG1 | BLDG2 | (null) | Testing | Normal Flow |
| 2 | ADC | BBC | A | 1 | 0 | Requirement Not yet met. | Ready. | 0 | BLDG3 | BLDG4 | 1 | Development | Process Flow |
Check out value() and nodes().