Update SQL Server table using XML data - sql-server

From my ASP.Net application I am generating XML and pass it as input data to stored procedure as below,
<Aprroval>
<Approve>
<is_nb_approved>false</is_nb_approved>
<is_approved>true</is_approved>
<is_submitted>true</is_submitted>
<UserId>35</UserId>
<ClientId>405</ClientId>
<taskDate>2015-05-23T00:00:00</taskDate>
</Approve>
<Approve>
<is_nb_approved>false</is_nb_approved>
<is_approved>true</is_approved>
<is_submitted>true</is_submitted>
<UserId>35</UserId>
<ClientId>405</ClientId>
<taskDate>2015-05-24T00:00:00</taskDate>
</Approve>
</Approval>
And below is my stored procedure,
create procedure UpdateTaskStatus(#XMLdata XML)
AS
UPDATE [TT_TaskDetail]
SET
is_approved=Row.t.value('(is_approved/text())[1]','bit'),
is_nb_approved=Row.t.value('(is_nb_approved/text())[1]','bit'),
is_submitted=Row.t.value('(is_submitted/text())[1]','bit')
FROM #XMLdata.nodes('/Aprroval/Aprrove') as Row(t)
WHERE user_id = Row.t.value('(UserId/text())[1]','int')
AND client_id = Row.t.value('(ClientId/text())[1]','int')
AND taskdate = Row.t.value('(taskDate/text())[1]','date')
But when I execute this stored procedure, I am getting return value as 0 and no record is getting updated. Any suggestions welcome.

You have 2 errors in your xml:
First is nonmatching root tags.
Second, more important, you are quering nodes('/Aprroval/Aprrove'), but inner tag is Approve not Aprrove.
Fiddle http://sqlfiddle.com/#!3/66b08/3

Your outer tags do not match. Your opening tag says, "Aprroval" instead of "Approval". Once I corrected that, I was able to select from the XML without issue.

Related

Parsing XML data in SQL with attribute

I currently have an XML I am pulling from a column in SQL formatted like this:
<Datas>
<CHILD value="test" />
</Datas>
I need a way to grab the value in the CHILD tag but I am having some issues I believe to be stemming from it being a self closing tag. I am able to get the data if it was formatted in this format:
<Datas>
<CHILD>test</CHILD>
</Datas>
However, this format is not an option as the application I'm pulling from does not store it this way.
I have tried the following SQL:
select cast(xmlField as xml) xmlField into tmp from (
select '<Datas><CHILD value = "test"/></Datas>' xmlField
) tb
SELECT
xmlField.value('(Datas/CHILD)[1]', 'nvarchar(max)') as Data
FROM tmp
drop table tmp
Any help is greatly appreciated. Thanks!
The problem isn't that it's self closing, it's that you want to access an attribute. For those you need to use the attribute's name prefixed with an #:
SELECT xmlField.value('(Datas/CHILD/#value)[1]', 'nvarchar(max)') AS Data
FROM tmp;

Creating XML Schema for Bulk Load to SQL Server - Child Element Describes Parent

I have an XML document that I'm working to build a schema for in order to bulk load these documents into a SQL Server table. The XML I'm focusing on looks like this:
<Coverage>
<CoverageCd>BI</CoverageCd>
<CoverageDesc>BI</CoverageDesc>
<Limit>
<FormatCurrencyAmt>
<Amt>30000.00</Amt>
</FormatCurrencyAmt>
<LimitAppliesToCd>PerPerson</LimitAppliesToCd>
</Limit>
<Limit>
<FormatCurrencyAmt>
<Amt>85000.00</Amt>
</FormatCurrencyAmt>
<LimitAppliesToCd>PerAcc</LimitAppliesToCd>
</Limit>
</Coverage>
<Coverage>
<CoverageCd>PD</CoverageCd>
<CoverageDesc>PD</CoverageDesc>
<Limit>
<FormatCurrencyAmt>
<Amt>50000.00</Amt>
</FormatCurrencyAmt>
<LimitAppliesToCd>Coverage</LimitAppliesToCd>
</Limit>
</Coverage>
Inside the Limit element, there's a child LimitAppliesToCd that I need to use to determine where the Amt element's value actually gets stored inside my table. Is this possible to do using the standard XML Bulk Load feature of SQL Server? Normally in XML I'd expect that the element would have an attribute containing the "PerPerson" or "PerAcc" information, but this standard we're using does not call for that.
If anyone has worked with the ACORD standard before, you might know what I'm working with here. Any help is greatly appreciated.
Don't know exactly what you are talking about, but this is a solution to get the information out of your XML.
Assumption: Your XML is already bulk-loaded into a declared variable #xml of type XML:
A CTE will pull the information out of your XML. The final query will then use PIVOT to put your data into the right column.
With a fitting table's structure the actual insert should be simple...
WITH DerivedTable AS
(
SELECT cov.value('CoverageCd[1]','varchar(max)') AS CoverageCd
,cov.value('CoverageDesc[1]','varchar(max)') AS CoverageDesc
,lim.value('(FormatCurrencyAmt/Amt)[1]','decimal(14,4)') AS Amt
,lim.value('LimitAppliesToCd[1]','varchar(max)') AS LimitAppliesToCd
FROM #xml.nodes('/root/Coverage') AS A(cov)
CROSS APPLY cov.nodes('Limit') AS B(lim)
)
SELECT p.*
FROM
(SELECT * FROM DerivedTable) AS tbl
PIVOT
(
MIN(Amt) FOR LimitAppliesToCD IN(PerPerson,PerAcc,Coverage)
) AS p

PostgreSQL query not working in Yii2

I want to execute query in my yii2 application. I'm using PostgreSQl. There is a table called list inside the user schema. If I try to build any query it returns 1. My code is here:
$numUsers = Yii::$app->db->createCommand('
SELECT COUNT(*) FROM "user"."list"
')->execute();
Please show me my mistake in the query above.
This is not related to the DB type in Yii2 if you want the result of a single value you should use queryScalar() instead of execute()
$numUsers = Yii::$app->db->createCommand('
SELECT COUNT(*) FROM "user"."list" ')->queryScalar();

Convert multiple SQL Server queries into one

I have a page that ask of users opinion about a topic. Their responses are then saved into a table. What I want to do is to check how many users selected an option 1,2,3 and 4.
What I have now are multiple T-SQL queries that run successfully but I believe there is a simplified version of the code I have written. I would be grateful if someone can simplify my queries into one single query. Thank you.
here is sample of data in the database table
enter image description here
$sql4 = "SELECT COUNT(CO) FROM GnAppItms WHERE CO='1' AND MountID='".$mountID."'";
$stmt4 = sqlsrv_query($conn2, $sql4);
$row4 = sqlsrv_fetch_array($stmt4);
$sql5="SELECT COUNT(CO) FROM GnAppItms WHERE CO='2' AND MountID='".$mountID."'";
$stmt5=sqlsrv_query($conn2,$sql5);
$row5=sqlsrv_fetch_array($stmt5);
$sql6="SELECT COUNT(CO) FROM GnAppItms WHERE CO='3' AND MountID='".$mountID."'";
$stmt6=sqlsrv_query($conn2,$sql6);
$row6=sqlsrv_fetch_array($stmt6);
$sql7="SELECT COUNT(CO) FROM GnAppItms WHERE CO='4' AND MountID='".$mountID."'";
$stmt7=sqlsrv_query($conn2,$sql7);
$row7=sqlsrv_fetch_array($stmt7);
You can do it by using group by in sql server
example :
create table a
(id int,
mountid nvarchar(100),
co int,
)
insert into a values (1,'aa',1)
insert into a values (2,'aa',2)
insert into a values (3,'aa',1)
insert into a values (4,'aa',2)
insert into a values (5,'aa',3)
Query
select co,count(co)as countofco from a
where mountid='aa'
group by
co
result
co countofco
1 2
2 2
3 1
Note : Beware of SQL injection when you are writing a sql query, so always use parametrized query. You can edit the above example code and make it as a parametrized query for preventing sql injection

SQL Query + Google Geocode Response XML

I have the XML response from the Google Geocoding API stored in a SQL Server XML column. Can someone help me with a query that will return all rows where the XML contains > 1 result?
e.g.
<GeocodeResponse>
<status>OK</status>
<result></result> <!-- more than one result is present -->
<result></result>
<result></result>
</GeocodeResponse>
So something like this gives me the first result:
SELECT XmlResponse.query('/GeocodeResponse/result') FROM Locations
But I'm not sure where to go from here...
You can use the exist() method of the XML data type to check if there exist a second <result> node.
select *
from Locations
where XmlResponse.exist('GeocodeResponse/result[2]') = 1
Test the query here. https://data.stackexchange.com/stackoverflow/q/101340/xmlcolumn-exist

Resources