I have this XML in a table column in SQL Server:
<root>
<Request>
<RequestData>
<VendorLeadList>
<VendorLeadItem>
<CampaignOfferTypeID>REN</CampaignOfferTypeID>
<LeadDispositionID>Lead</LeadDispositionID>
<Jurisdiction>NY</Jurisdiction>
<FirstName>Shikasta</FirstName>
<LastName>Kashti</LastName>
<MessageId>1347_1483825159115_c8273</MessageId>
</VendorLeadItem>
</VendorLeadList>
</RequestData>
<DualMessageID/>
<AzureBlobFile/>
<AzureBlobImageList/>
</Request>
</root>
I want to query all the records where it matches some nodes with specific values. For example I want all records where LeadDispositionID=Lead and Jurisdiction=NY and CampaignOfferTypeID=REN and a MessageId element exists (doesn't matter what value.)
I tried this but it doesn't work (no errors but the conditions doesn't match and it returns other records):
SELECT TOP 10 *
FROM [Messages]
WHERE PayLoadXml.exist('//LeadDispositionID[.="Lead"] and //CampaignOfferTypeID[.="REN"] and //Jurisdiction[.="NY"] and //MessageId') = 1
ORDER BY ID DESC
Any idea as to what I'm doing wrong?
You cannot combine nodes within .exist() simply with and. Your own example would work like this:
SELECT TOP 10 *
FROM #Messages
WHERE PayLoadXml.exist('//VendorLeadItem[LeadDispositionID[.="Lead"] and CampaignOfferTypeID[.="REN"] and Jurisdiction[.="NY"] and MessageId/text()]') = 1
Try it like this:
First a declared table to mock-up your Messages table. Insert 3 cases:
DECLARE #messages TABLE(SomeDescription VARCHAR(100),PayLoadXml XML);
INSERT INTO #messages VALUES
('Your example'
,'<root>
<Request>
<RequestData>
<VendorLeadList>
<VendorLeadItem>
<CampaignOfferTypeID>REN</CampaignOfferTypeID>
<LeadDispositionID>Lead</LeadDispositionID>
<Jurisdiction>NY</Jurisdiction>
<FirstName>Shikasta</FirstName>
<LastName>Kashti</LastName>
<MessageId>1347_1483825159115_c8273</MessageId>
</VendorLeadItem>
</VendorLeadList>
</RequestData>
<DualMessageID/>
<AzureBlobFile/>
<AzureBlobImageList/>
</Request>
</root>'
)
,('LeadDispositionID=Slave'
,'<root>
<Request>
<RequestData>
<VendorLeadList>
<VendorLeadItem>
<CampaignOfferTypeID>REN</CampaignOfferTypeID>
<LeadDispositionID>Slave</LeadDispositionID>
<Jurisdiction>NY</Jurisdiction>
<FirstName>Bruno</FirstName>
<LastName>Kashti</LastName>
<MessageId>1347_1483825159115_c8273</MessageId>
</VendorLeadItem>
</VendorLeadList>
</RequestData>
<DualMessageID/>
<AzureBlobFile/>
<AzureBlobImageList/>
</Request>
</root>'
)
,('LeadDispositionID=Lead but No MessageId'
,'<root>
<Request>
<RequestData>
<VendorLeadList>
<VendorLeadItem>
<CampaignOfferTypeID>REN</CampaignOfferTypeID>
<LeadDispositionID>Lead</LeadDispositionID>
<Jurisdiction>NY</Jurisdiction>
<FirstName>Bruno</FirstName>
<LastName>Kashti</LastName>
<MessageId></MessageId>
</VendorLeadItem>
</VendorLeadList>
</RequestData>
<DualMessageID/>
<AzureBlobFile/>
<AzureBlobImageList/>
</Request>
</root>'
);
This is the query:
The CROSS APPLY will ensure, that only nodes with a MessageId are taken into account. The WHERE will apply an additional filter
SELECT m.*
FROM #messages AS m
CROSS APPLY m.PayLoadXml.nodes(N'/root/Request/RequestData/VendorLeadList/VendorLeadItem[not(empty(MessageId/text()))]') AS A(itm)
WHERE itm.exist(N'LeadDispositionID[text()="Lead"]')=1
If you need to check more than one condition you might use this:
WHERE itm.exist(N'.[LeadDispositionID="Slave" and FirstName="Bruno"]')=1
Related
I have a table named "Table1" and in the table there are columns titled "Name" and "XMLDefinition".
Name XMLDefinition
--------------------------
Name1 xmlLink1
Name2 xmlLink2
Inside each XML an example would look similar to this below:
<Query xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<QueryView>
<QueryKey />
</QueryView>
<Description>
</Description>
<QueryFields>
<f />
<f />
</QueryFields>
<FilterFields>
<f ObjectName="TABLE5" ColumnName="ID">
<DateFilterTypes />
<FuzzyDateFilterTypes />
<MonthDayFilterTypes />
<Values>
<v>0</v>
</Values>
<TranslatedValues>
<v>No</v>
</TranslatedValues>
<DataType>Boolean</DataType>
</f>
<f ObjectName="TABLE2" ColumnName="USERID">
<DateFilterTypes />
<FuzzyDateFilterTypes />
<MonthDayFilterTypes />
<Values>
<v>B80055</v>
</Values>
<TranslatedValues>
<v>B80055</v>
</TranslatedValues>
<DataType>String</DataType>
</f>
</FilterFields>
</Query>
I'd like to return Name from TABLE1 as long as in the XML content contains where ObjectName = "TABLE2" AND ColumnName = "USERID".
I have tried the below and while it doesn't error out, it returns 0 records:
SELECT
a.Name,
X.Y.value('(f)[1]', 'VARCHAR(MAX)') as Object
FROM TABLE1 a
OUTER APPLY a.XMLDefinition.nodes('Query/FilterFields/f') as X(Y)
WHERE X.Y.value('(ObjectName)[1]', 'VARCHAR(MAX)') = 'TABLE2'
AND X.Y.value('(ColumnName)[1]', 'VARCHAR(MAX)') = 'USERID'
I'm not sure what I am missing as it seems I am drilling down from Query > FilterFields > f and I assume I'd be able to then filter based on the ObjectName and ColumnName here.
Attempt 2 Update:
SELECT Name from TABLE1
WHERE XMLDefinition.value('(/Query/QueryView/Description/QueryFields/FilterFields/f/#ObjectName) [1] ',' varchar(max)') = 'TABLE2'
AND XMLDefinition.value('(/Query/QueryView/Description/QueryFields/FilterFields/f/#ColumnName) [1] ',' varchar(max)') = 'USERID'
After trying this attempt by drilling through each tag, it is still giving me 0 results.
Attempt 3 Update:
select
a.Name,
X.Y.query(N'.') as [Object] --this returns the XML of the <f> element
from dbo.Table1 a
cross apply a.XMLDefinition.nodes('//*:f[#ObjectName="TABLE2"][#ColumnName="USERID"][1]') as X(Y);
I'm not sure why, but I tried this and now it worked and returned the results that I was looking for. I'm new to XML, but I assume this worked because it ignored all the namespaces and prior tags before the f tag?
The code below probably does what you're looking for. Note that cross apply will only return dbo.Table rows that matched the XPath query, as opposed to outer apply which will return all dbo.Table rows but only XML-derived values for those rows that matched the XPath query:
create table dbo.Table1 (
Name nvarchar(10),
XMLDefinition xml
);
insert dbo.Table1 (Name, XMLDefinition) values
(N'Name1', N'<xmlLink1 />'),
(N'Name2', N'<Query xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<FilterFields>
<f ObjectName="TABLE2" ColumnName="USERID" ParentPath="TABLE2" DisplayPath="TABLE2" CompareType="Or" UseLeftParenthesis="true" LeftParenthesisCount="1" IncludeCurrentNode="true">
<DateFilterTypes />
<FuzzyDateFilterTypes />
<MonthDayFilterTypes />
<Values>
<v>B80055</v>
</Values>
<TranslatedValues>
<v>B80055</v>
</TranslatedValues>
<DataType>String</DataType>
</f>
</FilterFields>
</Query>');
select
a.Name,
X.Y.query(N'.') as [Object] --this returns the XML of the <f> element
from dbo.Table1 a
cross apply a.XMLDefinition.nodes(N'/Query/FilterFields/f[#ObjectName="TABLE2"][#ColumnName="USERID"][1]') as X(Y);
I'm looking to return value for my where condition from an XML.
I'd like to return a value from messages table's Request column. Which is in XML data format. Unfortunately all I could achieve is retrieving nothing.
Then I tried to put the value as a column but I always get nulls for the values
Here's an XML from Request column:
<InvoiceRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/InternalReuqests">
<ActiveUserID xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">0</ActiveUserID>
<LinqConfigId xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">0</LinqConfigId>
<RequestHeaderInfo xmlns:d2p1="Fix.Services" xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">
<d2p1:MapArchive i:nil="true" />
<d2p1:HandledSuccessCategory>rscNone</d2p1:HandledSuccessCategory>
</RequestHeaderInfo>
<Username xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase" i:nil="true" />
<SSID>S-1-6-25-123456789-123456789-123456789-12345</SSID>
<miscdata xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:string>date:2020.02.26 08:27:00</d2p1:string>
<d2p1:string>hours:0</d2p1:string>
<d2p1:string>Ready:True</d2p1:string>
<d2p1:string>disct:False</d2p1:string>
<d2p1:string>extdisct:False</d2p1:string>
<d2p1:string>Matmove:False</d2p1:string>
<d2p1:string>Matlim:0</d2p1:string>
<d2p1:string>Comments:</d2p1:string>
</miscdata>
<ffreeID>468545</ffreeID>
</InvoiceRequest>
here's my sql query:
select id, Request.value('(/*:InvoiceRequest/*:ffreeID)[1]','varchar(max)')
from messages
I thought I should get in the first column the id from the database, and next to it the value of the ffreeID, but the Request.value is always null.
Could anyone look into it what am I missing?
You need for declare the default namespace, which for your xml is http://schemas.datacontract.org/2004/07/InternalReuqests:
--Sample XML
DECLARE #xml xml = '<InvoiceRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/InternalReuqests">
<ActiveUserID xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">0</ActiveUserID>
<LinqConfigId xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">0</LinqConfigId>
<RequestHeaderInfo xmlns:d2p1="Fix.Services" xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">
<d2p1:MapArchive i:nil="true" />
<d2p1:HandledSuccessCategory>rscNone</d2p1:HandledSuccessCategory>
</RequestHeaderInfo>
<Username xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase" i:nil="true" />
<SSID>S-1-6-25-123456789-123456789-123456789-12345</SSID>
<miscdata xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:string>date:2020.02.26 08:27:00</d2p1:string>
<d2p1:string>hours:0</d2p1:string>
<d2p1:string>Ready:True</d2p1:string>
<d2p1:string>disct:False</d2p1:string>
<d2p1:string>extdisct:False</d2p1:string>
<d2p1:string>Matmove:False</d2p1:string>
<d2p1:string>Matlim:0</d2p1:string>
<d2p1:string>Comments:</d2p1:string>
</miscdata>
<ffreeID>468545</ffreeID>
</InvoiceRequest>'; --Assumed this should be </InvoiceRequest>, not <InvoiceRequest>.
--Get value
WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/InternalReuqests')
SELECT X.Request.value('(/InvoiceRequest/ffreeID/text())[1]','int')
FROM (VALUES(#XML))X(Request);
Here is another way by simulating a mock table. Everything else resembles #Larnu's solution. All credit goes to #Larnu.
SQL
-- DDL and sample data population, start
DECLARE #tbl TABLE (ID INT IDENTITY PRIMARY KEY, Request XML);
INSERT INTO #tbl (Request)
VALUES
(N'<InvoiceRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/InternalReuqests">
<ActiveUserID xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">0</ActiveUserID>
<LinqConfigId xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">0</LinqConfigId>
<RequestHeaderInfo xmlns:d2p1="Fix.Services"
xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">
<d2p1:MapArchive i:nil="true"/>
<d2p1:HandledSuccessCategory>rscNone</d2p1:HandledSuccessCategory>
</RequestHeaderInfo>
<Username xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase" i:nil="true"/>
<SSID>S-1-6-25-123456789-123456789-123456789-12345</SSID>
<miscdata xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:string>date:2020.02.26 08:27:00</d2p1:string>
<d2p1:string>hours:0</d2p1:string>
<d2p1:string>Ready:True</d2p1:string>
<d2p1:string>disct:False</d2p1:string>
<d2p1:string>extdisct:False</d2p1:string>
<d2p1:string>Matmove:False</d2p1:string>
<d2p1:string>Matlim:0</d2p1:string>
<d2p1:string>Comments:</d2p1:string>
</miscdata>
<ffreeID>468545</ffreeID>
</InvoiceRequest>');
-- DDL and sample data population, end
WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/InternalReuqests')
SELECT ID
, c.value('(ffreeID/text())[1]','INT') AS ffreeID
FROM #tbl AS tbl
CROSS APPLY tbl.Request.nodes('/InvoiceRequest') AS t(c);
Output
+----+---------+
| ID | ffreeID |
+----+---------+
| 1 | 468545 |
+----+---------+
The following sql code
SELECT
b.GivenName [Individual/Name/FirstName] ,
b.FamilyName [Individual/Name/LastName] ,
b.Address_Country [Individual/Address/CountryCode] ,
b.AddressFree [Individual/Address/AddressFree]
FROM dbo.stage_Clients_Merge b
WHERE b.DWHClientNo = #dwhclientNo
FOR XML PATH('Owner'), TYPE
will generate an xml fragment
<Owner>
<Individual>
<Name>
<FirstName>Bob</FirstName>
<LastName>Smith</LastName>
</Name>
<Address>
<CountryCode>US</CountryCode>
<AddressFree>123,Utah</AddressFree>
</Address>
</Individual>
</Owner>
If I extend this query to include a sub-query to return, for example, all the orders associated with a individual using the following:
(SELECT
c.OrderIdentificationNumber [Individual/OrderNumber]
FROM
dbo.stage_Customer_Orders c
WHERE
c.CustomerNo = b.masterClient
FOR
XML PATH(''), TYPE)
I will get the individual section twice. How can I combine the two to return the following?
<Owner>
<Individual>
<OrderNo>12345</OrderNo>
<OrderNo>23456</OrderNo>
<Name>
<FirstName>Bob</FirstName>
<LastName>Smith</LastName>
</Name>
<Address>
<CountryCode>US</CountryCode>
<AddressFree>123,Utah</AddressFree>
</Address>
</Individual>
</Owner>
Try it like this
I set up a mock-up scenario for stand-alone solutions. Next time you have a question, you might try this on your own. This makes it much easier to understand your issue and create a fully working and testable solution for it.
DECLARE #stage_Clients_Merge TABLE(ID INT,FirstName VARCHAR(100),LastName VARCHAR(100),CountryCode VARCHAR(100),AdressFree VARCHAR(100));
INSERT INTO #stage_Clients_Merge VALUES
(1,'Bob','Smith','US','123/Utah')
,(2,'Jim','Doh','US','123/Maryland');
DECLARE #orders TABLE(CustomerID INT, OrderNo INT)
INSERT INTO #orders VALUES
(1,11111),(1,12222)
,(2,21111),(2,22222);
SELECT (SELECT OrderNo FROM #orders WHERE CustomerID=b.ID FOR XML PATH(''),TYPE) AS Individual
,FirstName AS [Individual/Name/FirstName]
,LastName AS [Individual/Name/LastName]
,CountryCode AS [Individual/Address/CountryCode]
,AdressFree AS [Individual/Address/AdressFree]
FROM #stage_Clients_Merge AS b
FOR XML PATH('Owner');
You can use a subquery and [data()] to just get the column values with no additional nesting - then use path as before:
SELECT
(SELECT c.OrderIdentificationNumber as [data()]
FROM dbo.stage_Customer_Orders c
WHERE c.CustomerNo = b.masterClient
For XML Path('OrderNo'), type) as [Individual],
b.GivenName [Individual/Name/FirstName] ,
b.FamilyName [Individual/Name/LastName] ,
b.Address_Country [Individual/Address/CountryCode] ,
b.AddressFree [Individual/Address/AddressFree]
FROM dbo.stage_Clients_Merge b
WHERE b.DWHClientNo = #dwhclientNo
FOR XML PATH('Owner'), TYPE
Hi I have the following xml input in a SP.
DECLARE #XmlVariable XML = '<portal><patientid>67518</patientid>
<forms>
<form id="31" type="C"/>
<form id="44" type="D"/>
</forms>
</portal>'
I have the following inmemory table:
DECLARE #TColumns table (
FormId int,
FormType varchar(1),
PatientId int
)
Now, my intention is to:
1.Iterate the xml and insert the values into the #TColumns table.
2.Read the #TColumns table row by row and based on the 3 column values update some existing table;something like
update myexistingtable set status=4 where Formid=31 && Formtype='C' and PatientId=67518.
For item number 1 above, this is what I have done till now, but there is some syntax error:
INSERT INTO #TColumns(FormId,FormType,PatientId)
SELECT
XTbl.Cats.value('.', 'int'),
XTbl.Cats.value('.', 'varchar(1)'),
XTbl.Cats.value('.', 'int')
FROM
#XmlVariable.nodes('/portal/forms/form/#id') AS XTbl(Cats),
#XmlVariable.nodes('/portal/forms/form/#type') AS XTbl(Cats),
#XmlVariable.nodes('/portal/forms/form/#patientid') AS XTbl(Cats)
The error I am getting is:The correlation name 'XTbl' is specified multiple times in a FROM clause.
Need help on this and also on the item number 2 above.
Thanks in advance.
Maybe you want something like this
SELECT
Tbl1.Form.value('#id', 'int'),
Tbl1.Form.value('#type', 'varchar(1)'),
Tbl2.Portal.value('patientid', 'int')
FROM
#XmlVariable.nodes('//form') Tbl1(Form),
#XmlVariable.nodes('//portal') Tbl2(Portal)
This is what helped.Yes its is based on Hogan's last suggestion.Thank you!
INSERT INTO #TColumns(FormId,FormType,PatientId)
SELECT
Tbl1.Form.value('#id', 'int'),
Tbl1.Form.value('#type', 'varchar(1)'),
Tbl2.Portal.value('.', 'int')
FROM
#XmlVariable.nodes('//form') Tbl1(Form),
#XmlVariable.nodes('//patientid') Tbl2(Portal)
I have table which contains columns like
SiteID (identity_Col)
SiteName
POrderID
Location
Address
Cluster
VenderName
I want to use xml string to insert/update/delete data in this table. Apart from this column, XML string contains one more column viz. RowInfo. This column will have values like "Unchanged","Update","New","Delete". Based on this values the rows in the table should be inserted,updated,deleted.
My XML string is as below:
<NewDataSet>
<DataTable>
<SiteID>2</SiteID>
<SiteName>NIZAMPURA</SiteName>
<POrderID>7</POrderID>
<Location>NIZAMPURA</Location>
<SiteAddress>Vadodara</SiteAddress>
<Cluster>002</Cluster>
<SubVendorName>Test Vender-1</SubVendorName>
<RowInfo>UNCHANGED</RowInfo>
</DataTable>
<DataTable>
<SiteID>16</SiteID>
<SiteName>Site-1</SiteName>
<POrderID>7</POrderID>
<Location>Alkapuri</Location>
<SiteAddress>test</SiteAddress>
<Cluster>Test Cluster</Cluster>
<SubVendorName>Test Vender12</SubVendorName>
<RowInfo>UNCHANGED</RowInfo>
</DataTable>
<DataTable>
<SiteID>17</SiteID>
<SiteName>Site-3</SiteName>
<POrderID>7</POrderID>
<Location>Alkapuri123</Location>
<SiteAddress>test123</SiteAddress>
<Cluster>Test Cluster123</Cluster>
<SubVendorName>Test Vender123</SubVendorName>
<RowInfo>DELETE</RowInfo>
</DataTable>
</NewDataSet>'
This is the code that I have written to insert data in table if RowInfo = "NEW"
IF len(ISNULL(#xmlString, '')) > 0
BEGIN
DECLARE #docHandle1 int = 0;
EXEC sp_xml_preparedocument #docHandle1 OUTPUT, #xmlString
INSERT INTO [SiteTRS] (
[SiteName],
[POrderID],
[Location],
[SiteAddress],
[Cluster],
[SubVendorName])
SELECT SiteName,POrderID,Location,SiteAddress,Cluster,SubVendorName
FROM OPENXML (#docHandle1, '/NewDataSet/DataTable')
WITH (SiteName varchar(50) './SiteName',
POrderID varchar(50) './PorderID',
Location varchar(50) './Location',
SiteAddress varchar(max) './SiteAddress',
Cluster varchar(50) './Cluster',
SubVendorName varchar(50) './SubVendorName',
RowInfo varchar(30) './RowInfo')
WHERE RowInfo='NEW'
But I don't know how to use XML to update/delete records in the table. Please guide
I am novice in the XML so dont have any idea. Please forgive me if I am making something childish.
I would strongly recommend not to use the old, legacy OPENXML stuff anymore - with XML support in SQL Server, it's much easier to use the built-in XPath/XQuery methods.
In your case, I would use a CTE (Common Table Expression) to break up the XML into an "inline" table of rows and columns:
DECLARE #input XML = '<NewDataSet>
<DataTable>
<SiteID>2</SiteID>
<SiteName>NIZAMPURA</SiteName>
<POrderID>7</POrderID>
<Location>NIZAMPURA</Location>
<SiteAddress>Vadodara</SiteAddress>
<Cluster>002</Cluster>
<SubVendorName>Vender-1</SubVendorName>
<RowInfo>UPDATE</RowInfo>
</DataTable>
<DataTable>
<SiteName>Site-1</SiteName>
<POrderID>7</POrderID>
<Location>Alkapuri</Location>
<SiteAddress>test</SiteAddress>
<Cluster>Cluster-1</Cluster>
<SubVendorName>Test Vender</SubVendorName>
<RowInfo>NEW</RowInfo>
</DataTable>
</NewDataSet>'
;WITH XMLData AS
(
SELECT
NDS.DT.value('(SiteID)[1]', 'int') AS 'SiteID',
NDS.DT.value('(SiteName)[1]', 'varchar(50)') AS 'SiteName',
NDS.DT.value('(POrderID)[1]', 'int') AS 'POrderID',
NDS.DT.value('(Location)[1]', 'varchar(100)') AS 'Location',
NDS.DT.value('(SiteAddress)[1]', 'varchar(100)') AS 'SiteAddress',
NDS.DT.value('(Cluster)[1]', 'varchar(100)') AS 'Cluster',
NDS.DT.value('(SubVendorName)[1]', 'varchar(100)') AS 'SubVendorName',
NDS.DT.value('(RowInfo)[1]', 'varchar(20)') AS 'RowInfo'
FROM
#input.nodes('/NewDataSet/DataTable') AS NDS(DT)
)
SELECT *
FROM XMLDATA
This gives you rows and columns which you can work with.
SiteID SiteName POrderID Location SiteAddress Cluster SubVendorName RowInfo
2 NIZAMPURA 7 NIZAMPURA Vadodara 002 Vender-1 UPDATE
NULL Site-1 7 Alkapuri test Cluster-1 Test Vender NEW
Now if you're on SQL Server 2008 or newer, you could combine this with the MERGE command to do your INSERT/UPDATE in a single statement, basically.
If you're on 2005, you will need to either store this information into a temporary table / table variable inside your stored proc, or you need to do the select multiple times; the CTE allows only one single command to follow it.
Update: with this CTE, you can then combine it with a MERGE:
;WITH XmlData AS
(
SELECT
NDS.DT.value('(SiteID)[1]', 'int') AS 'SiteID',
NDS.DT.value('(SiteName)[1]', 'varchar(50)') AS 'SiteName',
NDS.DT.value('(POrderID)[1]', 'int') AS 'POrderID',
NDS.DT.value('(Location)[1]', 'varchar(100)') AS 'Location',
NDS.DT.value('(SiteAddress)[1]', 'varchar(100)') AS 'SiteAddress',
NDS.DT.value('(Cluster)[1]', 'varchar(100)') AS 'Cluster',
NDS.DT.value('(SubVendorName)[1]', 'varchar(100)') AS 'SubVendorName',
NDS.DT.value('(RowInfo)[1]', 'varchar(20)') AS 'RowInfo'
FROM
#input.nodes('/NewDataSet/DataTable') AS NDS(DT)
)
MERGE INTO dbo.SiteTRS t
USING XmlData x ON t.SiteID = x.SiteID
WHEN MATCHED AND x.RowInfo = 'UPDATE'
THEN
UPDATE SET
t.SiteName = x.SiteName,
t.POrderID = x.POrderID,
t.Location = x.Location,
t.SiteAddress = x.SiteAddress,
t.Cluster = x.Cluster,
t.SubVendorName = x.SubVendorName
WHEN MATCHED AND x.RowInfo = 'DELETE'
THEN DELETE
WHEN NOT MATCHED AND x.RowInfo = 'NEW'
THEN
INSERT(SiteID, SiteName, POrderID, Location, SiteAddress, Cluster, SubVendorName)
VALUES(x.SiteID, x.SiteName, x.POrderID, x.Location, x.SiteAddress, x.Cluster, x.SubVendorName)
;
See some more resources:
SQL SERVER – 2008 – Introduction to Merge Statement – One Statement for INSERT, UPDATE, DELETE
Using SQL Server 2008's MERGE statement