I'm having trouble extracting some data from a XML file to MSSQL DB using CROSS APPLY, here is what I have:
Note: I did read about how to post here but pardon me if I'm still wrong.
XML File:
<?xml version="1.0" encoding="UTF-8" ?>
<ZMPROD01>
<IDOC BEGIN="1">
<EDI_DC40 SEGMENT="1">
<TABNAM>EDI_DC40</TABNAM>
<DOCNUM>0000003899888135</DOCNUM>
<CREDAT>20220201</CREDAT>
<CRETIM>152041</CRETIM>
</EDI_DC40>
<ZPROD SEGMENT="1">
<WERKS>8285</WERKS>
<LGNUM>0</LGNUM>
<AUFNR>000915229446</AUFNR>
<LINENO>RM01PL01</LINENO>
<CHARG>0006186588</CHARG>
<START1>20220202</START1>
<START2>211609</START2>
<QTY>4166.000</QTY>
<END1>20220202</END1>
<END2>240000</END2>
<MAKTX>579 FUS5 75ML ULTRA SENST GEL</MAKTX>
<PLN_ORDER>6963701111</PLN_ORDER>
<Z1PRODI SEGMENT="1">
<POSNR>000010</POSNR>
<MATNR>000000000098920665</MATNR>
</Z1PRODI>
<Z1PRODI SEGMENT="1">
<POSNR>000040</POSNR>
<HRKFT>V010</HRKFT>
</Z1PRODI>
<Z1PRODI SEGMENT="1">
<POSNR>000050</POSNR>
<MATNR>000000000099396964</MATNR>
</Z1PRODI>
</ZPROD>
</IDOC>
</ZMPROD01>
My SQL query:
INSERT INTO XMLTESTTABLE(PONo, ASP, LOTNo, EntryDate, StartDate, EndDate, GAS, PlannedQty, LineNum, SAPDesc, StartTime, EndTime)
SELECT
MY_XML.ZPROD.query('AUFNR').value('.', 'VARCHAR(9)'),
MY_XML.ZPROD.query('CHARG').value('.', 'VARCHAR(8)'),
MY_XML.ZPROD.query('PLN_ORDER').value('.', 'VARCHAR(10)'),
MY_XML.ZPROD.query('START1').value('.', 'date'),
MY_XML.ZPROD.query('START1').value('.', 'date'),
MY_XML.ZPROD.query('END1').value('.', 'date'),
MY_XML.ZPROD.query('CHARG').value('.', 'VARCHAR(8)'),
MY_XML.ZPROD.query('QTY').value('.', 'VARCHAR(9)'),
MY_XML.ZPROD.query('LINENO').value('.', 'VARCHAR(1)'),
MY_XML.ZPROD.query('MAKTX').value('.', 'VARCHAR(9)'),
MY_XML.ZPROD.query('START2').value('.', 'time'),
MY_XML.ZPROD.query('END2').value('.', 'time')
FROM (SELECT CAST(MY_XML AS xml)
FROM OPENROWSET(BULK 'C:\Users\PC_user\Documents\Idoc3899888135.xml', SINGLE_BLOB) AS T(MY_XML)) AS T(MY_XML)
CROSS APPLY MY_XML.nodes('ZMPROD01/ZPROD') AS MY_XML (ZPROD);
The result I get is (0 rows affected). I tried replacing ZMPROD01/ZPROD several times but different errors appeared, at some point complained about being unable to convert to date datatype.
On a separate note how, can I get data from EDI_DC40 as well? Not sure how the CROSS APPLY would look like to look for different places on the document.
Your help is appreciated.
Thanks.
Please try the following solution.
Notable points:
I adjusted the XPath expression in the .nodes() method.
No need to use the .query() method.
text() is added for performance reasons.
Last two data elements converted into TIME data type.
As it was already mentioned, the <END2>240000</END2> is not a legit
value for the TIME data type.
SQL
--INSERT INTO XMLTESTTABLE(PONo, ASP, LOTNo, EntryDate, StartDate, EndDate, GAS, PlannedQty, LineNum, SAPDesc, StartTime, EndTime)
SELECT ZPROD.value('(AUFNR/text())[1]', 'VARCHAR(9)')
, ZPROD.value('(CHARG/text())[1]', 'VARCHAR(8)')
, ZPROD.value('(PLN_ORDER/text())[1]', 'VARCHAR(10)')
, ZPROD.value('(START1/text())[1]', 'date')
, ZPROD.value('(START1/text())[1]', 'date')
, ZPROD.value('(END1/text())[1]', 'date')
, ZPROD.value('(CHARG/text())[1]', 'VARCHAR(8)')
, ZPROD.value('(QTY/text())[1]', 'VARCHAR(9)')
, ZPROD.value('(LINENO/text())[1]', 'VARCHAR(1)')
, ZPROD.value('(MAKTX/text())[1]', 'VARCHAR(9)')
, TRY_CAST(STUFF(STUFF(ZPROD.value('(START2/text())[1]', 'CHAR(6)'),3,0,':'),6,0,':') AS TIME)
, TRY_CAST(STUFF(STUFF(ZPROD.value('(END2/text())[1]', 'CHAR(6)'),3,0,':'),6,0,':') AS TIME)
FROM (SELECT CAST(MY_XML AS xml)
FROM OPENROWSET(BULK 'e:\Temp\Idoc3899888135.xml', SINGLE_BLOB) AS T(MY_XML)) AS T(MY_XML)
CROSS APPLY MY_XML.nodes('/ZMPROD01/IDOC/ZPROD') AS MY_XML (ZPROD);
Your path seems wrong - what about:
CROSS APPLY MY_XML.nodes('ZMPROD01/IDOC/ZPROD') AS MY_XML (ZPROD);
You seem to have forgotten the IDOC
And the data type is because you cannot convert the times to the data type time. Try starting with the select where everything is converted to varchar, then start changing the data tyoes, and you will find the errors
SELECT CAST('211609' AS TIME)
returns error
Related
I got this amazing code here on Stack but it was 8 years ago but works perfectly but, when run the t-script the column ObjectName always is NULL, someone can help me to fix it if possible?
The SQL Script
SELECT Pkg.props.value('../../DTS:Property[#DTS:Name="ObjectName"]
[1]','varchar(MAX)') ObjectName,
Pkg.props.value('(#SQLTask:SqlStatementSource)[1]', 'NVARCHAR(MAX)') AS
SqlStatement FROM (select cast(pkgblob.BulkColumn as XML) pkgXML from
openrowset(bulk '\\MYDTS.dtsx',single_blob)
as pkgblob) t CROSS APPLY pkgXML.nodes('//DTS:ObjectData//SQLTask:SqlTaskData') Pkg(props)
UNION
SELECT Pkg.props.value('../../../../DTS:Property[#DTS:Name="ObjectName"]
[1]','varchar(MAX)') ObjectName,
Pkg.props.value('data(./properties/property[#name=''SqlCommand''])[1]',
'varchar(max)') SqlStatement FROM(select cast(pkgblob.BulkColumn as XML)
pkgXML from openrowset(bulk '\\MYDTS.dtsx',single_blob) as
pkgblob) t CROSS APPLY
pkgXML.nodes('//DTS:Executable//pipeline//components//component') Pkg(props)
WHERE Pkg.props.value('data(./properties/property[#name=''SqlCommand''])
[1]', 'varchar(max)') <>''
And the result has been attached below. I would like to show the ObjectName instead NULL and I don't know how I can fix it.
ObjectName is no longer what/where it use to be from those years ago.
You'll need to browse the current dtsx in XML form and find your equivalent ObjectName.
SELECT CONVERT(XML, BulkColumn) AS BulkColumn FROM OPENROWSET(BULK 'C:\PathToPackage\MYDTS.dtsx', SINGLE_BLOB) AS x;
My sample dtsx looks like this in XML form:
<DTS:Executable xmlns:DTS="www.microsoft.com/SqlServer/Dts" DTS:refId="Package" DTS:CreationDate="7/23/2019 7:23:29 AM" DTS:CreationName="Microsoft.Package" DTS:CreatorComputerName="Overflow" DTS:CreatorName="Overflow\Stack" DTS:DTSID="{DEED1FFC-FCE3-4C63-A90C-3382EDA388A1}" DTS:ExecutableType="Microsoft.Package" DTS:LastModifiedProductVersion="14.0.3002.113" DTS:LocaleID="1033" DTS:ObjectName="deduplicate" DTS:PackageType="5" DTS:VersionBuild="20" DTS:VersionGUID="{27B38889-4D80-45F6-9CB0-F6B430B1DBBE}">
<DTS:Property DTS:Name="PackageFormatVersion">8</DTS:Property>
<DTS:Variables />
<DTS:Executables>
<DTS:Executable DTS:refId="Package\Execute SQL Task" DTS:CreationName="Microsoft.ExecuteSQLTask" DTS:Description="Execute SQL Task" DTS:DTSID="{A6053AE9-7445-4973-9AFD-E3AFFE97B68F}" DTS:ExecutableType="Microsoft.ExecuteSQLTask" DTS:LocaleID="-1" DTS:ObjectName="Execute SQL Task" DTS:TaskContact="Execute SQL Task; Microsoft Corporation; SQL Server 2017 RC1; © 2017 Microsoft Corporation; All Rights Reserved;http://www.microsoft.com/sql/support/default.asp;1" DTS:ThreadHint="1">
<DTS:Variables />
<DTS:ObjectData>
<SQLTask:SqlTaskData xmlns:SQLTask="www.microsoft.com/sqlserver/dts/tasks/sqltask" SQLTask:SqlStatementSource="Select GetDate()" />
</DTS:ObjectData>
</DTS:Executable>
...
In this specific XML, the next todos:
Pull out everything that is a SqlTaskData
Retrieve the SqlStatementSource value
Walk up two levels "../../" to DTS:Executable and Retrieve the ObjectName Attribute
WITH XMLNAMESPACES(
'www.microsoft.com/SqlServer/Dts' AS DTS,
'www.microsoft.com/sqlserver/dts/tasks/sqltask' AS SQLTask
),
dtsxAsXML AS (
SELECT CONVERT(XML, BulkColumn) AS BulkColumn
FROM OPENROWSET(BULK 'C:\PathToPackage\MYDTS.dtsx', SINGLE_BLOB) AS x
)
SELECT
X.Y.value('(../../#DTS:ObjectName)[1]', 'NVARCHAR(MAX)') AS ObjectName,
X.Y.value('(#SQLTask:SqlStatementSource)[1]', 'NVARCHAR(MAX)') AS SqlStatementSource
FROM dtsxAsXML d
CROSS APPLY d.BulkColumn.nodes('//DTS:ObjectData//SQLTask:SqlTaskData') X(Y)
ObjectName
SqlStatementSource
Execute SQL Task
Select GetDate()
Repeat this process for the dataflow component, the bottom union in your example.
Since you're already getting your SQL Statements, you don't need to use these example queries, you just need to review the xml from your dtsx, then find and change the relative paths in your existing query to the value you want.
I am struggling with importing XML Data into SQL Server 2016. I have tried a few things, but keep either getting errors or just no data is returned.
I have this XML Data stored in an XML file (limited the data because it is pretty sensitive:
<?xml version='1.0' encoding='UTF-8'?>
<wd:Report_Data xmlns:wd="urn:com.workday.report/Worker_Details_-_EXPORT_-_Workplace">
<wd:Report_Entry>
<wd:Active_Status>0</wd:Active_Status>
<wd:Legal_Name_-_First_Name>Charlotte</wd:Legal_Name_-_First_Name>
<wd:Position>Executive Housekeeper I</wd:Position>
<wd:Worker_Management_Level>Supervisor</wd:Worker_Management_Level>
<wd:continuous_service_date>1979-04-29-08:00</wd:continuous_service_date>
<wd:Hire_Date>1979-04-29-08:00</wd:Hire_Date>
<wd:termination_date>2019-12-22-08:00</wd:termination_date>
<wd:Anniversary_Month>04</wd:Anniversary_Month>
<wd:Years_of_Service>40</wd:Years_of_Service>
<wd:Employee_Type>Hotel</wd:Employee_Type>
<wd:Time_Type>Full Time</wd:Time_Type>
<wd:Pay_Rate_Type>Salary</wd:Pay_Rate_Type>
<wd:Marital_Status>Single</wd:Marital_Status>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Active_Status>0</wd:Active_Status>
<wd:Legal_Name_-_First_Name>Robert</wd:Legal_Name_-_First_Name>
<wd:Cost_Center_-_Name>Electronics</wd:Cost_Center_-_Name>
<wd:Work_Address_-_State_Province>Missouri</wd:Work_Address_-_State_Province>
<wd:Position>Manager Of Voice Networks</wd:Position>
<wd:Worker_Management_Level>Manager</wd:Worker_Management_Level>
<wd:continuous_service_date>1980-02-25-08:00</wd:continuous_service_date>
<wd:Hire_Date>1980-02-25-08:00</wd:Hire_Date>
<wd:termination_date>2020-03-22-07:00</wd:termination_date>
<wd:Anniversary_Month>02</wd:Anniversary_Month>
<wd:Years_of_Service>40</wd:Years_of_Service>
<wd:Employee_Type>Corporate</wd:Employee_Type>
<wd:Time_Type>Full Time</wd:Time_Type>
<wd:Pay_Rate_Type>Salary</wd:Pay_Rate_Type>
<wd:Marital_Status>Married</wd:Marital_Status>
</wd:Report_Entry>
</wd:Report_Data>
I have this code that I am trying to use, but keep getting just an empty result:
SELECT
XMLCol.ReportEntry.query('Active_Status').value('.', 'VARCHAR(20)') AS ActiveStatus
FROM
(SELECT
CAST(XMLCol AS XML)
FROM
OPENROWSET(BULK '\\afcn2011\root\DATA\VisualCron\Employee Export\EmployeeExport.xml', SINGLE_BLOB) AS T(XMLCol)
) AS T(XMLCol)
CROSS APPLY
XMLCol.nodes('Report_Data/Report_Entry') AS XMLCol(ReportEntry);
You need to respect and include the XML namespace defined in your document.
Try something like this:
-- define the namespace and give it a prefix - here "wd"
;WITH XMLNAMESPACES ('urn:com.workday.report/Worker_Details_-_EXPORT_-_Workplace' as wd)
SELECT
-- you need to include namespace prefix when referring to the XML element
-- also: is "VARCHAR(20)" really the best datatype?? Looks more like "INT" to me ...
XMLCol.ReportEntry.value('(wd:Active_Status/text())[1]', 'VARCHAR(20)') AS ActiveStatus
FROM
(SELECT
CAST(XMLCol AS XML)
FROM
OPENROWSET(BULK '\\afcn2011\root\DATA\VisualCron\Employee Export\EmployeeExport.xml', SINGLE_BLOB) AS T(XMLCol)
) AS T(XMLCol)
CROSS APPLY
-- you need to include namespace prefix in your XPath expression
XMLCol.nodes('/wd:Report_Data/wd:Report_Entry') AS XMLCol(ReportEntry);
I have the following XML file (I put here only a short scheme), it's a SEPA XML bank statement. I'm not familiar with parsing XML files, my next move will be inserting and comparing to data stored in the SQL databases for error checks. Sadly, I know what to do next, don't know how to make progress with my first step. All I need is to create a table to select values of 2 attributes from a file stored at a particular place
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
<GrpHdr>
..........
</GrpHdr>
<Stmt>
<Ntry>
<Amt Ccy="EUR">RequestedAmount1</Amt>
<AddtlNtryInf>RequestedInfo1</AddtlNtryInf>
</Ntry>
<Ntry>
<Amt Ccy="EUR">RequestedAmount2</Amt>
<AddtlNtryInf>RequestedInfo2</AddtlNtryInf>
</Ntry>
<Ntry>
<Amt Ccy="EUR">RequestedAmount3</Amt>
<AddtlNtryInf>RequestedInfo3</AddtlNtryInf>
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>
If the XML structure was simpler, for example like this...
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Ntry>
<Amt Ccy="EUR">RequestedAmount1</Amt>
<AddtlNtryInf>RequestedInfo1</AddtlNtryInf>
</Ntry>
<Ntry>
<Amt Ccy="EUR">RequestedAmount2</Amt>
<AddtlNtryInf>RequestedInfo2</AddtlNtryInf>
</Ntry>
<Ntry>
<Amt Ccy="EUR">RequestedAmount3</Amt>
<AddtlNtryInf>RequestedInfo3</AddtlNtryInf>
</Ntry>
...then I'd use this query to select requested attributes Amt and AddtlNtryInf and it works perfectly
SELECT
MY_XML.Ntry.query('Amt').value('.', 'NVARCHAR(255)') AS Amt,
MY_XML.Ntry.query('AddtlNtryInf').value('.', 'NVARCHAR(255)') AS AddtlNtryInf
FROM (SELECT CAST(MY_XML AS xml)
FROM OPENROWSET(BULK 'C:\tmp\TestSqlSimple.xml', SINGLE_BLOB) AS T(MY_XML)) AS T(MY_XML)
CROSS APPLY MY_XML.nodes('Ntry') AS MY_XML (Ntry);
But don't know how to deal with that more complicated one. I've tried something like this and several similar attempts but I failed because it doesn't select anything, the result is nothing
SELECT
MY_XML.Ntry.query('Amt').value('.', 'NVARCHAR(255)') AS Amt,
MY_XML.Ntry.query('AddtlNtryInf').value('.', 'NVARCHAR(255)') AS AddtlNtryInf
FROM (SELECT CAST(MY_XML AS xml)
FROM OPENROWSET(BULK 'C:\tmp\TestSqlSimple.xml', SINGLE_BLOB) AS T(MY_XML)) AS T(MY_XML)
CROSS APPLY MY_XML.nodes('/Document/BkToCstmrStmt/Stmt/Ntry') AS MY_XML (Ntry);
Can't figure out what to do with that CROSS APPLY. Thank you very much for any suggestions or improvements, you're doing a great job
You were almost there.
(1) The XML file has a default namespace, and it needs a special treatment via XMLNAMESPACES clause.
(2) The Amt element probably has a numeric value so you could use DECIMAL(x,y) data type. But I kept the NVARCHAR(255) to match the obfuscated XML file example.
(3) The SQL below is using .value() method without unnecessary .query() method.
(4) It is a good practice to use elementName/text() technique for performance reasons. It is MS SQL Server specific peculiarity.
SQL
-- DDL and sample data population, start
DECLARE #tbl TABLE (
ID INT IDENTITY PRIMARY KEY,
Amt NVARCHAR(255),
AddtlNtryInf NVARCHAR(255)
);
-- DDL and sample data population, end
;WITH XMLNAMESPACES (DEFAULT 'urn:iso:std:iso:20022:tech:xsd:camt.053.001.02')
, XmlFile (xmlData) AS
(
SELECT TRY_CAST(BulkColumn AS XML)
FROM OPENROWSET(BULK 'e:\Temp\TestSqlSimple.xml', CODEPAGE = '65001', SINGLE_BLOB) AS x
)
INSERT INTO #tbl (Amt, AddtlNtryInf)
SELECT c.value('(Amt/text())[1]', 'NVARCHAR(255)') AS Amt
, c.value('(AddtlNtryInf/text())[1]', 'NVARCHAR(255)') AS AddtlNtryInf
FROM XmlFile CROSS APPLY xmlData.nodes('/Document/BkToCstmrStmt/Stmt/Ntry') AS t(c);
-- test
SELECT * FROM #tbl;
Something like this:
declare #doc xml = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
<GrpHdr>
..........
</GrpHdr>
<Stmt>
<Ntry>
<Amt Ccy="EUR">RequestedAmount1</Amt>
<AddtlNtryInf>RequestedInfo1</AddtlNtryInf>
</Ntry>
<Ntry>
<Amt Ccy="EUR">RequestedAmount2</Amt>
<AddtlNtryInf>RequestedInfo2</AddtlNtryInf>
</Ntry>
<Ntry>
<Amt Ccy="EUR">RequestedAmount3</Amt>
<AddtlNtryInf>RequestedInfo3</AddtlNtryInf>
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>';
with xmlnamespaces (DEFAULT 'urn:iso:std:iso:20022:tech:xsd:camt.053.001.02')
select s.Stmt.value('(GrpHdr)[1]', 'varchar(200)') GrpHdr,
n.Ntry.value('(Amt)[1]', 'varchar(200)') Amt,
n.Ntry.value('(AddtlNtryInf)[1]', 'varchar(200)') AddtlNtryInf
from #doc.nodes('/Document/BkToCstmrStmt') s(Stmt)
outer apply s.Stmt.nodes('Stmt/Ntry') n(Ntry)
I am using XML to insert/update/delete records in table. But when I insert the row, the date value is inserted one less than the actual value. Below is the code for my Stored Procedure
IF(#Mode='UPDATE_TABLE')
BEGIN
;WITH XmlData AS
(
SELECT
NDS.DT.value('(ClaimExpenseID)[1]', 'int') AS 'ClaimExpenseID',
NDS.DT.value('(ClaimID)[1]', 'int') AS 'ClaimID',
NDS.DT.value('(POrderID)[1]', 'int') AS 'POrderID',
NDS.DT.value('(SiteID)[1]', 'int') AS 'SiteID',
NDS.DT.value('(FromDate)[1]', 'datetime') AS 'FromDate',
NDS.DT.value('(ToDate)[1]', 'datetime') AS 'ToDate',
NDS.DT.value('(ParticularID)[1]', 'int') AS 'ParticularID',
NDS.DT.value('(Description)[1]', 'varchar(200)') AS 'Description',
NDS.DT.value('(SubmittedAmount)[1]', 'int') AS 'SubmittedAmount',
NDS.DT.value('(CreatedDate)[1]', 'datetime') AS 'CreatedDate',
NDS.DT.value('(ApprovedAmount)[1]', 'int') AS 'ApprovedAmount',
NDS.DT.value('(ApprovedDate)[1]', 'datetime') AS 'ApprovedDate',
NDS.DT.value('(Remark)[1]', 'varchar(300)') AS 'Remark',
NDS.DT.value('(ApproveBy)[1]', 'int') AS 'ApproveBy',
NDS.DT.value('(RowInfo)[1]', 'varchar(20)') AS 'RowInfo'
FROM
#xmlString.nodes('/NewDataSet/DataTable') AS NDS(DT)
)
MERGE INTO dbo.ClaimExpenseTRS CET
USING XmlData x ON CET.ClaimExpenseID = x.ClaimExpenseID
WHEN MATCHED AND x.RowInfo = 'UPDATE'
THEN
UPDATE SET
CET.ClaimID=x.ClaimID,
CET.CreatedDate=x.CreatedDate,
CET.POrderID=x.POrderID,
CET.SiteID=x.SiteID,
CET.FromDate=x.FromDate,
CET.ToDate=x.ToDate,
CET.ParticularID=x.ParticularID,
CET.Description=x.Description,
CET.SubmittedAmount=x.SubmittedAmount,
CET.ApprovedAmount=x.ApprovedAmount,
CET.Remarks=x.Remark,
CET.ApproveBy=x.ApproveBy,
CET.ApprovedDate=x.ApprovedDate
WHEN MATCHED AND x.RowInfo = 'DELETE'AND CET.ClaimExpenseID = x.ClaimExpenseID
THEN DELETE
WHEN NOT MATCHED AND x.RowInfo = 'NEW'
THEN
INSERT(ClaimID, CreatedDate, POrderID, SiteID,FromDate,ToDate,ParticularID, Description,SubmittedAmount,ApprovedAmount,Remarks,ApproveBy,ApprovedDate)
VALUES(x.ClaimID,x.CreatedDate,x.POrderID,x.SiteID,x.FromDate,x.ToDate,x.
ParticularID,x.Description,x.SubmittedAmount,x.ApprovedAmount,x.Remark,x. ApproveBy,x.ApprovedDate);
END
This is the XML string..
<NewDataSet>
<DataTable>
<ClaimExpenseID>5</ClaimExpenseID>
<ClaimID>1</ClaimID>
<CreatedDate>2011-08-01T00:00:00+05:30</CreatedDate>
<POrderID>11</POrderID>
<SiteID>4</SiteID>
<FromDate>2011-08-07T00:00:00+05:30</FromDate>
<ToDate>2011-08-08T00:00:00+05:30</ToDate>
<NoOfDays>1</NoOfDays>
<ParticularID>1</ParticularID>
<Description>test</Description>
<SubmittedAmount>500</SubmittedAmount>
<Month>August</Month>
<Year>2011</Year>
<POrderNo>PO0002</POrderNo>
<SiteName>SITE 2</SiteName>
<ParticulerName>Food</ParticulerName>
<RowInfo>UNCHANGED</RowInfo>
<TableRowIndex>3</TableRowIndex>
</DataTable>
<DataTable>
<ClaimID>1</ClaimID>
<CreatedDate>2011-09-22T00:00:00+05:30</CreatedDate>
<POrderID>26</POrderID>
<SiteID>1</SiteID>
<FromDate>2011-09-22T00:00:00+05:30</FromDate>
<ToDate>2011-09-30T00:00:00+05:30</ToDate>
<NoOfDays>8</NoOfDays>
<ParticularID>1</ParticularID>
<Description>dinner</Description>
<SubmittedAmount>200</SubmittedAmount>
<POrderNo>PO-01</POrderNo>
<SiteName>ALKAPURI</SiteName>
<ParticulerName>Food</ParticulerName>
<RowInfo>NEW</RowInfo>
<TableRowIndex>4</TableRowIndex>
</DataTable>
</NewDataSet>
In second data table the from date value is 2011-09-22 and To date value is 2011-09-30 but when the value inserted in the database table it becomes 2011-09-21 and 2011-09-29 respectively..
Could this be your +5:30 timezone? Is this the same as your database or is your database trying to work out the time in a different timezone and coming up with the previous day?
Edit: I just confirmed this. If I read your date time: 2011-09-30T00:00:00+05:30 into my machine (based in the UK), I get a return of 2011-09-29 18:30:00.000
The code I used for the conversion was :
select cast('' as xml).value('xs:dateTime("2011-09-30T00:00:00+05:30")', 'datetime')
I was wondering which one of the following two was the better way of filtering on a column in my xml variable.
INSERT INTO [Tracking].[Team]([Name], [Description], [Begin_Dt], [End_Dt], [Update_Dt])
SELECT
x.[Team].value('Name', 'varchar(100)') AS [Name],
x.[Team].value('Description', 'varchar(250)') AS [Description],
x.[Team].value('Begin_Dt', 'datetime') AS [Begin_Dt],
x.[Team].value('End_Dt', 'datetime') AS [End_Dt],
getdate() as [Update_Dt]
FROM #xml.nodes('/Team') x([Team])
WHERE x.[Team].value('Team_Ref_ID', 'int') = 0
INSERT INTO [Tracking].[Team]([Name], [Description], [Begin_Dt], [End_Dt], [Update_Dt])
SELECT
x.[Team].value('Name', 'varchar(100)') AS [Name],
x.[Team].value('Description', 'varchar(250)') AS [Description],
x.[Team].value('Begin_Dt', 'datetime') AS [Begin_Dt],
x.[Team].value('End_Dt', 'datetime') AS [End_Dt],
getdate() as [Update_Dt]
FROM #xml.nodes('/Team') x([Team])
WHERE x.[Team].exist('Team_Ref_ID[. = 0]') = 1
Notice the WHERE clause, one uses exist, the other uses value, or is there a third method that's more effective ?
Thanks,
Raul
For querying an #xml variable the best improvement you can do is to have it be of type with an XML schema, see Typed XML Compared to Untyped XML. This will benefit the XPath expressions in your query (the .nodes('/Team'), the various .value and the .exists operators). But there will be an upfront cost in validating the schema when the variable is assigned.
The other typical XML performance improvement is XML indexes, but unfortunately they cannot be applied to variables so the point is mute in regard to your problem.
As to your particular minutia question (whether the .value('Team_Ref_ID') is faster than .exists('Team_Ref_ID[. = 0]')) I think the former is faster, but I have no evidence and I may well be wrong.
Actually what i found to be better was this
INSERT INTO [Tracking].[Team]([Name], [Description], [Begin_Dt], [End_Dt], [Update_Dt])
SELECT
x.[Team].value('Name', 'varchar(100)') AS [Name],
x.[Team].value('Description', 'varchar(250)') AS [Description],
x.[Team].value('Begin_Dt', 'datetime') AS [Begin_Dt],
x.[Team].value('End_Dt', 'datetime') AS [End_Dt],
getdate() as [Update_Dt]
FROM #xml.nodes('/Team[Team_Ref_Id = 0]') x([Team])
It filters out the nodes in the xml parser instead of having to filter them out in the SQL.