|
|
|
SSC-Addicted
      
Group: General Forum Members
Last Login: Sunday, May 12, 2013 4:01 AM
Points: 406,
Visits: 1,364
|
|
|
|
|
|
SSC-Enthusiastic
      
Group: General Forum Members
Last Login: Friday, April 19, 2013 11:06 AM
Points: 174,
Visits: 423
|
|
Greetings Richard,
That was very informative and helpful. I am starting to work with some XML now so thank you for showing how to solve the problem just before I hit it. 
Have a good day.
Terry Steadman
|
|
|
|
|
Ten Centuries
      
Group: General Forum Members
Last Login: Wednesday, May 15, 2013 5:22 AM
Points: 1,037,
Visits: 1,354
|
|
Of course, if you're storing your value in an attribute, NULL is represented by the absence of the attribute in the record element, and SQLXML deals with that fine.
Except for large data values, I prefer to store row values in attributes, as it better preserves the normality of the data and keeps the XML that much more compact.
|
|
|
|
|
SSC Rookie
      
Group: General Forum Members
Last Login: Thursday, May 02, 2013 9:10 PM
Points: 26,
Visits: 263
|
|
| I too am just starting with xml in my designs. Thank you for putting this out there!
|
|
|
|
|
Hall of Fame
       
Group: General Forum Members
Last Login: Friday, March 15, 2013 2:43 PM
Points: 3,924,
Visits: 1,554
|
|
XML always remained mystery to me. Never understood the concept completely. May because I never worked on a project which had mandatory XML programming.
And just last week got a project where I had to move XML data from SQL Server to Oracle 10g, as its a PITA.
Thanks for the article, Rick.
SQL DBA.
|
|
|
|
|
SSCommitted
      
Group: General Forum Members
Last Login: 2 days ago @ 12:39 PM
Points: 1,662,
Visits: 1,708
|
|
sknox (10/26/2010) Of course, if you're storing your value in an attribute, NULL is represented by the absence of the attribute in the record element, and SQLXML deals with that fine. Absolutely correct, and I would like to add my 2 cents about the inner text treatment. Inner text is treated in exact same fashion. If you would like the statement to return null values, just don't provide the node at all and SQL Server will deal with it just fine as well. For example, the xml sample below has 2 "records". First record does not have the node named Gender and the second record does not have the ID attribute. This means that the first record will have null for Gender column and second - null for ID column. I believe that this is the simplest way to deal with nulls, specifically because the out of the box minOccurences of any node or attribute is zero anyway.
declare @xml xml;
set @xml = ' <rows> <r ID="1"> <LastName>Clown</LastName> <FirstName>Bozo</FirstName> <MiscInfo>Bozo is a clown at Wringley</MiscInfo> </r> <r> <LastName>Netchaev</LastName> <FirstName>Oleg</FirstName> <Gender>Male</Gender> <MiscInfo>Oleg''s info goes here</MiscInfo> </r> </rows> ';
select item.value('@ID', 'int') ID, item.value('LastName[1]', 'varchar(10)') LastName, item.value('FirstName[1]', 'varchar(10)') FirstName, item.value('Gender[1]', 'varchar(10)') Gender, item.value('MiscInfo[1]', 'varchar(35)') MiscInfo from @xml.nodes('//rows/r') R(item); The above returns expected output:
ID LastName FirstName Gender MiscInfo ----------- ---------- ---------- ---------- ----------------------------------- 1 Clown Bozo NULL Bozo is a clown at Wringley NULL Netchaev Oleg Male Oleg's info goes here Very good article, thank you Richard. It is great to learn about different methods to achieve the same result.
Oleg
|
|
|
|
|
SSC-Addicted
      
Group: General Forum Members
Last Login: Sunday, May 12, 2013 4:01 AM
Points: 406,
Visits: 1,364
|
|
sknox (10/26/2010) Of course, if you're storing your value in an attribute, NULL is represented by the absence of the attribute in the record element, and SQLXML deals with that fine.
Except for large data values, I prefer to store row values in attributes, as it better preserves the normality of the data and keeps the XML that much more compact. Querying for an attribute that is not available in the document will indeed make value() return NULL, just like when an element is not specified. However, not specifying the attribute may have different interpretation than specifying an element with a nil attribute, even though in both situations the value() function will return NULL.
For example imagine a procedure that takes an xml document as a parameter. This procedure will update some record(s) using the values from the xml document. In this situation the choice between storing the values in attributes or elements does make a difference:
Storing the values in attributes means you have to choose what will happen if no attribute for a column is specified: will you leave the current value in that column unchanged or will you assign the column a null value? You will have to choose either option, and by doing so the other option is not possible any more. However, if you define your xml so that the values are stored in elements, you can explicitly set the column to null by specifying an xsi:nil="true" attribute on that column's element to make the procedure put a NULL value in the column or you can leave the column unchanged by not including the element for that column in the xml.
So, yes: using attributes instead of elements to store your values results in more compact xml documents and it may even result in slightly better performance processing the xml documents. But you have to be absolutely sure you will never need the added semantic options that using elements offers. If you need to switch from attribute oriented into element oriented after the solution has been taken into production, you may be in serious trouble.
edit: elaborated on the consequences of choosing attributes
Posting Data Etiquette - Jeff Moden Posting Performance Based Questions - Gail Shaw Hidden RBAR - Jeff Moden Cross Tabs and Pivots - Jeff Moden Catch-all queries - Gail Shaw
If you don't have time to do it right, when will you have time to do it over?
|
|
|
|
|
SSC-Addicted
      
Group: General Forum Members
Last Login: Tuesday, May 14, 2013 12:31 PM
Points: 437,
Visits: 883
|
|
Querying for an attribute that is not available in the document will indeed make value() return NULL, just like when an element is not specified. However, not specifying the attribute may have different interpretation than specifying an element with a nil attribute, even though in both situations the value() function will return NULL.
using xpath's not() function makes null handling really simple, especially in xsl transforms. //Employee[not(@certification)] will easily find all Employee elements with no certification attribute (i.e.: Employee.certification is null).
|
|
|
|
|
SSC Eights!
      
Group: General Forum Members
Last Login: Monday, May 13, 2013 2:42 PM
Points: 877,
Visits: 1,158
|
|
Really nice article. We are using XML but we were not facing any issue because we are not passing date type value. Thanks for pointing the issue.
Thanks
|
|
|
|
|
Forum Newbie
      
Group: General Forum Members
Last Login: Wednesday, May 08, 2013 9:31 AM
Points: 4,
Visits: 61
|
|
.value() will actually return a NULL value if you have Typed XML. If you create an XML schema with nillable=true then .value will actually handle all the hard work. i.e)
<?xml version="1.0" encoding="utf-8"?> <xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0"> <xs:element name="BusinessFunction"> <xs:complexType> <xs:sequence> <xs:element name="Business_Function_Id" type="xs:int" maxOccurs="1" minOccurs="1" /> <xs:element name="Parent_Business_Function_Id" type="xs:int" maxOccurs="1" minOccurs="0" nillable="true" /> <xs:element name="Name" type="xs:string" maxOccurs="1" minOccurs="0" /> <xs:element name="Description" type="xs:string" maxOccurs="1" minOccurs="0" nillable="true" /> <xs:element name="Begin_Dt" type="xs:dateTime" maxOccurs="1" minOccurs="0" /> <xs:element name="End_Dt" type="xs:dateTime" maxOccurs="1" minOccurs="0" nillable="true" /> <xs:element name="Update_Dt" type="xs:dateTime" maxOccurs="1" minOccurs="0" /> <xs:element name="Delete_Dt" type="xs:dateTime" maxOccurs="1" minOccurs="0" nillable="true" /> <xs:element name="TimeStamp" type="xs:base64Binary" maxOccurs="1" minOccurs="0" nillable="true" /> </xs:sequence> </xs:complexType> </xs:element>
As you can see my Delete_Dt and End_Dt columns have a nullable="true" attribute.
So when you actually call value('Delete_Dt', 'dateTime') it will return a NULL value instead of the default. i.e)
declare @xml xml (TrackingXML) SET @xml = '<BusinessFunction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Business_Function_Id>0</Business_Function_Id><Delete_Dt xsi:nil="true" /></BusinessFunction>'
SELECT x.[BusinessFunction].value('Delete_Dt', 'dateTime') FROM @xml.nodes('/BusinessFunction') x([BusinessFunction])
Give it a shot, Raul
|
|
|
|