<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
  <title>Bob Beauchemin's Blog</title>
  <link rel="alternate" type="text/html" href="http://www.sqlskills.com/blogs/bobb/" />
  <link rel="self" href="http://www.sqlskills.com/blogs/bobb/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2008-05-16T16:12:43.39-07:00</updated>
  <author>
    <name>Bob Beauchemin</name>
  </author>
  <subtitle>newtelligence powered</subtitle>
  <id>http://www.sqlskills.com/blogs/bobb/</id>
  <generator uri="http://www.dasblog.net" version="2.0.7180.0">DasBlog</generator>
  <entry>
    <title>SQL Server 2008 Change Tracking and Sync Services ARE made for each other... in VS2008 SP1</title>
    <link rel="alternate" type="text/html" href="http://www.sqlskills.com/blogs/bobb/2008/05/16/SQLServer2008ChangeTrackingAndSyncServicesAREMadeForEachOtherInVS2008SP1.aspx" />
    <id>http://www.sqlskills.com/blogs/bobb/PermaLink,guid,1240b5a7-5437-4a80-ba78-232412f1c7d3.aspx</id>
    <published>2008-05-16T16:12:43.39-07:00</published>
    <updated>2008-05-16T16:12:43.39-07:00</updated>
    <category term="SQL Server 2008" label="SQL Server 2008" scheme="http://www.sqlskills.com/blogs/bobb/CategoryView,category,SQL%2BServer%2B2008.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
This item was mentioned in other blogs too, but just to mention it again (so my SQLCE
and Sync Services friends won't think I overlooked it)...
</p>
        <p>
Visual Studio 2008 SP1 Beta contains direct support for using SQL Server 2008 Change
Tracking. When you use ADO.NET 1.0 Sync Services with a SQL Server 2008 database,
the Sync Services designer (that's Add/New Item/Local Database Data Cache) adds a
checkbox that allows you simply to "Use SQL Server Change Tracking". No extra triggers,
no tombstone tables, change tracking does it all for you. Visual Studio generates
some scripts to enable change tracking at a database level and at a table level
for the tables you select.
</p>
        <p>
There's some nice generated code that warns you if you need to resync because you
haven't synchronized often enough. And you can tweak the SQL scripts for more control.
You can specify a CHANGE_RETENTION (the default is 2 days) and whether or not
AUTO_CLEANUP is ON (it's on by default) in your ALTER DATABASE statement. And
if you want to write your own, more granular synchronization or conflict resolution
code, you can specify WITH TRACK_COLUMNS_UPDATED = ON (default is OFF). 
</p>
        <p>
Something that puzzled me was, although the SQL Server Books Online states: "Using
snapshot isolation is the easiest way for you to help ensure that all change tracking
information is consistent. For this reason, we strongly recommend that snapshot isolation
be set to ON for the database.", the ALTER DATABASE DDL generated by Visual Studio
did not include the option to SET ALLOW_SNAPSHOT_ISOLATION ON. Enabling snapshot isolation
in SQL Server does involve a non-trivial amount of overhead, so it looks like they
set it to the least overhead option and let you decide if you need snapshot isolation
after reading the arguments/scenarios where it's useful in Books Online. Probably
a wise choice.
</p>
        <p>
Synchronization Framework is an exciting technology, given that there's
so many possible uses of synchronization with "Local Data Caches" and, with the support
for Sync Services in mobile devices. The next release of the Synchronization Framework
(2.0, there's a beta out already) even contains support for Peer-to-Peer synchronization
through the model. Perhaps this will fit some additional "replication via
services" in databases. We'll have to wait and see if the Peer-to-Peer sync provider
even supports databases, I guess. Always something interesting going on...
</p>
        <img width="0" height="0" src="http://www.sqlskills.com/blogs/bobb/aggbug.ashx?id=1240b5a7-5437-4a80-ba78-232412f1c7d3" />
        <br />
        <hr />
This blog is sponsored by <a href="http://www.sqlskills.com">SQLSkills</a>. 
</div>
    </content>
  </entry>
  <entry>
    <title>SQL Server 2008 data types in LINQ to SQL and EF, they (mostly) did it</title>
    <link rel="alternate" type="text/html" href="http://www.sqlskills.com/blogs/bobb/2008/05/16/SQLServer2008DataTypesInLINQToSQLAndEFTheyMostlyDidIt.aspx" />
    <id>http://www.sqlskills.com/blogs/bobb/PermaLink,guid,6ee055aa-47ab-4dd7-a1d0-fd3936d54ff2.aspx</id>
    <published>2008-05-16T15:43:32.811875-07:00</published>
    <updated>2008-05-16T15:43:32.811875-07:00</updated>
    <category term="SQL Server 2008" label="SQL Server 2008" scheme="http://www.sqlskills.com/blogs/bobb/CategoryView,category,SQL%2BServer%2B2008.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Last fall I'd asked the folks on the data access team about the possibility of including
the new SQL Server 2008 data types in the new data access object mapping layers. At
that time they said "no" but they also asked "why do you want it?" and "are people
expecting it?". Someone must have had some compelling arguments.
</p>
        <p>
I'm sure you've read this in other blogs, but in Visual Studio 2008 SP1 Beta, which
arrived Monday, there was...drumroll please...support for all four date and time types
in not only LINQ to SQL, but in ADO.NET Entity Framework. Thanks! I'm still a bit
surprised about the inclusion of DateTimeOffset in EF (its a SQL Server-specific data
type and EF is more platform-neutral than LINQ to SQL), but it was a cool surprise
to have them there.  
</p>
        <p>
Everyone's blog entry also points out there is some special support for Filestream
storage (including a System.Data.Types.SqlFilestream class), but they identify
Filestream as a data type. Filestream is a storage format rather than a data type,
the actual data type is varbinary(max). Minor terminology nit. You can read and write
FILESTREAM based types without resorting to PInvoke. Cool.
</p>
        <p>
Of course, there were some SQL Server 2008 data types (the SQLCLR-based types) that
aren't "in there". These are the spatial types (Geometry and Geography) and the HierarchyID
data type. Perhaps for EF/LINQ to SQL version 2. These types are correctly identified
in Server Explorer in a table but attempting to add a table containing them to an
EF diagram fails (it actually leaves the type out of the diagram) and in LINQ to SQL
throws an error "the data type is not supported". 
</p>
        <p>
That means if you have one of these types in your SQL Server 2008 database, you need
to do something funky like treat it as a varbinary(max) and deserialize it (think
IBinarySerialize) on the client yourself. Because the SQLCLR-based data types
would have a one-to-one mapping to .NET classes (Geometry = Microsoft.SqlServer.Types.SqlGeometry,
Geography = SqlGeography, HierarchyID = SqlHierarchyID) these would possibly be straightforward
to implement in the next release. They WOULD be a potential model-breaker in that
you would have "columns" (entity properties) that have their own properties and methods.
Another whole level of indirection.
</p>
        <p>
I've said before that IMHO, spatial support is the "killer developer feature" in SQL
Server 2008. Let's hope for more API support in future. But THANKS for the inclusion
of the date and time types.
</p>
        <img width="0" height="0" src="http://www.sqlskills.com/blogs/bobb/aggbug.ashx?id=6ee055aa-47ab-4dd7-a1d0-fd3936d54ff2" />
        <br />
        <hr />
This blog is sponsored by <a href="http://www.sqlskills.com">SQLSkills</a>. 
</div>
    </content>
  </entry>
  <entry>
    <title>First blog entry in a month...what's up</title>
    <link rel="alternate" type="text/html" href="http://www.sqlskills.com/blogs/bobb/2008/05/16/FirstBlogEntryInAMonthwhatsUp.aspx" />
    <id>http://www.sqlskills.com/blogs/bobb/PermaLink,guid,f67c7248-4a2f-4aab-825c-ed8ba4373210.aspx</id>
    <published>2008-05-16T15:20:37.29625-07:00</published>
    <updated>2008-05-16T15:20:37.29625-07:00</updated>
    <category term="SQL Server 2008" label="SQL Server 2008" scheme="http://www.sqlskills.com/blogs/bobb/CategoryView,category,SQL%2BServer%2B2008.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
After posting the last blog entry, I realized that I hadn't blogged in about a month.
Hmmmm...
</p>
        <p>
Well, since last month I posted the demos for my <a href="http://www.devconnections.com/shows/sqlspring2006/default.asp?s=75">SQLConnections</a> talks
on the SQLskills website (under PastConferences). I really had a good time at SQLConnections,
its been a while since I'd been invited to speak there. Thanks to those folks who
showed up and said hi.
</p>
        <p>
I've been updating my classes for SQL Server 2008 while waiting for the next CTP.
Don't know when that's coming, but everyone's guess is "sometime in June". And I've
found a few more neat things in SQL Server 2008 that I'll get around to writing about
some day soon. And did some experimenting with the Visual Studio 2008 SP1 Beta (see
previous post).
</p>
        <p>
And I've done a lot of yardwork and gardening. I've been outside almost every day;
might even lose that pastey-white "programmer who never sees the sun" look. But its
97 degrees in Portland today (yes, 97, really) and its a bit hot for gardening.
</p>
        <p>
Next stop...<a href="http://www.microsoft.com/events/teched2008/developer/default.mspx">TechEd
Developer Week</a> in June. I'm doing a <a href="https://www.msteched.com/dev/public/precons.aspx">precon
there on SQL Server 2008</a> and a couple of other interesting talks. Wonder
if it will be 97 degrees in Orlando... If you're in Orlando stop by and say hi. 
</p>
        <img width="0" height="0" src="http://www.sqlskills.com/blogs/bobb/aggbug.ashx?id=f67c7248-4a2f-4aab-825c-ed8ba4373210" />
        <br />
        <hr />
This blog is sponsored by <a href="http://www.sqlskills.com">SQLSkills</a>. 
</div>
    </content>
  </entry>
  <entry>
    <title>Trace Events in ADO.NET Entity Framework</title>
    <link rel="alternate" type="text/html" href="http://www.sqlskills.com/blogs/bobb/2008/05/16/TraceEventsInADONETEntityFramework.aspx" />
    <id>http://www.sqlskills.com/blogs/bobb/PermaLink,guid,1d83ed40-dcc0-4467-b9f4-a7d49dd2890a.aspx</id>
    <published>2008-05-16T14:37:31.5775-07:00</published>
    <updated>2008-05-16T14:37:31.5775-07:00</updated>
    <category term="SQL Server 2008" label="SQL Server 2008" scheme="http://www.sqlskills.com/blogs/bobb/CategoryView,category,SQL%2BServer%2B2008.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Every once in a while I'll get inquires on a paper I wrote in 2004 about the ETW trace
providers for ADO.NET (named "Tracing Data Access"). I got an inquiry today, and since
I'd recently installed Visual Studio 2008 SP1 Beta, I thought I'd try it out on a
LINQ to SQL program and an Entity Framework program. 
</p>
        <p>
If you haven't read the paper, the <a href="http://msdn.microsoft.com/en-us/library/ms971550.aspx">original
is still available</a> on MSDN, but <a href="http://msdn.microsoft.com/en-us/library/aa964124.aspx">an
embellished version</a> (including SNAC tracing in addition to ADO.NET) was released
in 2006. I'm also doing a talk at TechEd on "End-to-End tracing in ADO.NET and SQL
Server 2008". If you're at all interested in client tracing or SQL Server 2008 Extended
Events, it will be worth your while to attend.
</p>
        <p>
Unless the LINQ to SQL program has its own ETW provider that I missed, I got no LINQ
to SQL specific trace events. Since LINQ to SQL is a thin layer over System.Data.SqlClient,
I do get the events for SqlClient however.
</p>
        <p>
Entity Framework however, is another matter. I not only get EF-specific trace events, but
there appears to be some new trace namespace abbreviations for EF as well. These are
the ones I've seen while going through one trace of one simple EF program. I may have
missed some.
</p>
        <p>
dobj = System.Data.Objects<br />
ec   = System.Data.EntityClient<br />
cqt  = System.Data.Common.CommandTrees<br />
pc   = System.Data.Query.PlanCompiler
</p>
        <p>
There's quite a bit of trace information for some parts of EF, like the CommandTree
portion. But after a whole half-hour and a few traces, it appears that not all items
in EF are as thoroughly instrumented with trace events as, say, SqlClient. On the
other hand, EF provider for SQL Server will show lots of SqlClient-specific and System.Data.Common
events, as does LINQ to SQL.
</p>
        <p>
Another interesting thing I discovered from running the trace. It appears that EF
is using the ADO.NET DataSet in some way, perhaps (wild guess) for entity tracking
and change tracking. The way I came to this conclusion is that, I have a simple console
app that produced no DataSets, but my trace shows lots of DataSet activity. Perhaps
this is common knowledge, but it was a bit of a surprise to me.
</p>
        <img width="0" height="0" src="http://www.sqlskills.com/blogs/bobb/aggbug.ashx?id=1d83ed40-dcc0-4467-b9f4-a7d49dd2890a" />
        <br />
        <hr />
This blog is sponsored by <a href="http://www.sqlskills.com">SQLSkills</a>. 
</div>
    </content>
  </entry>
  <entry>
    <title>Heading off to SQLConnections</title>
    <link rel="alternate" type="text/html" href="http://www.sqlskills.com/blogs/bobb/2008/04/17/HeadingOffToSQLConnections.aspx" />
    <id>http://www.sqlskills.com/blogs/bobb/PermaLink,guid,ee409e89-d4de-4fc4-929a-13d40696c0e4.aspx</id>
    <published>2008-04-17T07:42:51.627-07:00</published>
    <updated>2008-04-17T07:44:25.987125-07:00</updated>
    <category term="SQL Server 2008" label="SQL Server 2008" scheme="http://www.sqlskills.com/blogs/bobb/CategoryView,category,SQL%2BServer%2B2008.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I'm heading off to <a href="http://www.sqlconnections.com/shows/SP2008SQL/default.asp">SQLConnections</a> in
Orlando early tomorrow morning. I'll see starting with a preconference "Day of SQL
Server 2008 for Developers" and covering, well, every new feature that could interest a
developer. I'll also being doing a series of talks about everything from Spatial data
support to Extended Events to PowerShell in SQL Server to XML for DBAs. 
</p>
        <p>
If you'll be in Orlando for the conference, stop by and say hi.
</p>
        <img width="0" height="0" src="http://www.sqlskills.com/blogs/bobb/aggbug.ashx?id=ee409e89-d4de-4fc4-929a-13d40696c0e4" />
        <br />
        <hr />
This blog is sponsored by <a href="http://www.sqlskills.com">SQLSkills</a>. 
</div>
    </content>
  </entry>
  <entry>
    <title>Converting an EAV design to sparse columns and populating</title>
    <link rel="alternate" type="text/html" href="http://www.sqlskills.com/blogs/bobb/2008/04/08/ConvertingAnEAVDesignToSparseColumnsAndPopulating.aspx" />
    <id>http://www.sqlskills.com/blogs/bobb/PermaLink,guid,249fe5db-0941-4e60-ac7e-387276610391.aspx</id>
    <published>2008-04-08T10:50:47.205125-07:00</published>
    <updated>2008-04-08T10:50:47.205125-07:00</updated>
    <category term="SQL Server 2008" label="SQL Server 2008" scheme="http://www.sqlskills.com/blogs/bobb/CategoryView,category,SQL%2BServer%2B2008.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
One of the uses for sparse columns will likely be replacing entity-attribute-value
designs. In an EAV design, the "sparse attribute" values are represented by a separate
table. The attribute value can either be declared as (n)varchar or sql_variant. An
example I've always used is the hardware store that wants to keep track of its products
in a "products" table, but each product has different attributes. If you use the minimum
number of columns to simplify the example, the EAV design looks like this.
</p>
        <p>
create table products -- base table<br />
(<br />
 id int primary key,<br />
 name varchar(max)<br />
)<br />
go<br />
create table properties -- sparse attribute (name-value pair) table<br />
(<br />
 id int,<br />
 name varchar(50),<br />
 value varchar(max),<br />
 CONSTRAINT PK_properties PRIMARY KEY (id, name),<br />
 FOREIGN KEY (id) REFERENCES products (id)<br />
)<br />
go
</p>
        <p>
Here's a straightforward way to convert the table to use SQL Server 2008's sparse
columns. It uses dynamic SQL, but in this case there's no user input (SQL injection
worries).
</p>
        <p>
declare @tab nvarchar(max), 
<br />
        @sql nvarchar(max)
</p>
        <p>
set @tab=N'create table products2 (id int primary key, name nvarchar(max) '<br />
select  @tab=@tab+','+ name + ' varchar(max) sparse' from properties 
<br />
group by name 
<br />
set @tab += ' ,col_values xml column_set for all_sparse_columns);'<br />
-- select @tab<br />
exec(@tab)
</p>
        <p>
Populating it is also straghtforward using the pivot operator, introduced in SQL Server
2005. In the case where each item has only one of each sparse property (the table
constraint enforces this), and our properties table has only three columns, there's
no real aggregation with pivot. The aggregate is just required by the pivot operator
syntax. This populates the table:
</p>
        <p>
declare @col nvarchar(max), 
<br />
        @sql nvarchar(max)
</p>
        <p>
set @cols=N''<br />
select  @cols=@cols+','+ name from properties 
<br />
group by name 
<br />
 select @cols<br />
set @cols=substring(@cols,2,datalength(@cols)/2 - 1)<br />
set @sql=N'insert into products2 (id, name,' + @cols + ') select p.id, p.name, <a href="mailto:'+@cols">'+@cols</a>+<br />
      N' from (<br />
      select id, name, value 
<br />
      from properties<br />
      ) as q<br />
      pivot<br />
      (<br />
      max(value)<br />
      for name in (<a href="mailto:'+@cols">'+@cols</a>+<br />
      ')<br />
      ) as PivotTable'<br />
set @sql += ' join products p on PivotTable.id = p.id'<br />
-- select @sql<br />
exec (@sql)
</p>
        <p>
What remains to be done now is to choose better data types for the sparse columns,
if the data isn't really a string. If you haven't enforced value type correctness
in the application, this may require some data cleansing. Full example as an attachment.
Remember that currently (in CTP6) you can only have 1024 total columns in a table;
but the limit will be increased to 30000 sparse columns before RTM.
</p>
        <a href="http://www.sqlskills.com/blogs/bobb/content/binary/eav_to_sparse.zip">eav_to_sparse.zip
(1.23 KB)</a>
        <img width="0" height="0" src="http://www.sqlskills.com/blogs/bobb/aggbug.ashx?id=249fe5db-0941-4e60-ac7e-387276610391" />
        <br />
        <hr />
This blog is sponsored by <a href="http://www.sqlskills.com">SQLSkills</a>. 
</div>
    </content>
  </entry>
  <entry>
    <title>Getting an activity ID with Extended Events</title>
    <link rel="alternate" type="text/html" href="http://www.sqlskills.com/blogs/bobb/2008/04/07/GettingAnActivityIDWithExtendedEvents.aspx" />
    <id>http://www.sqlskills.com/blogs/bobb/PermaLink,guid,225592e5-0cd7-48e4-82b0-44d5882406d6.aspx</id>
    <published>2008-04-07T11:54:14.3741946-07:00</published>
    <updated>2008-04-07T11:54:14.3741946-07:00</updated>
    <category term="SQL Server 2008" label="SQL Server 2008" scheme="http://www.sqlskills.com/blogs/bobb/CategoryView,category,SQL%2BServer%2B2008.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
It's easier than you'd think... When you use the SQL Server 2008 CREATE EVENT SESSION
DDL statement with extended events, you specify:
</p>
        <p>
Events to be captured (e.g. sqlserver.error_reported)<br />
Actions to be fired to add more information (e.g. sqlserver.sql_text)<br />
Predicates for conditional capture (e.g. where sqlserver.error_reported.error = 547)<br />
Event target to collect the events (e.g. package0.ring_buffer)<br />
Addtional options (e.g. MAX_MEMORY)
</p>
        <p>
In general, the way you look for events, actions, predicates, etc to use is to query
against the metadata views:
</p>
        <p>
select p.name + '.' + o.name as [Full Name], 
<br />
       o.description s [Description]<br />
from sys.dm_xe_objects o<br />
join sys.dm_xe_packages p on o.package_guid = p.guid<br />
-- @type can be 'event', 'action', etc<br />
where o.object_type = @type order by p.name, o.name 
</p>
        <p>
Two of the actions listed have to do with activity (causality): package0.attach_activity_id
and package0.attach_activity_id_xfer. In addition there is an option TRACE_CAUSALITY.
I thought you'd have to set the TRACE_CAUSALITY option <strong>and</strong> add the
actions to collect activity information. But attempting to add either action produced
an error.
</p>
        <p>
It's easier than that. Simply turning on the TRACE_CAUSALITY option is enough. The
actions <strong>can't</strong> be specified in CREATE EVENT SESSION (or ALTER
EVENT SESSION) because they are for internal use. The activity_ids show up at the
target without explicitly naming the actions.
</p>
        <img width="0" height="0" src="http://www.sqlskills.com/blogs/bobb/aggbug.ashx?id=225592e5-0cd7-48e4-82b0-44d5882406d6" />
        <br />
        <hr />
This blog is sponsored by <a href="http://www.sqlskills.com">SQLSkills</a>. 
</div>
    </content>
  </entry>
  <entry>
    <title>SqlClient, System.Transactions, SQL Server 2008, and MARS</title>
    <link rel="alternate" type="text/html" href="http://www.sqlskills.com/blogs/bobb/2008/04/05/SqlClientSystemTransactionsSQLServer2008AndMARS.aspx" />
    <id>http://www.sqlskills.com/blogs/bobb/PermaLink,guid,d4b5729c-f2de-4ca9-8095-19f0f0b40115.aspx</id>
    <published>2008-04-05T15:14:44.78-07:00</published>
    <updated>2008-04-09T10:40:52.892625-07:00</updated>
    <category term="SQL Server 2008" label="SQL Server 2008" scheme="http://www.sqlskills.com/blogs/bobb/CategoryView,category,SQL%2BServer%2B2008.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
It appears that there are some changes in .NET 3.5 System.Transactions (or System.Transactions.dll
and System.Data.dll version 2.0.50727.1433 if you're looking at assembly versions).
Florin Lazar blogs about a change to the syntax <a href="http://blogs.msdn.com/florinlazar/archive/2008/03/24/8334137.aspx">here</a>. And
Alazel Acheson blogs about changes to SqlClient changes to accomodate using lightweight
transactions with less promotion to distributed transactions in the ADO.NET Team blog.
</p>
        <p>
It is interesting to read how the latest version of SqlClient can combine automatic
transactions with connection pooling to use promotion to a distributed only when necessary.
It was reminiscent of how COM+ used the connection pool; the difference is that
COM+ always used distibuted transactions. Some of the changes use a transaction-aware
connection reset mode that's only supported in SQL Server 2008. So server changes
were required as well.
</p>
        <p>
At the end of the blog entry Alazel mentions that you can't use this facility
with two open connections at the same time; it requires that there is a free connection
with the appropriate transaction scope in the pool. I immediately thought of SQL Server's
sp_getbindtoken and sp_bindsession, the manual way to allow two connections to share
a single transaction context. But sp_getbindtoken and sp_bindsession are on the deprecation
list (to be removed in a future version of SQL Server) in SQL Server 2008. The books
online entry for these calls recommends "using MARS or distributed transactions instead".
But why MARS?
</p>
        <p>
MARS (multiple active resultsets) made its appearence in SQL Server 2005 and its data
access stacks. It permits you to have multiple interleaved sessions while using a
single SQL Server connection. These multiple sessions share the same transaction,
modulo an interesting but escoteric behavior known as batch-scoped transactions. MARS
also does not support named savepoints.
</p>
        <p>
What MARS and sp_getbindtoken/sp_bindsession have in common is that they are both
solutions to the same "problem". I prefer calling this a SQL Server "behavior" because its not
technicall a problem, just how the underlying network stack works. SQL Server
does not allow other activity on a connection (like an UPDATE or a second SELECT)
while reading a rowset is in progress. Pre-MARS, if you wanted to have multiple commands
in a single transaction scope, you would use two connections and "bind" the transaction
scopes together with the transaction token. With the MARS capability this is no longer
necessary. 
</p>
        <p>
So, the OpenConnction1/DoCommand1/Close then OpenConnection2/DoCommand2/Close pattern
is now acommodated by System.Transactions and SQL Server 2008 without transaction
promotion. To do two commands with the same transaction scope without closing the
connection, use a single connection and multiple sessions with MARS. With either data
access pattern, only a single physical connection to SQL Server is needed.
</p>
        <img width="0" height="0" src="http://www.sqlskills.com/blogs/bobb/aggbug.ashx?id=d4b5729c-f2de-4ca9-8095-19f0f0b40115" />
        <br />
        <hr />
This blog is sponsored by <a href="http://www.sqlskills.com">SQLSkills</a>. 
</div>
    </content>
  </entry>
  <entry>
    <title>Accessing multiple servers with the SQL Server 2008 PowerShell provider</title>
    <link rel="alternate" type="text/html" href="http://www.sqlskills.com/blogs/bobb/2008/03/25/AccessingMultipleServersWithTheSQLServer2008PowerShellProvider.aspx" />
    <id>http://www.sqlskills.com/blogs/bobb/PermaLink,guid,9974f4aa-89cf-48dd-a8a8-1b5b27b2c62f.aspx</id>
    <published>2008-03-25T00:21:58.002875-07:00</published>
    <updated>2008-03-25T00:21:58.002875-07:00</updated>
    <category term="SQL Server 2008" label="SQL Server 2008" scheme="http://www.sqlskills.com/blogs/bobb/CategoryView,category,SQL%2BServer%2B2008.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Short post this evening...
</p>
        <p>
Just in case anyone else flails around looking for this feature, its right under your
nose. When you use the PowerShell SQL Server 2008 provider, you have visibility to
a single, local machine (and all its SQL Server instances you can access with integrated
security) by default. To get access to multiple machines using the provider, simply <strong>reference
a SQL provider path that contains that machine name</strong>. If the (Windows) principal
has access to the other machine's SQL Server instance, it will open a connection using
Windows auth.
</p>
        <p>
For example, say that I'm on a machine named zmv20. I have access to machine zmv21's
SQL Server instance as well.
</p>
        <p>
&gt;cd SQLSERVER:\SQL<br />
&gt;dir
</p>
        <p>
MachineName<br />
-----------<br />
zmv20
</p>
        <p>
&gt;dir zmv21  &lt;---- makes a connection to zmv21
</p>
        <p>
Instance Name  (on zmv21)<br />
-------------<br />
DEFAULT
</p>
        <p>
&gt;dir           &lt;---- now you
can "see" zmv21 too
</p>
        <p>
MachineName<br />
-----------<br />
zmv20<br />
zmv21
</p>
        <p>
Using the test-path cmdlet also works. 
</p>
        <p>
&gt;test-path SQLSERVER:\SQL\zmv22  &lt;---- can I login to this machine too?
</p>
        <p>
But bear in mind that this is subject to a connection timeout lag. The error message
indicates that its first using WMI to obtain the machine connection.
</p>
        <p>
Of course, all this is doc'd in SQL Server Books Online. Where I missed it a few times...I
was looking for the equivalent of a "connect" command. You don't need one.
</p>
        <img width="0" height="0" src="http://www.sqlskills.com/blogs/bobb/aggbug.ashx?id=9974f4aa-89cf-48dd-a8a8-1b5b27b2c62f" />
        <br />
        <hr />
This blog is sponsored by <a href="http://www.sqlskills.com">SQLSkills</a>. 
</div>
    </content>
  </entry>
  <entry>
    <title>More about sparse columns and column_sets</title>
    <link rel="alternate" type="text/html" href="http://www.sqlskills.com/blogs/bobb/2008/03/20/MoreAboutSparseColumnsAndColumnsets.aspx" />
    <id>http://www.sqlskills.com/blogs/bobb/PermaLink,guid,83abbc74-1a02-4734-93a2-06fae51a72cb.aspx</id>
    <published>2008-03-20T11:03:07.18525-07:00</published>
    <updated>2008-03-20T11:03:07.18525-07:00</updated>
    <category term="SQL Server 2008" label="SQL Server 2008" scheme="http://www.sqlskills.com/blogs/bobb/CategoryView,category,SQL%2BServer%2B2008.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I'm still getting used to the new sparse column feature in SQL Server 2008. 
</p>
        <p>
I'd just read in the BOL definition of ALTER TABLE that you can add a column_set to
an existing table. I was converting a sample app from an EAV (entity attribute value)
design to sparse columns. I used the existing "attribute-value" table to create the
sparse columns, then created the table. I then went back to add the column_set with
ALTER TABLE after the fact.
</p>
        <p>
alter table sparsetest3 add spcolset xml column_set for all_sparse_columns
</p>
        <p>
Received this error message:<br />
Msg 1734, Level 16, State 1, Line 1<br />
Cannot create the sparse column set 'spcolset' in the table 'sparsetest3' because
the table already contains a sparse column set. A table cannot have more than one
sparse column set.
</p>
        <p>
Huh? I figured that I should be able to add the column_set and filed the lack of this
capability as a bug. It came back as "by design".  And doc'd in BOL that way.
The fact that its by design makes perfect sence and helped to solidify in my mind
how the column_set works. 
</p>
        <p>
In a "normal" table (even with sparse columns) without a column_set, "select * from
table" returns all of the columns. If a table has a sparse column_set, "select * from..."
behaves differently, and returns only the non-sparse columns and the column_set column. NOT
the individual sparse columns. You can INSERT or UPDATE this table by using only
the column set. When you update using a column_set, all of the sparse columns that
you don't specify are set to NULL. You can even update to column_set to NULL itself,
which NULLs out all of the sparse columns.
</p>
        <p>
The reason that "A column set cannot be added to a table if that table already contains
sparse columns" (BOL exact wording under "Guidelines for using sparse columns") is
that it could break existing code that uses "select * from...". Imagine:
</p>
        <p>
create table sparsetab (<br />
 id int identity primary key,<br />
 col1 int,<br />
 spcol2 int sparse<br />
);
</p>
        <p>
select * from sparsetab -- returns spcol2<br />
-- add column_set (this is disallowed, but imagine it DID work)<br />
select * from sparsetab -- doesn't return spcol2, only the column_set, can break code
that relies ont spcol2
</p>
        <p>
And BOL is right in ALTER TABLE as well.
</p>
        <p>
create table sparsetab2 (<br />
 id int identity primary key,<br />
 col1 int<br />
);<br />
go<br />
-- add first sparse column and column_set at the same time, works fine.<br />
alter table sparsetab2 
<br />
 add spcol1 int sparse,<br />
       spcolset xml column_set for all_sparse_columns<br />
go
</p>
        <p>
You can even, as BOL indicates, add a column_set to a table that does not yet have
a sparse column.
</p>
        <p>
create table sparsetab4 (<br />
 id int identity primary key,<br />
 spcolset xml column_set for all_sparse_columns<br />
);<br />
go<br />
-- Now you can add sparse columns, they use the column_set
</p>
        <p>
The ONLY issue I have is with the error message 1734 at the beginning of the
post. It's misleading, because I DON'T already have a column_set. But I DO already
have sparse columns.
</p>
        <p>
In last sparse column correction from a long-ago post. I'd heard (early on) that you
would be able to have over 4 million sparse columns (actually sizeof(int) of them).
This turns out to be incorrect, it was announced lately that the limit will be 30,000
sparse columns. And, in the current CTP6 you can only have 1024 total columns (in
as previous versions); the sparse column limit will be changed sometime before RTM.
</p>
        <p>
Amazingly, when I quoted the 30,000 column limit to a class last week, there was a
groan. One student told me his EAV table already had over 60,000 unique attributes.
30,000 wouldn't be enough...must be a HUGE EAV table. That's the motivation for sparse
column. Also, his EAV table had the "value" column defined as SQL_VARIANT. That's
the other motivation, sparse columns are strongly typed. Although inserting through
the column_set always uses a string (nvarchar) as the value, and attempts to convert
string to the definied data type for specific columns.
</p>
        <img width="0" height="0" src="http://www.sqlskills.com/blogs/bobb/aggbug.ashx?id=83abbc74-1a02-4734-93a2-06fae51a72cb" />
        <br />
        <hr />
This blog is sponsored by <a href="http://www.sqlskills.com">SQLSkills</a>. 
</div>
    </content>
  </entry>
</feed>