Convert xml text in a cell to Columns - sql

Our front end development team saves surveys in a SQL database table as xml text. Each survey has different set of fields and need help on how to automatically convert the cell holding the xml text to multiple columns.
Below is an example of the xml text in a cell which needs to be split into individual columns.
<?xml version="1.0" encoding="utf-16"?>
<root>
<userid>JS 30/08/1981</userid>
<column___1>0</column___1>
<column___2>1</column___2>
<column___3>0</column___3>
<column___4>0</column___4>
<column___5>0</column___5>
<column___6>0</column___6>
<column___7>0</column___7>
<column___8>0</column___8>
<column___9>0</column___9>
<column___1_0>0</column___1_0>
<column___1_1>0</column___1_1>
<column___1_2>0</column___1_2>
<column___1_3>0</column___1_3>
<column___1_4>0</column___1_4>
<column___1_5>0</column___1_5>
<column___1_6>0</column___1_6>
<column___1_7>0</column___1_7>
<column___1_8>0</column___1_8>
<column___1_9>0</column___1_9>
<column___2_0>0</column___2_0>
<column___2_1>0</column___2_1>
<column___D_S>0</column___D_S>
<column___A_S>2</column___A_S>
<column___S_S>0</column___S_S>
<userid___u_i_d>5</userid___u_i_d>
</root>

I created a test table using the syntax below:
CREATE TABLE [dbo].[XmlTest](
[id] [int] IDENTITY(1,1) NOT NULL,
[surveyxml] [xml] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
I then loaded 2 records into the test table(the 1st being the XML you have in your example).
Use a query like below:
SELECT
fields.value('(userid/text())[1]', 'varchar(50)') as userid,
fields.value('(column___1/text())[1]', 'varchar(50)') as column1,
fields.value('(column___2/text())[1]', 'varchar(50)') as column2,
fields.value('(column___3/text())[1]', 'varchar(50)') as column3
FROM
xmltest CROSS APPLY
surveyxml.nodes('/root') AS Root(fields)
The following results are returned:
You can add all the fields you want to the query, and change the data type if you know what it is. Good Luck

You can make this as generic dynamic code like this:
drop table if exists #tmp
DECLARE #XML as xml
SET #XML = N'<?xml version="1.0" encoding="utf-16"?>
<root>
<userid>JS 30/08/1981</userid>
<column___1>0</column___1>
<column___2>1</column___2>
<column___3>0</column___3>
<column___4>0</column___4>
<column___5>0</column___5>
<column___6>0</column___6>
<column___7>0</column___7>
<column___8>0</column___8>
<column___9>0</column___9>
<column___1_0>0</column___1_0>
<column___1_1>0</column___1_1>
<column___1_2>0</column___1_2>
<column___1_3>0</column___1_3>
<column___1_4>0</column___1_4>
<column___1_5>0</column___1_5>
<column___1_6>0</column___1_6>
<column___1_7>0</column___1_7>
<column___1_8>0</column___1_8>
<column___1_9>0</column___1_9>
<column___2_0>0</column___2_0>
<column___2_1>0</column___2_1>
<column___D_S>0</column___D_S>
<column___A_S>2</column___A_S>
<column___S_S>0</column___S_S>
<userid___u_i_d>5</userid___u_i_d>
</root>
'
/* First find all the column names and values */
SELECT
b.value('local-name(.)','VARCHAR(50)') AS ColumnName,
b.value('.','VARCHAR(MAX)') AS ColumnValue
into #tmp
FROM #xml.nodes('/root') x(x)
CROSS APPLY x.nodes('*') a(b)
/* Now build the select */
declare #sql nvarchar(max)=''
select #sql=#sql+'
'+iif(#sql='','',',')+''''+ ColumnValue + '''['+ColumnName+']'
from #tmp
set #sql='select '+#sql
exec sp_executesql #sql

Related

SQL Parse xml column data

I have very little experience with SQL Server. Here is what I am trying to accomplish:
I have a table with many rows. Every row contains a column named "Config". The data stored in the Config column is of the xml type. The xml structure looks like this:
<root>
<path1>
<path2>
<path3>true</path3>
</path2>
</path1>
</root>
I am trying to go through every row in the table and find the percentage of true to false values of <path3>.
I looked at some SQL documentation and tried to use the value() function I am having difficulties extracting the XML data from the column:
select Config.value('(/root/path1/path2/path3)[1]','nvarchar(max)') from [MyDB].[dbo].[MyTable]
Here is the result of my query:
I would like to query and extract data from the XML "Config" column of my table and aggregate that data into columns.
You need to specify namespaces in the query when xml is built with namespaces. For example
CREATE TABLE tbl (Config xml);
INSERT INTO tbl (Config)
VALUES ('<root xmlns="abc">
<path1>
<path2>
<path3>true</path3>
</path2>
</path1>
</root>') ;
Then
with xmlnamespaces (DEFAULT 'abc')
select Config.value('(/root/path1/path2/path3)[1]','nvarchar(max)') path3Txt
from tbl;
or explicit specification
with xmlnamespaces ('abc' as x)
select Config.value('(/x:root/x:path1/x:path2/x:path3)[1]','nvarchar(max)') path3Txt
from tbl;
You would need to use CROSS APPLY. Check it out.
SQL
-- DDL and sample data population, start
DECLARE #tbl TABLE (ID INT IDENTITY(1,1) PRIMARY KEY, [Config] XML);
INSERT INTO #tbl
VALUES (N'<root>
<path1>
<path2>
<path3>true</path3>
</path2>
</path1>
</root>')
, (N'<root>
<path1>
<path2>
<path3>false</path3>
</path2>
</path1>
</root>');
-- DDL and sample data population, end
;WITH rs AS
(
SELECT ID
, col.value('(./text())[1]','VARCHAR(20)') AS Result
FROM #tbl tbl
CROSS APPLY tbl.[Config].nodes('/root/path1/path2/path3') AS tab(col)
)
SELECT * FROM rs;

Selecting XML nodes with SQL Server

My XMLData is stored under table.[column] : dbo.promotions.[PromotionDiscountData]
and the XML looks like the following when i expand it:
<ArrayOfPromotionDiscountBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<PromotionDiscountBase xsi:type="OrderPromotionDiscount">
<DiscountType>Fixed</DiscountType>
<DiscountAmount>5.0000</DiscountAmount>
</PromotionDiscountBase>
</ArrayOfPromotionDiscountBase>
I would like to export a report and flatten out the xml as a column with everything else in the dbo.promotions table.
What would be the best way to get the DiscountType and DiscountAmount Out of the xml?
Thanks!
Please try the following.
SQL
-- DDL and data population, start
DECLARE #tbl TABLE (ID INT IDENTITY(1,1) PRIMARY KEY,[xmlData] XML NOT NULL);
INSERT INTO #tbl([xmlData])
VALUES
(N'<ArrayOfPromotionDiscountBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<PromotionDiscountBase xsi:type="OrderPromotionDiscount">
<DiscountType>Fixed</DiscountType>
<DiscountAmount>5.0000</DiscountAmount>
</PromotionDiscountBase>
</ArrayOfPromotionDiscountBase>');
-- DDL and data population, end
SELECT ID
, col.value('(DiscountType)[1]', 'VARCHAR(30)') AS [DiscountType]
, col.value('(DiscountAmount)[1]', 'DECIMAL(10,4)') AS [DiscountAmount]
FROM #tbl AS tbl
CROSS APPLY tbl.[xmlData].nodes('/ArrayOfPromotionDiscountBase/PromotionDiscountBase') AS tab(col);

How to write a FULL XML record to column based on row count

I have a stored procedure that I am using to write custom XML based on a vendors requirements for integrating two systems. I would like to write each record to a column to bypass the char limitation in a sql column. I am including a very simple version of my SP. I have 600 fields in the true SP. I have 4700 records in the table and my XML is getting cut off after 200 rows process. Is there a way to return everything between the Command action="Upsert" invalidLookupBehavior="Skip" and the "/Command" in their own columns?
I'm stumped. I apologize for the duplicate post.. TAB
USE [DEV]
GO
/****** Object: StoredProcedure [dbo].[MASTER_TABLE_XML_PHASE_I] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[MASTER_TABLE_XML_PHASE_I_SIMPLE]
AS
declare
#xml nvarchar(max),
#metaEMPLOYEE nvarchar(max)
CREATE TABLE #MASTER_TABLE_IMPORT
(
[EMP_COMPANY_ID] [int] NOT NULL,
[EMP_LAST_NAME] [nvarchar](50) NULL,
[EMP_MIDDLE_NAME] [nvarchar](50) NULL,
[EMP_FIRST_NAME] [nvarchar](50) NULL,
[EMP_PREFIX] [nchar](6) NULL,
[EMP_PREFERRED_NAME] [nvarchar](50) NULL,
[EMP_FORMER_NAME] [nvarchar](50) NULL,
[EMP_SYSTEM_NUMBER] [nvarchar](100) NOT NULL,
[IMP_CREATE_DATE] [datetime] NULL,
[IMP_LAST_UPDATE_DATE] [datetime] NULL,
)
INSERT INTO #MASTER_TABLE_IMPORT
(
[EMP_COMPANY_ID] ,
[EMP_LAST_NAME] ,
[EMP_MIDDLE_NAME] ,
[EMP_FIRST_NAME],
[EMP_PREFIX] ,
[EMP_PREFERRED_NAME],
[EMP_FORMER_NAME] ,
[EMP_SYSTEM_NUMBER] ,
[IMP_CREATE_DATE],
[IMP_LAST_UPDATE_DATE]
)
SELECT
EMP_COMPANY_ID ,
EMP_LAST_NAME,
EMP_MIDDLE_NAME ,
EMP_FIRST_NAME,
EMP_PREFIX ,
EMP_PREFERRED_NAME,
EMP_FORMER_NAME ,
T1.EMP_SYSTEM_NUMBER,
IMP_CREATE_DATE,
IMP_LAST_UPDATE_DATE
FROM MASTER_TABLE_PHASE_I AS T1
INNER JOIN (SELECT EMP_SYSTEM_NUMBER ,MAX(IMP_CREATE_DATE) AS MaxDate
FROM MASTER_TABLE_PHASE_I
GROUP BY EMP_SYSTEM_NUMBER) AS T2
ON (T1.EMP_SYSTEM_NUMBER = T2.EMP_SYSTEM_NUMBER AND T1.IMP_CREATE_DATE = T2.MaxDate)
/*OPEN XML FULL FILE TAGS*/
set #xml =
N'<DataChange><Commands>'
+ N'' + CHAR(10);
/*OPEN EMPLOYEE TABLE*/
/*OPEN EMPLOYEE FIELDS*/
select #metaEMPLOYEE =
CONVERT(nvarchar(max),
(
(select
/*OPEN XML UNIQUE RECORD TAGS*/
'<Command action="Upsert" invalidLookupBehavior="Skip"><Tables><Table name="EMPLOYEE"><Fields>'+
'<Field name="COMPANY_ID" lookupValue="False">84</Field>',
'<Field name="LAST_NAME">' + EMP_LAST_NAME + '</Field>',
'<Field name="MIDDLE_NAME">' + EMP_MIDDLE_NAME + '</Field>',
'<Field name="FIRST_NAME">' + EMP_FIRST_NAME + '</Field>',
'<Field name="PREFIX" lookupValue="True">' + EMP_PREFIX + '</Field>',
'<Field name="PREFERRED_NAME">' + EMP_PREFERRED_NAME + '</Field>',
'<Field name="FORMER_NAME">' + EMP_FORMER_NAME + '</Field>',
'<Field name="SYSTEM_NUMBER" recordIdentifier="True">' + EMP_SYSTEM_NUMBER + '</Field>',
/*CLOSE EMPLOYEE FIELDS*/
'</Fields>',
/*CLOSE EMPLOYEE TABLE*/
'</Table>',
/*CLOSE EMPLOYEE RECORD ALL TABLES*/
'</Tables>',
/*CLOSE XML COMMAND*/
/*CLOSE XML UNIQUE RECORD TAGS*/
'</Command>'
FROM #MASTER_TABLE_IMPORT
WHERE 1=1
FOR XML PATH(''),TYPE).value('(./text())[1]','NVARCHAR(MAX)')))
/*BUILD XML*/
/*CLOSING MASTER COMMAND*/
/*CLOSING MASTER DATA CHANGE*/
SET #xml = #xml + #metaEMPLOYEE +'</Commands></DataChange>'
SELECT #xml;
CREATE TABLE XMLDATA
(
xCol XML
) ;
INSERT INTO XMLDATA ( xCol )
SELECT #xml
DECLARE #Command VARCHAR(255)
DECLARE #Filename VARCHAR(100)
SELECT #Filename = 'C:\Client_XML\Data.dat'
SELECT #Command = 'bcp "select xCol from ' + DB_NAME()
+ '..XMLDATA" queryout '
+ #Filename + ' -w -T -S' + ##servername
EXECUTE master..xp_cmdshell #command
--WRITE THE XML TO A FILE
SELECT CONVERT(nVARCHAR(max),BulkColumn)
FROM OPENROWSET(BULK 'C:\Client_XML\Data.dat', SINGLE_BLOB) AS x
DROP TABLE XMLDATA
Thank you Shnugo. I'm not a SQL developer. Unfortunately we have a resource issue and so I thought I would give this a try. I understand enough to be dangerous and ask questions correctly. This is so much better. Thank you, thank you. There are only a handful of fields in this example (I have nearly 600 fields and 4700 records to process every 15 minutes, hence the need for this). When I run this, the XML is still truncated at row 1200. Is there a way to take the #myXML results and parse to columns base on the the row id of the data source? One row? Is there a column number limitation in a SQL table? Here is a screen shot of what I would expect this table to look like.
SQL Table concept
Thank you for your help and you patience.
Pennie
I am determining that it is truncated in two ways.
1- I am saving the file to a folder on my HD using xp_cmd_shell
2- I have saved the results from my query.
This is the last record in the returned file row 1200
<Command action="Upsert" invalidLookupBehavior="Skip"><Tables><Table name="EMPLOYEE" /><Fields><Field name="COMPANY_ID" lookupValue="False">84</Field><Field name="LAST_NAME">Auditore</Field><Field name="MIDDLE_NAME" /><Field name="FIRST_NAME">Ezio</Field><Field name="PREFIX" loo
ends right there.
Pennie
Hi Shnugo. How do I add Child Nodes ==> ChildTables to your concept? I just keep getting errors.
The FOR XML clause is not allowed in a ASSIGNMENT statement.
This is what the XML result should look like. I also have ChildTables nested in ChildTables.
<Command action="Upsert" invalidLookupBehavior="Skip"><Tables><Table name="EMPLOYEE"><Fields><Field name="COMPANY_ID" lookupValue="False">84</Field><Field name="LAST_NAME">Pinot</Field><Field name="FIRST_NAME">Gris</Field><Field name="PREFIX" lookupValue="True">Ms.</Field><Field name="SYSTEM_NUMBER" recordIdentifier="True">1603-XXXXX</Field><Field name="GENDER" lookupValue="True">Female</Field><Field name="MARITAL_STATUS" lookupValue="True">Married</Field><Field name="BIRTH_COUNTRY" lookupValue="True">Guatemala</Field><Field name="USER_ID_EMAIL">gris.pinot#me.com</Field></Fields><ChildTables><Table name="EMPLOYEE_CF"><Fields><Field name="CF_TEXT001">Gris</Field><Field name="CF_TEXT002">Pinot</Field><Field name="CF_TEXT003">Pinot</Field><Field name="CF_TEXT026">Family</Field><Field name="CF_TEXT027">No</Field><Field name="CF_NUMBER001">2</Field></Fields></Table><Table name="EMPLOYEE_PASSPORT"><Fields><Field name="ISSUE_COUNTRY" lookupValue="True">Guatemala</Field></Fields></Table><Table name="ASSIGNMENT"><Fields><Field name="NUMBER" recordIdentifier="True">1603-XXXXX</Field><Field name="FROM_COUNTRY" lookupValue="True">United Arab Emirates</Field><Field name="TO_COUNTRY" lookupValue="True">Malaysia</Field><Field name="TYPE" lookupValue="True">Long Term</Field><Field name="PHASE" lookupValue="True">New Assignment</Field><Field name="SCHEDULED_END_DATE">04/30/2019</Field><Field name="FROM_COMPANY_LEVEL1">From Level1</Field><Field name="FROM_COMPANY_LEVEL2">From Level2</Field><Field name="FROM_COMPANY_LEVEL3">From Level3</Field><Field name="FROM_COMPANY_LEVEL4">From Level4</Field><Field name="TO_COMPANY_LEVEL1">To Level1</Field><Field name="TO_COMPANY_LEVEL2">To Level2</Field><Field name="TO_COMPANY_LEVEL3">To Level3</Field><Field name="TO_COMPANY_LEVEL4">To Level4</Field></Fields><ChildTables><Table name="ASSIGNMENT_CF"><Fields><Field name="CF_TEXT002">No</Field><Field name="CF_TEXT005">1234567</Field><Field name="CF_TEXT009">1111111</Field><Field name="CF_TEXT010">2222222</Field><Field name="CF_DATE004">03/22/2016</Field><Field name="CF_DATE005">03/23/2016</Field></Fields></Table><Table name="ASSIGNMENT_EMPLOYEE_CONTACT"><Fields><Field name="LOCATION_TYPE" recordIdentifier="true">Current Address</Field><Field name="CONTACT_TYPE" recordIdentifier="true">Address</Field></Fields></Table><Table name="ASSIGNMENT_CONTACT"><Fields><Field name="TYPE" recordIdentifier="true">Manager</Field><Field name="NAME">Trinity</Field><Field name="EMAIL">trinity#me.com.com</Field><Field name="PHONE">5555555555</Field></Fields></Table><Table name="ASSIGNMENT_CONTACT"><Fields><Field name="TYPE" recordIdentifier="true">Home HR Contact</Field><Field name="NAME">Kim</Field><Field name="EMAIL">kim.#me.com</Field><Field name="PHONE">5555555551</Field></Fields></Table><Table name="ASSIGNMENT_CONTACT"><Fields><Field name="TYPE" recordIdentifier="true">HR Contact</Field><Field name="NAME">Pennie</Field><Field name="EMAIL">me#me.com</Field><Field name="PHONE">5555555552</Field></Fields></Table><Table name="ASSIGNMENT_MAILING_ADDRESS"><Fields><Field name="LOCATION_TYPE" recordIdentifier="true">Home Address</Field> </Fields></Table><Table name="POLICY"><Fields><Field name="NAME">424</Field></Fields></Table><Table name="UT_ACCOUNT_SPECIFIC_MISC_COMP_DATA"><Fields><Field name="HOME_BUSINESS_FUNCTION">Finance</Field><Field name="HOST_BUSINESS_FUNCTION">Finance</Field><Field name="EST_ASSIGNMENT_START_DATE">07/01/2016</Field></Fields></Table></ChildTables></Table></ChildTables></Table></Tables></Command>
I appreciate the help.
Pennie
4/5
#Shnugo This is still unresolved as I am not able to use #command. The other part of this is I cannot write the XML from the result set. It is custom. The result set is coming from a system I do not own. Though this was all extremely helpful. I am working with the suggestions. I would like to vote as you were very responsive and so knowledgeable. Maybe because I am so new I am not able to vote. Regardless, I am not clear on how to vote.
P
You are doing a huge lot of unnecessary work...
It seems that you do not need your temp table
You should never build your XML as string via string concatenation
The result returned by SELECT ... FOR XML has (almost) no limit in size
Size restrictions are - in most cases - bound to intermediate steps / conversions / computations / whatever, where the return type is not big enough
If you go like this, the whole result is in #myXML.
From there you can continue however you like...
DECLARE #myXML XML;
WITH CTE_instead_of_TempTable AS
(
SELECT EMP_COMPANY_ID ,
EMP_LAST_NAME,
EMP_MIDDLE_NAME ,
EMP_FIRST_NAME,
EMP_PREFIX ,
EMP_PREFERRED_NAME,
EMP_FORMER_NAME ,
T1.EMP_SYSTEM_NUMBER,
IMP_CREATE_DATE,
IMP_LAST_UPDATE_DATE
--This is the source you are using to fill your temp table. Cannot know, wheter it's correct or not
--The two "FROM" lines are disturbing...
FROM MASTER_TABLE_PHASE_I AS T1
INNER JOIN (SELECT EMP_SYSTEM_NUMBER ,MAX(IMP_CREATE_DATE) AS MaxDate
FROM MASTER_TABLE_PHASE_I
GROUP BY EMP_SYSTEM_NUMBER) AS T2
ON (T1.EMP_SYSTEM_NUMBER = T2.EMP_SYSTEM_NUMBER AND T1.IMP_CREATE_DATE = T2.MaxDate)
)
SELECT #myXML=
(
SELECT
(
SELECT
'Upsert' AS [#action]
,'Skip' AS [#invalidLookupBehavior]
,(
SELECT
'EMPLOYEE' AS [Table/#name]
,(
SELECT
'COMPANY_ID' AS [Field/#name]
,'False' AS [Field/#lookupValue]
,84 AS [Field]
,''
,'LAST_NAME' AS [Field/#name]
,EMP_LAST_NAME AS [Field]
,''
,'MIDDLE_NAME' AS [Field/#name]
,EMP_MIDDLE_NAME AS [Field]
,''
,'FIRST_NAME' AS [Field/#name]
,EMP_FIRST_NAME AS [Field]
,''
,'PREFIX' AS [Field/#name]
,'True' AS [Field/#lookupValue]
,EMP_PREFIX AS [Field]
,''
,'PREFERRED_NAME' AS [Field/#name]
,EMP_PREFERRED_NAME AS [Field]
,''
,'FORMER_NAME' AS [Field/#name]
,EMP_FORMER_NAME AS [Field]
,''
,'SYSTEM_NUMBER' AS [Field/#name]
,'True' AS [Field/#recordIdentifier]
,EMP_SYSTEM_NUMBER AS [Field]
FOR XML PATH(''),TYPE
) AS [Fields]
FOR XML PATH('Tables'),TYPE
)
FROM CTE_instead_of_TempTable
FOR XML PATH('Command'),TYPE
)
FOR XML PATH('Commands'),ROOT('DataChange'),TYPE
)
SELECT #myXML;

Importing XML data with a namespace into SQL Server

I have an XML document containing data that I want to import into existing SQL server tables:
<?xml version="1.0" encoding="UTF-8"?>
<geia:GEIA-STD-0007 xmlns:geia="http://www.geia_STD_0007.com/2006/schema" xmlns:xsi=`enter code here`"http://www.w3.org/2001/XMLSchema-instance">
<geia:full_file>
<geia:XA_end_item_acronym_code_data>
<geia:end_item_acronym_code>ON565</geia:end_item_acronym_code>
<geia:logistics_support_analysis_control_number_structure>32222222</geia:logistics_support_analysis_control_number_structure>
</geia:XA_end_item_acronym_code_data>
<geia:XB_logistics_support_analysis_control_number_indentured_item_data>
<geia:end_item_acronym_code>ON565</geia:end_item_acronym_code>
<geia:logistics_support_analysis_control_number>E2C06CAAE</geia:logistics_support_analysis_control_number>
<geia:alternate_logistics_support_analysis_control_number_code>06</geia:alternate_logistics_support_analysis_control_number_code>
<geia:logistics_support_analysis_control_number_type>P</geia:logistics_support_analysis_control_number_type>
<geia:logistics_support_analysis_control_number_nomenclature>CABLE ASSEMBLY W5</geia:logistics_support_analysis_control_number_nomenclature>
<geia:reliability_availability_and_maintainability_indicator>Y</geia:reliability_availability_and_maintainability_indicator>
<geia:system_end_item_identifier>N</geia:system_end_item_identifier>
<geia:technical_manual_functional_group_code>41JE150</geia:technical_manual_functional_group_code>
</geia:XB_logistics_support_analysis_control_number_indentured_item_data>
<geia:XB_logistics_support_analysis_control_number_indentured_item_data>
<geia:end_item_acronym_code>ON565</geia:end_item_acronym_code>
<geia:logistics_support_analysis_control_number>E2C06CAAMZZ</geia:logistics_support_analysis_control_number>
<geia:alternate_logistics_support_analysis_control_number_code>06</geia:alternate_logistics_support_analysis_control_number_code>
<geia:logistics_support_analysis_control_number_type>P</geia:logistics_support_analysis_control_number_type>
<geia:logistics_support_analysis_control_number_nomenclature>CONSUMABLES</geia:logistics_support_analysis_control_number_nomenclature>
<geia:system_end_item_identifier>N</geia:system_end_item_identifier>
</geia:XB_logistics_support_analysis_control_number_indentured_item_data>
</geia:full_file>
</geia:GEIA-STD-0007>
I have been looking online for code that can help me accomplish this task but have not had much luck. So far this is the code I have been trying to use:
----step 1 Import XML data from an XML file into SQL Server table using the OPENROWSET function
drop table lsa.XMLwithOpenXML
CREATE TABLE lsa.XMLwithOpenXML
(
Id INT IDENTITY PRIMARY KEY,
XMLData XML,
LoadedDateTime DATETIME
)
INSERT INTO lsa.XMLwithOpenXML(XMLData, LoadedDateTime)
SELECT CONVERT(XML, BulkColumn) AS BulkColumn, GETDATE()
FROM OPENROWSET(BULK 'D:\Temp\e2c.xml', SINGLE_CLOB) AS x;
--SELECT * FROM lsa.XMLwithOpenXML
--get xmldata to shred
-------------------------------------------------------------------------
Declare #xmlData as xml
Select #xmlData = XMLData FROM lsa.XMLwithOpenXML
------------------------------------------------------------
--create variable to hold the int id of the xmldoc created by the sp
DECLARE #XMLdocId AS INT
--procedureName, outputId, InputData
EXEC sp_xml_preparedocument #XMLdocId OUTPUT, #xmlData , '<geia:GEIA-STD-0007 xmlns:geia="http://www.geia_STD_0007.com/2006/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
--create an OenXML query to shred the doc, or transfer it into rowsets
INSERT INTO [lsa].[XB]
(
[end_item_acronym_code])
Select end_item_acronym_code from
OpenXML(#XMLdocId, '/geia:XB_logistics_support_analysis_control_number_indentured_item_data',2)
;WITH XMLNAMESPACES ('xmlns:geia="http://www.geia_STD_0007.com/2006/schema' AS geia, DEFAULT 'http://www.w3.org/2001/XMLSchema-instance' )
SELECT
x.c( '.' ) AS result
FROM #xmlData.nodes('geia:GEIA-STD-0007/geia:full_file/geia:XB_logistics_support_analysis_control_number_indentured_item_data') x(c)
EXEC sp_xml_removedocument #XMLdocId
I realize that this code is very wrong. The path that I am passing to the OpenXML() function is wrong, but I have tried many iterations of it and none have been successful. I am also not 100% certain how to go about pulling out the different table data (ie XA, XB) but my plan is to pull from one table then reiterate the code for each additional table. This code will be used to import large amounts of data (I only posted a part of the xml file) with many different tables. If anyone has a better idea, then I would welcome it, as I am still learning.

need help regarding querying xml in sql server

i have two table in sql server 2005. in one table table1 there is one column whose data type is xml where we save data in xml format. now i have another table table2 where we store few fileds name. so now i want to write query in such a on xml data which will return those fields value which are defined in table2. how to achieve it with simple sql statement instead of store procedure.
my xml structure and data like below one
<Record xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DELETED>
<JID>41185</JID>
<WID>0</WID>
<AccountReference>LH169</AccountReference>
<OEReference>Ari002</OEReference>
<InvoiceNumber>0</InvoiceNumber>
<OrderPlacedBy>Mark Catterall</OrderPlacedBy>
<Specialist>0FFICINA MOTTAUTO</Specialist>
<Priority>2</Priority>
<JobType>OUR</JobType>
<JobState>NOTSTARTED</JobState>
<JobAddedDate>2011-05-31T16:17:00</JobAddedDate>
<JobStartedDate>2011-05-31T16:18:00</JobStartedDate>
<JobFinishedDate>1777-01-01T00:00:01</JobFinishedDate>
<JobShippedDate>1777-01-01T00:00:01</JobShippedDate>
<RecievedDate>1777-01-01T00:00:01</RecievedDate>
<UPSShippingNumber />
<CustomerName>02 IRELAND</CustomerName>
<ContactName>ALAN CONLAN</ContactName>
<Telephone>00353868377926</Telephone>
<StandardHours>3.00</StandardHours>
<JobDescription>test for search 2</JobDescription>
<UserName xsi:nil="true" />
<AwaitingCustomer>0</AwaitingCustomer>
<ReturnToCore>0</ReturnToCore>
<AwaitingFromSalvage>0</AwaitingFromSalvage>
<PartDescription>test for search 2</PartDescription>
<PostalCode>IRELAND</PostalCode>
<OURPrice xsi:nil="true" />
<ExchangePrice xsi:nil="true" />
<NewPrice xsi:nil="true" />
<eBayPrice xsi:nil="true" />
<Status>UPDATED</Status>
</DELETED>
</Record>
suppose in my table2 few fields are stored like
JID,WID,AccountReference,OEReference,InvoiceNumber.
so please guide me how to write sql on xml data which will return only JID,WID,AccountReference,OEReference,InvoiceNumber from xml data but filed name will not be hard coded rather it will be fetch from another table table2.
please guide me.
To read data from xml you can use like this:
Select
MyXmlColumn.value('(Record/DELETED/JID)[1]', 'int' ) as JID,
MyXmlColumn.value('(Record/DELETED/WID)[1]', 'int' ) as WID,
MyXmlColumn.value('(Record/DELETED/AccountReference)[1]', 'nvarchar(255)' ) as AccountReference from table2
[update]
create a stored procedure with your parameters:
create procedure getmyxmldata
(
#param1 varchar(50),
#param2 varchar(50)
)
as
begin
declare #myQuery varchar(1000);
set #myQuery = 'Select
MyXmlColumn.value(''(Record/DELETED/' + #param1 + ')[1]'', ''nvarchar(255)'' ) as ' + #param1 + ',
MyXmlColumn.value(''(Record/DELETED/' + #param1 + ')[1]'', ''nvarchar(255)'' ) as ' + #param1 + ' from table2';
EXEC sp_executesql #myQuery
end
It is also possible to read the specified fields from the other table in this stored procedure and create your select statement dynamically without passing parameters.
[Update 2]
you can try this for multiple deleted tags:
Select
Row.value('(./JID)[1]', 'int' ) as JID,
Row.value('(./WID)[1]', 'int' ) as WID,
Row.value('(./AccountReference)[1]', 'nvarchar(255)' ) as AccountReference
from table2
CROSS APPLY MyXmlColumn.nodes('/Record/DELETED') as Record(Row)