I tried to fetch an element from an XML in stored procedure as follows
USE [ION]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[AddToCustomer]
(#id VARCHAR(20))
AS
BEGIN
DECLARE #xx xml
DECLARE #custname varchar(8000)
DECLARE #fid varchar(20)
SET NOCOUNT ON;
SELECT #fid=[C_ID], #xx=cast([C_XML] as xml) FROM [ION].[dbo].[COR_INBOX_ENTRY] WHERE [C_WAS_PROCESSED]=0 and [C_ID]=#id
if(##ROWCOUNT!=0)
BEGIN
SELECT #xx.value('(/SyncMESCustomer/ApplicationArea/Sender/ConfirmationCode)[1]', 'varchar(100)')
END
END
I am pretty sure that the variable #xx is loaded with the xml. I need to select the value of '/SyncMESCustomer/ApplicationArea/Sender/ConfirmationCode' but its returning a NULL.
Sample xml is as follows
<SyncMESCustomer xmlns="http://schema.infor.com/InforOAGIS/2" xmlns:xs="http://www.w3.org/2001/XMLSchema" languageCode="GB" releaseID="9.2" systemEnvironmentCode="Production" versionID="2.9.1">
<ApplicationArea>
<Sender>
<LogicalID schemeVersionID="15.4.0.0">lid://infor.m3be.ipc_mec_dev</LogicalID>
<ComponentID schemeVersionID="MCP2-1514-02">M3BE</ComponentID>
<ConfirmationCode>OnError</ConfirmationCode>
</Sender>
<CreationDateTime>2017-06-09T13:41:36.996Z</CreationDateTime>
<BODID>5cfa6949-11ef-41dc-a380-4cc79f2687cc</BODID>
</ApplicationArea>
<DataArea>
<Sync>
<TenantID>TEST</TenantID>
<AccountingEntityID>1_001</AccountingEntityID>
<ActionCriteria>
<ActionExpression actionCode="Replace" />
</ActionCriteria>
</Sync>
<MESCustomer>
<CUSTOMER_NO>TEST6</CUSTOMER_NO>
<ipc_CSS_CUST_CUST_NAME>
<CUSTOMER_NO>TEST6</CUSTOMER_NO>
<CUST_NAME>Hawaii Inc_MES</CUST_NAME>
<STATUS_DATE>20170609</STATUS_DATE>
<STATUS_WORD>20</STATUS_WORD>
</ipc_CSS_CUST_CUST_NAME>
<STATUS_WORD>20</STATUS_WORD>
</MESCustomer>
</DataArea>
</SyncMESCustomer>
Thanks in advance.
;WITH XMLNAMESPACES(DEFAULT 'http://schema.infor.com/InforOAGIS/2','http://www.w3.org/2001/XMLSchema' as ns0)
Select #XML.value('SyncMESCustomer[1]/ApplicationArea[1]/Sender[1]/ConfirmationCode[1]','varchar(100)')
Returns
OnError
This works for me... you can add another alias to your namespace...
<SyncMESCustomer xmlns:xz="http://schema.infor.com/InforOAGIS/2" xmlns:xs="http://www.w3.org/2001/XMLSchema" languageCode="GB" releaseID="9.2" systemEnvironmentCode="Production" versionID="2.9.1"
DECLARE #xx XML
SET #xx = '<SyncMESCustomer>
<ApplicationArea>
<Sender>
<LogicalID schemeVersionID="15.4.0.0">lid://infor.m3be.ipc_mec_dev</LogicalID>
<ComponentID schemeVersionID="MCP2-1514-02">M3BE</ComponentID>
<ConfirmationCode>OnError</ConfirmationCode>
</Sender>
<CreationDateTime>2017-06-09T13:41:36.996Z</CreationDateTime>
<BODID>5cfa6949-11ef-41dc-a380-4cc79f2687cc</BODID>
</ApplicationArea>
<DataArea>
<Sync>
<TenantID>TEST</TenantID>
<AccountingEntityID>1_001</AccountingEntityID>
<ActionCriteria>
<ActionExpression actionCode="Replace" />
</ActionCriteria>
</Sync>
<MESCustomer>
<CUSTOMER_NO>TEST6</CUSTOMER_NO>
<ipc_CSS_CUST_CUST_NAME>
<CUSTOMER_NO>TEST6</CUSTOMER_NO>
<CUST_NAME>Hawaii Inc_MES</CUST_NAME>
<STATUS_DATE>20170609</STATUS_DATE>
<STATUS_WORD>20</STATUS_WORD>
</ipc_CSS_CUST_CUST_NAME>
<STATUS_WORD>20</STATUS_WORD>
</MESCustomer>
</DataArea>
</SyncMESCustomer>'
SELECT
xmlData.A.value('./ConfirmationCode[1]', 'varchar(100)')
FROM #xx.nodes('/SyncMESCustomer/ApplicationArea/Sender') xmlData(A);
Related
I've got problem with parsing informations from XML into SQL with double namespace.
Have a look at this code:
DECLARE #Handle AS INT; -- The handle of the XML data, passed to sp_xml_preparedocument
DECLARE #Xml AS NVARCHAR(1000); -- The XML document for this example
SET #Xml = N'
<SiBikNet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://www.ws.bik.pl/ws/ki/2v2/types">
<BIK_REQUEST>
<siBikNetResponse>
<consentDate>2018-07-29</consentDate>
<citizenshipStatus>citizen</citizenshipStatus>
<nationality>PL</nationality>
<pesel>123</pesel>
</siBikNetResponse>
</BIK_REQUEST>
</SiBikNet>';
EXEC sys.sp_xml_preparedocument #Handle OUTPUT , #Xml, N'<SiBikNet xmlns:t="https://www.ws.bik.pl/ws/ki/2v2/types"/>'; --Prepare a parsed document
SELECT *
FROM
OPENXML(#Handle,'/t:SiBikNet/t:BIK_REQUEST/t:siBikNetResponse', 2)
WITH ( nationality NVARCHAR(10) 't:nationality',
pesel NVARCHAR(10) 't:pesel '
);
EXEC sys.sp_xml_removedocument #Handle;
Which gives me proper output in forms of table with 2 columns.
But when I will add one row with double namespace: then I cannot parse this informations :
DECLARE #Handle AS INT; -- The handle of the XML data, passed to sp_xml_preparedocument
DECLARE #Xml AS NVARCHAR(1000); -- The XML document for this example
SET #Xml = N'
<SiBikNet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://www.ws.bik.pl/ws/ki/2v2/types">
<BIK_REQUEST xmlns="">
<siBikNetResponse>
<consentDate>2018-07-29</consentDate>
<citizenshipStatus>citizen</citizenshipStatus>
<nationality>PL</nationality>
<pesel>123</pesel>
</siBikNetResponse>
</BIK_REQUEST>
</SiBikNet>';
EXEC sys.sp_xml_preparedocument #Handle OUTPUT , #Xml, N'<SiBikNet xmlns:t="https://www.ws.bik.pl/ws/ki/2v2/types"/>'; --Prepare a parsed document
SELECT *
FROM
OPENXML(#Handle,'/t:SiBikNet/t:BIK_REQUEST/t:siBikNetResponse', 2)
WITH ( nationality NVARCHAR(10) 't:nationality',
pesel NVARCHAR(10) 't:pesel '
);
EXEC sys.sp_xml_removedocument #Handle;
Can anyone help ?
When I get stuck with anonymous namespaces or oddball namespace combinations, the simplest way is to just use the XPath function local-name(). Like this:
DECLARE #Handle AS INT; -- The handle of the XML data, passed to sp_xml_preparedocument
DECLARE #Xml AS NVARCHAR(1000); -- The XML document for this example
SET #Xml = N'
<SiBikNet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://www.ws.bik.pl/ws/ki/2v2/types">
<BIK_REQUEST xmlns="">
<siBikNetResponse>
<consentDate>2018-07-29</consentDate>
<citizenshipStatus>citizen</citizenshipStatus>
<nationality>PL</nationality>
<pesel>98070902702</pesel>
</siBikNetResponse>
</BIK_REQUEST>
</SiBikNet>';
EXEC sys.sp_xml_preparedocument #Handle OUTPUT , #Xml, N'<SiBikNet xmlns:t="https://www.ws.bik.pl/ws/ki/2v2/types"/>'; --Prepare a parsed document
SELECT *
FROM
OPENXML(#Handle,'/*[local-name()="SiBikNet"]/*[local-name()="BIK_REQUEST"]/*[local-name()="siBikNetResponse"]', 2)
WITH ( nationality NVARCHAR(10) ,--'t:nationality',
pesel NVARCHAR(10) --'t:pesel '
);
EXEC sys.sp_xml_removedocument #Handle;
I am having xml as result for webservice api . i need to parse the result and update to database table. my xml is below . it is a response text.
<?xml version="1.0" encoding="utf-8"?>
<double>1</double>
Sqlserver 2008 Code :
declare #xml xml, #rate DECIMAL(10,4)
set #xml=REPLACE(#ResponseText ,'encoding="utf-8"','')
select #rate= #xml.value('(/double)[1]','decimal')
I want to get the value of double but it always return the null .
Please help me out .
Hi , have Done changes as per your suggestion still no getting.
declare #xml XML
DECLARE #responsetext VARCHAR(900)
declare #rate DECIMAL(10,4)
SET #responsetext = '<?xml version="1.0" encoding="utf-8"?>
<double xmlns="http://www.webserviceX.NET/">1</double>'
set #xml=REPLACE(#ResponseText ,'encoding="utf-8"','')
select #rate= #xml.value('(/double)[1]','decimal')
select #rate
You need to declare the namespace when querying using the value() Method.
Change the first parameter of value() from
'(/double)[1]'
to
'declare namespace x="http://www.webserviceX.NET/"; (/x:double)[1]'
So the full example will look like this
declare #xml XML
DECLARE #responsetext VARCHAR(900)
declare #rate DECIMAL(10,4)
SET #responsetext = '<?xml version="1.0" encoding="utf-8"?>
<double xmlns="http://www.webserviceX.NET/">1</double>'
set #xml=REPLACE(#ResponseText ,'encoding="utf-8"','')
select #rate= #xml.value('declare namespace x="http://www.webserviceX.NET/"; (/x:double)[1]','decimal')
select #rate
which should return 1.000 (decimal)
DECLARE #X XML = '<?xml version="1.0" encoding="utf-8"?>
<double xmlns="http://www.webserviceX.NET/">1</double>'
SELECT #X.value ('declare namespace x="http://www.webserviceX.NET/"; (/x:double)[1]', 'decimal')
Updated to reflect your use of namespace; the general point is that you don't need to do string manipulation to make this work. The header is fully supported. However, namespaces are important.
Not an answer, just some sample code - this returns a 1, not a NULL:
declare #xml xml, #rate DECIMAL(10,4)
declare #ResponseText varchar(900)
set #ResponseText = '<?xml version="1.0" encoding="utf-8"?> <double>1</double>'
set #xml=REPLACE(#ResponseText ,'encoding="utf-8"','')
select #rate= #xml.value('(/double)[1]','decimal')
select #rate
I have a xml column that look like
SET #XMLData = '<ArrayOfEntityNested xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/Gbms.Dto.Bijak">
<EntityNested>
<Id xmlns="http://schemas.datacontract.org/2004/07/Gbms.Dto">1</Id>
<Date xmlns="http://schemas.datacontract.org/2004/07/Gbms.Dto.VirginBijak">0001-01-01T00:00:00</Date>
<Description xmlns="http://schemas.datacontract.org/2004/07/Gbms.Dto.VirginBijak">deesc</Description>
<Number xmlns="http://schemas.datacontract.org/2004/07/Gbms.Dto.VirginBijak" i:nil="true" />
</EntityNested>
</ArrayOfEntityNested>'
I need insert data from the XML into a temp table.
here
For this I use from following code. But it's not working, and it's not inserting any data into temp table.
--Variables Decleration
DECLARE #XMLData VARCHAR(MAX)
DECLARE #idoc INT
-- Creating Temporary Table
CREATE TABLE #TEMP_TABLE
(
REC_ID INT IDENTITY(1,1),
[Id] INT,
[Date] VARCHAR(50),
[Number] VARCHAR(50),
);
--Case 1
SET #XMLData = '<ArrayOfEntityNested xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/Gbms.Dto.Bijak">
<EntityNested>
<Id xmlns="http://schemas.datacontract.org/2004/07/Gbms.Dto">1</Id>
<Date xmlns="http://schemas.datacontract.org/2004/07/Gbms.Dto.VirginBijak">0001-01-01T00:00:00</Date>
<Number xmlns="http://schemas.datacontract.org/2004/07/Gbms.Dto.VirginBijak" i:nil="true" />
</EntityNested>
</ArrayOfEntityNested>
'
--Reading Data from XML and inserting into Temp Table
EXECUTE sp_xml_preparedocument #idoc OUTPUT, #XMLData
INSERT INTO #TEMP_TABLE
SELECT *
FROM OpenXML(#idoc,'/ArrayOfEntityNested/EntityNested', 1)
WITH #TEMP_TABLE
EXECUTE sp_xml_removedocument #idoc
--Displaying data from Temp Table
SELECT * FROM #TEMP_TABLE
DROP TABLE #TEMP_TABLE;
But that doesn't work, if xml format correct might look like :
SET #XMLData = '<ArrayOfEntityNested>
<EntityNested>
<Id>1</Id>
<Date>0001-01-01T00:00:00</Date>
<Description>deesc</Description>
<EmployeeId>2</EmployeeId>
<IsDeleted>false</IsDeleted>
<LoadingPermitTruckId>7541</LoadingPermitTruckId>
</EntityNested>
</ArrayOfEntityNested>'
then it works.
Please help me.
First of all - please use appropriate data types! If your source data is XML - why aren't you using the XML datatype?
Also, if you have a Date in your table - why isn't that a DATE or DATETIME type?? And why is the Number a VARCHAR(50) ??
Makes no sense......
Then: you're not looking at the XML namespaces that are present in the XML document - but you must!
At lastly - I would recommend using the native XQuery support instead of the legacy, deprecated sp_xml_preparedocument / OpenXML approach....
Seems much easier, much clearer to me...
Use this:
-- variable declaration
DECLARE #XMLData XML
-- creating temporary table
CREATE TABLE #TEMP_TABLE
(
REC_ID INT IDENTITY(1,1),
[Id] INT,
[Date] DATETIME2(3),
[Number] INT
);
and then use proper XQuery statements, including the XML namespaces to handle the data:
SET #XMLData = '<ArrayOfEntityNested xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/Gbms.Dto.Bijak">
<EntityNested>
<Id xmlns="http://schemas.datacontract.org/2004/07/Gbms.Dto">1</Id>
<Date xmlns="http://schemas.datacontract.org/2004/07/Gbms.Dto.VirginBijak">0001-01-01T00:00:00</Date>
<Number xmlns="http://schemas.datacontract.org/2004/07/Gbms.Dto.VirginBijak" i:nil="true" />
</EntityNested>
<EntityNested>
<Id xmlns="http://schemas.datacontract.org/2004/07/Gbms.Dto">42</Id>
<Date xmlns="http://schemas.datacontract.org/2004/07/Gbms.Dto.VirginBijak">2013-12-22T14:45:00</Date>
<Number xmlns="http://schemas.datacontract.org/2004/07/Gbms.Dto.VirginBijak">373</Number>
</EntityNested>
</ArrayOfEntityNested>'
;WITH XMLNAMESPACES ('http://schemas.datacontract.org/2004/07/Gbms.Dto.Bijak' AS ns1,
'http://schemas.datacontract.org/2004/07/Gbms.Dto' AS ns2,
'http://schemas.datacontract.org/2004/07/Gbms.Dto.VirginBijak' AS ns3)
INSERT INTO #TEMP_TABLE(ID, Date, Number)
SELECT
xc.value('(ns2:Id)[1]', 'int'),
xc.value('(ns3:Date)[1]', 'DateTime2'),
xc.value('(ns3:Number)[1]', 'int')
FROM
#XmlData.nodes('/ns1:ArrayOfEntityNested/ns1:EntityNested') AS xt(xc)
DECLARE #idoc int
DECLARE #doc varchar(1000)
SET #doc ='
<OutLookContact>
<Contact FirstName="Asif" LastName="Ghafoor" EmailAddress1="asifghafoor#my.web.pk" />
<Contact FirstName="Rameez" LastName="Ali" EmailAddress1="rameezali#my.web.pk" />
</OutLookContact>'
--Create an internal representation of the XML document.
EXEC sp_xml_preparedocument #idoc OUTPUT, #doc
-- Execute a SELECT statement that uses the OPENXML rowset provider.
DECLARE #Temp TABLE(FirstName VARCHAR(250),LastName VARCHAR(250),Email1 VARCHAR(250))
INSERT INTO #Temp(FirstName,LastName,Email1)
SELECT *
FROM OPENXML (#idoc, '/OutLookContact/Contact',1)
WITH (FirstName varchar(50),LastName varchar(50),EmailAddress1 varchar(50))
select FirstName,LastName,Email1 from #Temp
it will be a lot easier if you try to use a tool called pentaho. http://en.wikipedia.org/wiki/Pentaho
it is an open source tool which is used for data integration.you can create a database connection from mysql or oracle to it and do the transformation.it is easy to use.
I'm getting an error when executing this in SQL Server 2005, But works if I remove the namespaces from the root node :
DECLARE #XmlDocumentHandle int
DECLARE #XmlDocument nvarchar(1000)
SET #XmlDocument = N'<ROOT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema>
<Customer>
<ID>VINET</ID>
<Name>Paul Henriot</Name>
<Order OrderID="10248" CustomerID="VINET" EmployeeID="5" OrderDate="1996-07-04T00:00:00">
<OrderDetail ProductID="11" Quantity="12"/>
<OrderDetail ProductID="42" Quantity="10"/>
</Order>
</Customer>
<Customer>
<ID>LILAS</ID>
<Name>Carlos Gonzlez</Name>
<Order OrderID="10283" CustomerID="LILAS" EmployeeID="3" OrderDate="1996-08-16T00:00:00">
<OrderDetail ProductID="72" Quantity="3"/>
</Order>
</Customer>
</ROOT>'
-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument #XmlDocumentHandle OUTPUT, #XmlDocument
-- Execute a SELECT statement using OPENXML rowset provider.
SELECT *
FROM OPENXML (#XmlDocumentHandle, '/ROOT/Customer',2)
WITH (CustomerID varchar(10) 'ID',
ContactName varchar(20) 'Name')
EXEC sp_xml_removedocument #XmlDocumentHandle
You are just missing a double quote at the end of the first line of xml:
SET #XmlDocument = N'<ROOT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
(the 2nd-to-last char)
I am able to run your query ok on SQL 2008 after making this change.
John
Suppose I have a query like this -
SELECT * FROM
OPENXML(#i, '/root/authors', 2)
WITH authors
Now, I want to pass '/root' via a parameter/variable like -
DECLARE #nodeName varchar(MAX) ----> EDIT: Solution- Use fixed length instead of MAX
SET #nodeName = '/root'
and use #nodeName instead. Then concatenate the rest of the elements dynamically.
I am getting error just by using #nodeName in the OPENXML parameter.
Better to use the new XML type.
create proc [dbo].[getLocationTypes](#locationIds XML,
#typeIds XML=null)
as
begin
set nocount on
SELECT locationId, typeId
FROM xrefLocationTypes
WHERE locationId
IN (SELECT Item.value('.', 'int' )
FROM #locationIDs.nodes('IDList/ID') AS x(Item))
AND (typeId IN
(SELECT Item.value('.', 'int' )
FROM #typeIds.nodes('IDList/ID') AS x(Item)))
ORDER BY 1, 2
end
And then you would call this like:
EXECUTE dbo.getLocationTypes '<IDList><ID>1</ID><ID>3</ID></IDList>',
'<IDList><ID>200</ID><ID>300</ID><ID>400</ID></IDList>'
I tried the following in SQL 2008 R2 and it works fine.
DECLARE #idoc int
DECLARE #doc varchar(1000)
SET #doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
<Order CustomerID="VINET" EmployeeID="5" OrderDate="1996-07-04T00:00:00">
<OrderDetail OrderID="10248" ProductID="11" Quantity="12"/>
<OrderDetail OrderID="10248" ProductID="42" Quantity="10"/>
</Order>
</Customer>
<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">
<Order CustomerID="LILAS" EmployeeID="3" OrderDate="1996-08-16T00:00:00">
<OrderDetail OrderID="10283" ProductID="72" Quantity="3"/>
</Order>
</Customer>
</ROOT>'
--Create an internal representation of the XML document.
EXEC sp_xml_preparedocument #idoc OUTPUT, #doc
-- Execute a SELECT statement that uses the OPENXML rowset provider.
DECLARE #NodeName VARCHAR(100)
SET #NodeName = '/ROOT/Customer'
SELECT *
FROM OPENXML (#idoc, #NodeName,1)
WITH (CustomerID varchar(10),
ContactName varchar(20))
It could be that other versions of SQL only support the use of NVARCHAR as a parameter, not VARCHAR.
I hope this help.