The SQL Server 2008 February CTP is now installed. I did it on my daily machine to force me to use it in a more realistic environment. It installed a-ok with my default SQL 2005 instance. As you can see below you can use the SQL 2008 IDE to manage and work with both SQL Server instances on your computer at the same time.
I am playing with the new XML features of SQL Server. For those of you that know my old company, Corzen, used the XML data type to do some really cool stuff. I'm now investigating the XML features for the update to the Programming SQL Server 2008 book from MS Press.
I guess that XLINQ is pretty cool and well accepted Microsoft did not change all that much in the XML world in SQL Server 2008. The new XML features of SQL Server 2008 are:
- Lax validation support in XSD-giving you some more flexibility with your required areas of the XSD
- Full support of the XSD: xs:dateTime, basically the preservation of time zones
- Union and List types in XSDs (I have not played with this yet so can't speak to how useful it will be yet, give me a day)
- Support of the LET FLOWR expression in XQuery (yay!)
- XML DML "enhancements." I put that in quotes for two reasons, there is only one true enhancement, allowing you to insert data from a SQL column or a SQL variable as part of your insert. This is a very minor enhancement, I was hoping for a new syntax for specifying position, etc. Also XML DML is SQL Server specific, so it is hard to get very excited about this feature.
Now let's take a look at some of the XSD enhancements. SQL Server 2005 added the ability put XML data into an intrinsic XML data type. This was a vast improvement over SQL Server 2000 where we had to put data in text fields. In addition, SQL Server 2005 allowed us to restrict this column with an XSD. Consider this XSD:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:simpleType name="orderAmt" >
<xsd:restriction base="xsd:int" >
<xsd:maxInclusive value="5000" />
<xsd:minExclusive value="1" />
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="Order">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CustomerName" type="xsd:string" />
<xsd:element name="OrderDate" type="xsd:dateTime"/>
<xsd:element name="OrderAmt" type="orderAmt"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
We have defined a few elements, given them a sequence and data types. We also say that you can only have an order amount between 1 and 5000 (work with me, I like simple demos) since the OrderAmt element inherits the simple type orderAmt. This works well, for example if we create an XSD and a table with an XML column bound to that XSD in SQL 2005:
--Valid SQL Server 2005 Schema
CREATE XML SCHEMA COLLECTION dbo.order_xsd
AS
'<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:simpleType name="orderAmt" >
<xsd:restriction base="xsd:int" >
<xsd:maxInclusive value="5000" />
<xsd:minExclusive value="1" />
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="Order">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CustomerName" type="xsd:string" />
<xsd:element name="OrderDate" type="xsd:dateTime"/>
<xsd:element name="OrderAmt" type="orderAmt"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>'
GO
CREATE TABLE xml_schematest (
Order_ID int primary key,
Order_XML XML(order_xsd) --XML Schema Name
)
Now let's insert some XML in there, the XML will be like this:
Insert into xml_schematest
VALUES
(1,
'<Order>
<CustomerName>Bill Gates</CustomerName>
<OrderDate>2008-10-10T14:22:27.25-05:00</OrderDate>
<OrderAmt>100</OrderAmt>
</Order>
')
Here is the result, notice the Z for UTC as well as the new time (more on that below):
<Order>
<CustomerName>Bill Gates</CustomerName>
<OrderDate>2008-10-10T19:22:27.250Z</OrderDate>
<OrderAmt>100</OrderAmt>
</Order>
This XML will fail since it has an order over 5000.
Insert into xml_schematest
VALUES
(2,
'<Order>
<CustomerName>Bill Gates</CustomerName>
<OrderDate>2008-10-10T14:22:27.25-05:00</OrderDate>
<OrderAmt>10000</OrderAmt>
</Order>
')
So life is good. We have a nice XSD and it restricts our content. SQL Server 2008 has added two new features of an XSD that we will look at today. The first is something called Lax validation. Let's say that you wanted to add an additional element after <OrderAmt> that is not part of the same schema. In SQL Server 2005, schemas can use processContents values of skip and strict for any and anyAttribute declarations as a wildcard. If it was set to skip, SQL will skip completely the validation of the additional element, if it is set to strict, SQL will require that it has an element or namespace defined in the current schema. SQL Server 2008 adds support for an additional validation option: lax. By setting the processContents attribute for this wildcard section to lax, you can enforce validation for any elements that have a schema associated with them, but ignore any elements that are not defined in the schema. Pretty cool, no?
Also the xsd:dateTime XML data type is now timezone aware. SQL Server 2005 you had to provide a time zone for dateTime, time and date data (did you really ever do that? If you needed the flexibility, trust me, this was a pain). What was not cool was that SQL Server 2005 did not preserve the time zone information for your data for dateTime or time, it normalizes it to UTC (so for example 2008-10-10T08:00:00:000-5:00 is normalized to 2008-10-10T13:00:00:000Z. Notice the Z for UTC. Quite annoying.) In SQL Server 2008, this has been removed! Take a look at this code:
CREATE XML SCHEMA COLLECTION dbo.order_xsd
AS
'<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:simpleType name="orderAmt" >
<xsd:restriction base="xsd:int" >
<xsd:maxInclusive value="5000" />
<xsd:minExclusive value="1" />
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="Order">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CustomerName" type="xsd:string" />
<xsd:element name="OrderDate" type="xsd:dateTime"/>
<xsd:element name="OrderAmt" type="orderAmt"/>
<xsd:any namespace="##other" processContents="lax"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>'
GO
CREATE TABLE xml_schematest (
Order_ID int primary key,
Order_XML XML(order_xsd) --XML Schema Name
)
GO
Now this will work and even preserve the time zone of -5 (New York) and notice the random <Notes> element due to lax validation. Here is how to insert the XML:
Insert into xml_schematest
VALUES
(1,
'<Order>
<CustomerName>Bill Gates</CustomerName>
<OrderDate>2008-10-10T14:22:27.25-05:00</OrderDate>
<OrderAmt>100</OrderAmt>
<Notes xmlns="sf">Steve Test 1</Notes>
</Order>
')
Here are the results in the database with the original time zone:
<Order>
<CustomerName>Bill Gates</CustomerName>
<OrderDate>2008-10-10T14:22:27.25-05:00</OrderDate>
<OrderAmt>100</OrderAmt>
<Notes xmlns="sf">Steve Test 1</Notes>
</Order>
Tomorrow I will look at Union and List types.