<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.3" xml:lang="en-us" xmlns="http://purl.org/atom/ns#">
  <title>Bob Beauchemin's Blog</title>
  <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/" />
  <modified>2005-07-25T11:55:48.3125000-07:00</modified>
  <tagline>newtelligence powered</tagline>
  <generator>newtelligence dasBlog 1.6.4121.0</generator>
  <author>
    <name>Bob Beauchemin</name>
  </author>
  <entry>
    <title>Blog Moving Soon</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=627f602c-542b-4779-b072-9efdf3c37b78" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=627f602c-542b-4779-b072-9efdf3c37b78</id>
    <issued>2005-07-25T11:55:48.1875000-07:00</issued>
    <modified>2005-07-25T11:55:48.3125000-07:00</modified>
    <created>2005-07-25T11:55:48.1875000-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      This is just a little friendly message to let you'all know that the blog is moving
      soon. If you enjoy reading, watch for me to appear in the SQL community.
   </p>
        <p>
      Cheers, Bob
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=627f602c-542b-4779-b072-9efdf3c37b78" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Changing SQL Login password with the utilities</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=5f47edac-8e85-40f6-8eeb-af1c0a2db22c" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=5f47edac-8e85-40f6-8eeb-af1c0a2db22c</id>
    <issued>2005-07-06T16:17:11.4531250-07:00</issued>
    <modified>2005-07-06T16:17:11.5000000-07:00</modified>
    <created>2005-07-06T16:17:11.4531250-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      After writing a blog entry on "<a href="http://staff.develop.com/bobb/weblog/#a24ae4f39-33e3-4648-9e79-783a4d0ed54b">How
      DO you change your SQL Login Password</a>" and complaining that "neither" SSMS nor
      SQLCMD allows you to change this" I was using this feature on the June CTP and, lo
      and behold, both of these utilities allow changing your password.
   </p>
        <p>
      SQLCMD -? shows<br />
      -z new password<br />
      -Z new password and exit
   </p>
        <p>
      And in SSMS, if you use a SQL login whose password has expired (or is designated "must
      change on first login") you get a nice, GUI-based “old password/new password/re-enter
      new password” prompt.
   </p>
        <p>
      Don't know how I missed this before, sorry for complaining. If you use SQL Logins
      with login policies, code like this really should be part of your application. Perhaps
      a way to change password before it expires as well, like SQLCMD does. I'm still surprised
      that SSMS doesn't have this option on the login screen.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=5f47edac-8e85-40f6-8eeb-af1c0a2db22c" />
      </body>
    </content>
  </entry>
  <entry>
    <title>I'm Database Geek of the Week (last week)</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=1e285ff8-c461-41e8-ac57-b1e355d68089" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=1e285ff8-c461-41e8-ac57-b1e355d68089</id>
    <issued>2005-07-05T19:53:40.5312500-07:00</issued>
    <modified>2005-07-05T19:53:55.2812500-07:00</modified>
    <created>2005-07-05T19:53:40.5312500-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Sometime between when I left for Europe and when I started reading email that wasn't
      addressed "question from student" (yes, I do answer all those), <a href="http://www.simple-talk.com/2005/06/21/database-geek-of-the-week-bob-beauchemin/">my
      "Database Geek of the Week" interview got published</a>. By a guy from Red Gate Software
      named Douglas Reilly.
   </p>
        <p>
      The way I think this works is that someone suggests you for this honor. I don't know
      who suggested me, I wasn't told. Then Douglas writes some nice stuff about you and
      thinks up some questions he'd like to ask. Custom questions, too, from the way they
      sounded. Cool. He sends them to you and you answer in email. And he publishes questions
      and answers. Interesting concept. 
   </p>
        <p>
      On "my interview" page, there are links to articles (not mine) about "ADO.NET Data
      Access" and ".NET 2.0 transaction model". How relevent and coincidental.
   </p>
        <p>
      Anyway, I'm honored...that someone would take the time to write questions and nice
      stuff about me and blog/ezine-style publish it. Thanks Douglas.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=1e285ff8-c461-41e8-ac57-b1e355d68089" />
      </body>
    </content>
  </entry>
  <entry>
    <title>It's been a whole year</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=8f7c64c8-e0e8-4944-9ac6-70c9e88aeda1" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=8f7c64c8-e0e8-4944-9ac6-70c9e88aeda1</id>
    <issued>2005-07-05T19:37:05.1250000-07:00</issued>
    <modified>2005-07-05T19:37:05.1875000-07:00</modified>
    <created>2005-07-05T19:37:05.1250000-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Wow. I was going through old blog entries looking for some unique insight (TM) I had,
      once upon a time, about SQL Server 2005 error handling in SQLCLR. Found a bunch of
      stuff, not sure how unique (or insightful) it was. But...
   </p>
        <p>
      I realized I've been blogging over a year. First entry, July 1 2004 That's amazing,
      because I wasn't sure I understood the zen of blogging when I started. Not sure I
      do now either, but its been a whole year. I realize the entries have been slowing
      down as SQL Server 2005 has been coming closer to release. And as I start in earnest
      on the update of the "First Look" book. No technical content to this entry, just mindless
      reflection.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=8f7c64c8-e0e8-4944-9ac6-70c9e88aeda1" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Au revoir, Ascend</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=a01c3ef6-9ec1-4a47-a1c0-79f108678e98" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=a01c3ef6-9ec1-4a47-a1c0-79f108678e98</id>
    <issued>2005-07-03T20:34:46.3281250-07:00</issued>
    <modified>2005-07-04T05:59:02.0312500-07:00</modified>
    <created>2005-07-03T20:34:46.3281250-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I just finished up our last gig for SQL Server 2005 Ascend last week in Paris (OK...
      in Les Ulis). It was my first class on the June CTP, and it seemed to go without
      incident. Students were enthusiastic and a good time appeared to be had by all. There
      are a two more "rescheduled for a later date" classes still to be done, but this is
      for all intents and purposes the end of Ascend phase 2 for us.
   </p>
        <p>
      The only technical surprise of the week came when I added some rows to a table containing
      a UDT. After I did a "SELECT * FROM udttab" from SSMS, the rows are displayed in binary
      (back to the original behavior a la beta1), but when the UDT column contained a NULL
      value, I got the well-known "Assembly ... or one of its dependencies cannot be found".
      After making the assembly available I received, not the expected database NULL, but
      the binary value that corresponded to my UDT when it was NULL. Hmmm. It sounds like
      a few folks have been asking about this, and its been reported as a bug already. Interesting
      behavior. Using SQLCMD, the value NULL is displayed as you'd expect.
   </p>
        <p>
      I just wanted to thank the folks from Ascend and thank the students as well. It's
      been a great time, I've enjoyed the traveling, the technical challange, and the nice
      reception that I received everywhere. Au revoir!
   </p>
        <p>
      Now on to the release...keep on watching for more information.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=a01c3ef6-9ec1-4a47-a1c0-79f108678e98" />
      </body>
    </content>
  </entry>
  <entry>
    <title>SqlNotificationRequest changes</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=069a6b19-7f5b-40b2-be22-2a888c54fc81" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=069a6b19-7f5b-40b2-be22-2a888c54fc81</id>
    <issued>2005-06-12T23:13:53.0000000-07:00</issued>
    <modified>2005-06-12T23:13:53.2031250-07:00</modified>
    <created>2005-06-12T23:13:53.0000000-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      In the April CTP of .NET 2.0, I chanced upon some changes to SqlNotificationRequest,
      using my favorite tool, <a href="http://www.aisto.com/roeder/dotnet/">.NET Reflector </a>and
      my one my favorite investigative techniques, called “follow the error message”. 
   </p>
        <p>
      It turns out that two properties in SqlNotificationRequest the <em>id</em> and <em>Service</em> properties
      are about to be replaced. They still work but are marked “do not use, to be
      removed”. They'll but replaced by the <em>UserData</em> and <em>Options </em>properties.
      UserData appears to be a straight replacement for id, probably mandated
      by the .NET naming police. The naming police are possibly the same folks who replaced
      SqlContext.GetPipe and GetWindowsIdentity methods with the Pipe and WindowsIdentity
      properties. Making things consistent is nice, but its hard on folks who write things
      like demos, labs, slides, books, and articles. 
   </p>
        <p>
      SqlNotificationRequest.Options is more interesting. While the Service property only
      let you specify the Service Broker Service name, options gives you...you guessed it,
      more options. You can also specify which database the broker service lives in or even
      the Broker indentifier. 
   </p>
        <p>
      Suppose you wanted to listen for query notifications on a query on a table in the
      pubs database, using a service named “MyService” that also lives
      in the pubs database in your local SQL Server instance. Using the soon-obsolete Service
      and Id properties it would look like this:
   </p>
        <p>
      SqlNotificationRequest not = new SqlNotificationRequest();<br />
      not.Id = Guid.NewGuid().ToString();<br />
      not.Service = "MyService";<br />
      not.Timeout = 0;<br />
      // now hook it up to the right SqlCommand
   </p>
        <p>
      Using the new syntax would look like this:
   </p>
        <p>
      SqlNotificationRequest not = new SqlNotificationRequest();<br />
      not.UserData = Guid.NewGuid().ToString();<br />
      not.Options = "service=MyService;local database=pubs";<br />
      not.Timeout = 0;<br />
      // now hook it up to the right SqlCommand
   </p>
        <p>
      You can even use the Service Broker identifier GUID (look it up by “select name,
      service_broker_guid from sys.databases”) in the Options like this:
   </p>
        <p>
      //NB: Service Broker service names are case sensistive!<br />
      //not.Options = "service=MyService;local database=pubs";<br />
      not.Options = "service=MyService;broker instance=CE086F11-C691-47F1-A8B6-1B7BD59EA6AE";
   </p>
        <p>
      This property gives you the option of pointing at a service in a different database
      in the same instance, or even a different instance, subject to sercurity, of course.
      Happy query notifying. I gotta go fix a paper. And a book chapter. And a slide.
      And a lab. And... geez.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=069a6b19-7f5b-40b2-be22-2a888c54fc81" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Outstanding Service Broker book</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=be510e05-7ea5-4cd2-b7b3-143a58b43ee5" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=be510e05-7ea5-4cd2-b7b3-143a58b43ee5</id>
    <issued>2005-06-12T22:47:56.0625000-07:00</issued>
    <modified>2005-06-12T22:47:56.2500000-07:00</modified>
    <created>2005-06-12T22:47:56.0625000-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      While at TechEd, I purchased the first computer book I've actually had to shell out
      hard cash for in quite a while, <a href="http://www.mannpublishing.com/Catalog/BookDetail.aspx?BookID=37">The
      Rational Guide to SQL Server 2005 Service Broker</a> by Roger Wolter. Congratulations,
      Roger, you've got a winner here! Weighing in at just under 250 pages, this book is
      an explanation of Service Broker from its raison d'etre to the most intricate details.
      The first chapter says it's meant to compliment the info in the BOL, and the material
      fits right in while BOL leaves off.
   </p>
        <p>
      I've had the pleasure of having Roger explain the Service Broker to me in person,
      quite a few times, but the book lays it all out as though you'd hung out with him
      for months. A great explanation of this extermely powerful but often misunderstood
      feature of SQL Server 2005. You might have to wait in line for this one, but it's
      worth waiting for. I got mine autographed too.
   </p>
        <p>
      Are there any superlatives I've left out? Well if so, fill 'em in yourself.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=be510e05-7ea5-4cd2-b7b3-143a58b43ee5" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Back From TechEd</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=dd5b73c3-4d7a-413d-a7d9-680b94076b34" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=dd5b73c3-4d7a-413d-a7d9-680b94076b34</id>
    <issued>2005-06-12T22:30:04.2187500-07:00</issued>
    <modified>2005-06-12T22:30:04.4062500-07:00</modified>
    <created>2005-06-12T22:30:04.2187500-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I meant to blog from TechEd but with all the activity, I never got the time.
      The talk on when to use T-SQL and when to use SQLCLR drew an overflow crowd, and folks
      seemed to really like it. Thanks to all of you who attended. 
   </p>
        <p>
      To attempt to summarize in one sentence, the “official” T-SQL vs SQLCLR
      positioning exists in the paper, “<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsql90/html/sqlclrguidance.asp">Using
      CLR Integration in SQL Server 2005</a>” by Balaji Rathakrishnan, Christian Kleinerman,
      Brad Richards, Ramachandran Venkatesh, Vineet Rao. Since this is the list of folks
      who designed the product, it lays out the trade-offs and intended usage. Although
      the specifics have changed a bit since the paper was written (combined provider replacing
      SqlServer provider, new UDF coding style, etc) the paper's main points are just as
      valid today as they were when it was originally written, according to the authors.
   </p>
        <p>
      Other than the talk, I spent a lot of time at the SQL Server cabana, hanging out with <a href="http://sqljunkies.com/WebLog/ktegels">Kent
      Tegels </a>and the folks on the SQL Server team, answering and asking questions.
      I especially enjoyed the “SQL Server 2005 BI Power Hour” talk, showing
      off use cases for SQL Server Integration Services, Reporting Services, Analysis Services,
      and Notification Services. My favorite demo showed how Reporting Services could be
      used to design a template for a Notification Services message by <a href="http://www.bookpool.com/sm/0672326647">Shyam
      Pather</a>. Very cool, Shyam. I hope we'll be seeing many more ways to integrate the
      various SQL Server 2005 product features in future.
   </p>
        <p>
      I also spent quite a lot of time catching up with many old friends who I haven't
      seen in a long time. And also making some new friends. I don't do a lot of conferences
      as a rule, but this one was well worth it.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=dd5b73c3-4d7a-413d-a7d9-680b94076b34" />
      </body>
    </content>
  </entry>
  <entry>
    <title>What's a truncation exception?</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=c8ce155a-39ed-4553-b2c3-d02bbbb04c3f" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=c8ce155a-39ed-4553-b2c3-d02bbbb04c3f</id>
    <issued>2005-06-03T14:43:54.6250000-07:00</issued>
    <modified>2005-06-03T14:45:04.8281250-07:00</modified>
    <created>2005-06-03T14:43:54.6250000-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I commonly do a demo when teaching SQL Server 2005 where I write a SQLCLR UDF that's
      returns the string "Hello World". The define it, sans VS autodeploy, like this.
   </p>
        <p>
      CREATE FUNCTION somefunc()<br />
      RETURNS NVARCHAR(4)<br />
      AS EXTERNAL NAME MyAssembly.MyClass.MyFunction
   </p>
        <p>
      When invoked, it returns "Hell", silently truncating the string the CLR sent it. UNTIL
      Apr CTP. Now its returns "Truncation Exception". Surprise, surprise... After reporting
      this as a bug, I was told that "That's the way its supposed to work. To prevent silent
      data loss."
   </p>
        <p>
      I agree. Except now its works differently than this T-SQL function:
   </p>
        <p>
      CREATE FUNCTION somefuncT()<br />
      RETURNS NVARCHAR(4)<br />
      AS<br />
      BEGIN<br />
        RETURN N'Hello World'<br />
      END
   </p>
        <p>
      Correct again, it does work differently. The idea is the T-SQL one still silently
      truncates data, but the SQLCLR one does "the right thing". The T-SQL one still works
      the way it does for backward compatibility only. Maybe in the next release they'll
      work the same. 
   </p>
        <p>
      So what's your preference, backward compatibility or lack of silent data loss (and
      exceptions)? Just curious...
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=c8ce155a-39ed-4553-b2c3-d02bbbb04c3f" />
      </body>
    </content>
  </entry>
  <entry>
    <title>How DO you change your SQL Login password?</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=24ae4f39-33e3-4648-9e79-783a4d0ed54b" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=24ae4f39-33e3-4648-9e79-783a4d0ed54b</id>
    <issued>2005-06-03T14:27:43.0312500-07:00</issued>
    <modified>2005-06-12T23:14:44.9375000-07:00</modified>
    <created>2005-06-03T14:27:43.0312500-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      SQL Server 2005 will, by default on Windows Server 2003 systems, enforce password
      policies for SQL Server logins as well as Windows logins. Nice feature, but this means
      that your SQL Server login password can expire. So how do you change it? Well certainly
      the DBA can change it as (s)he always has, but you'd hate to bother your DBA every
      42 days. Never mind what the DBA would think of that... And the user interface programs,
      SSMS and SQLCMD don't yet provide that feature. Neither does Visual Studio 2005 Server
      Explorer.
   </p>
        <p>
      The functionality does exist in the supported database APIs. That is ADO.NET, OLE
      DB, and ODBC. With ADO.NET you have to be using 2.0, with OLE DB and ODBC the new
      SNAC providers are required. In ODBC, there is a new connection option SQL_COPT_SS_OLDPWD.
      In OLE DB there's an Old Password connection string parameter. In ADO.NET 2.0 SqlClient
      it's a static method on SqlConnection called (amazingly enough) ChangePassword. It
      takes to strings as input and here's how it works.
   </p>
        <p>
      You change your connection code to use a loop, like while conn.ConnectionState ==
      ConnectionState.Closed. Loop as many times as you like, most folks will probably loop
      twice. Bracket your calls to Open with a try-catch block. In the catch block, look
      for the following error codes:
   </p>
        <p>
      18487 - Password Expired<br />
      18488 - Must change password on first login
   </p>
        <p>
      If you get one of these call ChangePassword. You'd think that the parameters are "old
      password, new password". They are not. The first parameter must have enough information
      to connect to the server, including at minimum server name, your userid and your old
      password. The second parameter is just your new password. This changes your password,
      now change your connection string and Open again.
   </p>
        <p>
      There are a couple of repercussions/refinements to this:
   </p>
        <p>
      1. You obviously shouldn't even think about keeping password in the program, if you
      ever did this before. Check out <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/vsgenerics.asp">my
      MSDN article </a>for the built-in place to keep connection strings now.<br />
      2. This can only be used to change passwords on a SQL Server 2005 server. And only
      SQL Login passwords, naturally. It requires that the server and client be using the
      new network libraries.<br />
      3. There is no standard "New Password", "Old Password" GUI box. You need to make one
      yourself. Standard cavaets for passwords in GUIs apply.<br />
      4. There is no way to currently tell with standard SQL Server calls, how soon your
      password will expire. Think "Your password will expire in N days" message we all know
      and love.
   </p>
        <p>
      So that's it. I have a "rough and ready" code example (that I wrote on a bet with
      Larry Chestnut at an Ascend gig a while ago) I'll probably clean up and post
      on my website eventually but this gives you the basic idea. And BTW, this isn't meant
      to push SQL Logins on anyone. If you can use only Windows logins in SQL Server (any
      release) and forgo SQL Logins entirely, PLEASE DO.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=24ae4f39-33e3-4648-9e79-783a4d0ed54b" />
      </body>
    </content>
  </entry>
  <entry>
    <title>They did it! Relative paths in SSMS projects</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=27cfab13-b74d-4fd0-a99f-03678cee552e" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=27cfab13-b74d-4fd0-a99f-03678cee552e</id>
    <issued>2005-05-26T08:21:17.5156250-07:00</issued>
    <modified>2005-05-26T08:21:17.6875000-07:00</modified>
    <created>2005-05-26T08:21:17.5156250-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      For a long time I've been griping that SSMS projects (SQL Server Script projects)
      use absolute pathnames rather than relative paths. I didn't think it was going to
      be fixed, I'd received a reply “this works as expected”. This week, as
      I was explaining to students why they had the put the SSMS projects in a specific
      directory as always, someone noticed that it's fixed...relative path names for files
      in SSMS projects. You must open and save each project to get this behavior, but...works
      now.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=27cfab13-b74d-4fd0-a99f-03678cee552e" />
      </body>
    </content>
  </entry>
  <entry>
    <title>A Second Look at SQL Server 2005 for Developers</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=fdaa87e0-2c33-4a44-b80f-dbd4e8561a03" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=fdaa87e0-2c33-4a44-b80f-dbd4e8561a03</id>
    <issued>2005-05-22T11:15:13.9531250-07:00</issued>
    <modified>2005-05-22T11:49:29.7343750-07:00</modified>
    <created>2005-05-22T11:15:13.9531250-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I've heard rumblings on various newsgroups that our book “<a href="http://www.awprofessional.com/bookstore/product.asp?isbn=0321180593&amp;rl=1">A
      First Look at SQL Server 2005 for Developers</a>” is getting a little long in
      the tooth in some topics. Features got postponed in the client area, some syntax changed,
      the managed providers were combined, and so forth. I've been reporting on changes
      via this blog and also have been trying to keep a running scorecard of changes
      on the <a href="http://staff.develop.com/bobb/sql2005book/">book's website</a>. This
      should be updated more for the next CTP or so; I've been waiting for official beta3.
   </p>
        <p>
      In the meantime, we also signed to produce an updated version for SQL Server RTM.
      No, it won't be called “A Second Look...”, the title is set to be “A
      Developer's Guide to SQL Server 2005”. It won't be exactly at RTM because this
      time we'd like to wait to see what the final feature set looks like “when we
      open the box“. We're also going to add a chapter on SMO. Thanks for supporting
      the first one, and taking a look at the new SQL Server features with us.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=fdaa87e0-2c33-4a44-b80f-dbd4e8561a03" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Dan Sullivan is blogging</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=df7cdcbd-40c5-4c5e-b1a5-bc1a66a0bb3d" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=df7cdcbd-40c5-4c5e-b1a5-bc1a66a0bb3d</id>
    <issued>2005-05-22T10:55:49.3593750-07:00</issued>
    <modified>2005-05-22T10:55:49.5468750-07:00</modified>
    <created>2005-05-22T10:55:49.3593750-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      On my latest visit to the <a href="http://www.sqlservicebroker.com">SQL Service Broker
      Developer Spot</a>, I noticed that my friend and coauthor Dan Sullivan <a href="http://spaces.msn.com/members/dsullivan/">is
      blogging </a>now. And that two of Dan's first three posts have been accompanied by
      article-sized papers. Subscribed.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=df7cdcbd-40c5-4c5e-b1a5-bc1a66a0bb3d" />
      </body>
    </content>
  </entry>
  <entry>
    <title>XML Schema for the truly lazy</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=e67c5e74-3afc-43b4-9aeb-b9c4ce6394c4" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=e67c5e74-3afc-43b4-9aeb-b9c4ce6394c4</id>
    <issued>2005-05-16T00:02:45.4375000-07:00</issued>
    <modified>2005-05-16T00:02:45.6875000-07:00</modified>
    <created>2005-05-16T00:02:45.4375000-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Here's something I've noticed you can do with SQL Server 2005 and Visual Studio 2005.
   </p>
        <p>
      Take a set of XML documents with the same basic structure. Load one into Visual Studio
      2005. Click on the XML menu, Create XML Schema. Make any refinements to the XML schema
      that is produced that you want, based on your knowledge of the document content. Note
      that the XML schema is created without the "targetNamespace" attribute. Save to disk.
   </p>
        <p>
      Open an SSMS 2005 (that's SQL Server Management Studio) query window. Paste in your
      XML schema and use it to create an XML SCHEMA COLLECTION (of one XML schema). Now
      you can use the XML SCHEMA COLLECTION to strongly type an XML data type, in a SQL
      table column, variable, what-have-you.
   </p>
        <p>
      You can also do XQuery (strongly typed) without using namespace declarations in XQuery
      preface or namespace prefixes in your query text. 
   </p>
        <p>
      This works because each XML SCHEMA COLLECTION is permitted to have a single "no namespace"
      schema. SQL Server wouldn't recognize the noNamespaceSchemaLocation (yes, schemas
      with no namespace are allowed by the XML Schema spec) even if you had it because it
      does not resolve schemas that don't "live in" SQL Server. And the VS-produced schema
      specifies attributeFormDefault="unqualified" and elementFormDefault="qualified" so
      the queries work.
   </p>
        <p>
      That's for the truly lazy and after all, probably evil to true schema afficianados...so
      go back and put a namespace in your XML Schema, and use prefixes or default element
      namespace in XQuery preface. 
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=e67c5e74-3afc-43b4-9aeb-b9c4ce6394c4" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Combined provider: transactions and the return of 6522</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=08223a98-0900-41f0-9884-02d25b989dc2" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=08223a98-0900-41f0-9884-02d25b989dc2</id>
    <issued>2005-05-15T23:06:35.4531250-07:00</issued>
    <modified>2005-05-15T23:06:35.5937500-07:00</modified>
    <created>2005-05-15T23:06:35.4531250-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      With April CTP came the new combined managed provider replaces System.Data.SqlServer
      with a new improved, works in-process or out, System.Data.SqlClient. I just call it
      "the combined provider" now. People that didn't work on the betas will look at me
      funny when the product RTMs; "was there ever anything other than System.Data.SqlClient?".
      Why yes, Virginia...
   </p>
        <p>
      With the new provider, some of the error handling problems passing SQLCLR errors back
      to T-SQL resurfaced. Some work-arounds didn't work-around the same way. Some people
      noticed this on the newsgroups. I reported a bug on first day, but didn't want to
      be too "complain-y" here. And noticed what work-arounds (AKA coding practices so that
      things work right) still work. 
   </p>
        <p>
      The most severe problem was that if you tried to catch a SQLCLR error with a dummy
      try-catch block in your CLR code, AND executed your SQLCLR code inside a T-SQL TRY-CATCH,
      you got:
   </p>
        <p>
      Msg 0, Level 11, State 0, Line 0 
      <br />
      A severe error occurred on the current command. The results, if any, 
      <br />
      should be discarded. 
   </p>
        <p>
      Oh. That was in SSMS. In SQLCMD you got nothing. No error from the CATCH, no results.
   </p>
        <p>
      Bug is reported as fixed today. Cool. Although it was the fourth CTP after beta2,
      this was first *ever* release of the combined provider. They'll iron it out. Can't
      wait to try it in next CTP. Then I'll write about it.
   </p>
        <p>
      BTW, transactions are MUCH improved in the new combined provider. Not only can you
      use System.Transactions (<a href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=46d6d573-06a0-4409-b491-f478cd5d53bd">try
      rolling back in that trigger with Transaction.Current.Rollback() now</a>), but using
      BeginTransaction and nesting transactions in nested stored procedures works exactly
      like it does in T-SQL. Excellent.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=08223a98-0900-41f0-9884-02d25b989dc2" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Go ahead, make a validation mistake...</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=173b7dff-be6e-4fbe-bf18-81a02482f0b1" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=173b7dff-be6e-4fbe-bf18-81a02482f0b1</id>
    <issued>2005-05-15T22:43:07.7812500-07:00</issued>
    <modified>2005-05-15T23:10:23.1718750-07:00</modified>
    <created>2005-05-15T22:43:07.7812500-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      One of the nice surprises in the April CTP is that SQL Server 2005 XML schema validation
      errors come with a location now. That's handy. Here's an example:
   </p>
        <p>
      Msg 6926, Level 16, State 1, Line 1<br />
      XML Validation: Invalid simple type value: '1134'. 
      <br />
      Location: /*:Invoice[1]/*:LineItems[1]/*:LineItem[1]/*:Sku[1]
   </p>
        <p>
      Even better would be a line and column number that points out where the processor
      thinks this error in a value() method happened.
   </p>
        <p>
      Msg 2389, Level 16, State 1, Line 4<br />
      XQuery [xmlinvoice.invoice.value()]: 'value()' requires a singleton (or empty sequence),
      found operand of type 'xdt:untypedAtomic *'
   </p>
        <p>
      I know what was wrong with my query (i.e. what the message means) its become one of
      my favorite error message because it reminds me that this implementation does static
      type checking, but WHERE is there an xdt:untypedAtomic *? I guess there's no way to
      tell me where in a single XPath expression I went wrong, but if there are multiple lines
      or FLWOR expressions, give me a hint. 
   </p>
        <p>
      The revised (I think) error at least tells me which "value()" function has a bad query.
      So if there are multiple value()s in the SQL query and one is wrong, I know which
      one. 
   </p>
        <p>
      Of course, if I got all my XQuery statements right, I wouldn't have this problem...
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=173b7dff-be6e-4fbe-bf18-81a02482f0b1" />
      </body>
    </content>
  </entry>
  <entry>
    <title>DataDirect providers...and some ADO.NET 2.0 beta2 changes</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=c783b51a-862b-4d0e-ac95-33af58bc25dd" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=c783b51a-862b-4d0e-ac95-33af58bc25dd</id>
    <issued>2005-05-15T22:25:45.1562500-07:00</issued>
    <modified>2005-05-15T22:25:45.3437500-07:00</modified>
    <created>2005-05-15T22:25:45.1562500-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Realized that I haven't blogged in a while. I been ...uh...working on stuff and traveling
      a lot lately. Big surprise, right? This week I'll be on vacation. Traveling. Now I
      understand what the term “busman's holiday“ means.
   </p>
        <p>
      Last weekend I had dinner with Rob Steward of DataDirect Technologies at his house. The
      ribs were great (thanks Rob) and while they were cooking I asked him if there
      would be support of rich schema metadata, base classes, and the neat stuff I wrote
      about I my ADO.NET 2.0 series of articles in DataDirect's line of ADO.NET data providers.
      He said that there would be, of course. They want to show up in that neat new Visual
      Studio 2005 connection dialog (that lists the ADO.NET data providers rather than OLE
      DB providers) too. And make a good showing in Server Explorer.
   </p>
        <p>
      Then I asked about whether their classes derived from System.Data.ProviderBase's.
      This isn't the base classes in System.Data.Common (they support those), but the base
      classes to assist provider writers. Surprise! Those classes are now protected sealed
      in .NET 2.0 beta2. Oh. Guess not, then.
   </p>
        <p>
      But they will support all the same things you'd have gotten from these classes
      for free: ConnectionStringBuilder, Connection Pooling (they always did support this),
      etc. So you'll be good to go. 
   </p>
        <p>
      Also, in looking through DbProviderFactory and friends, the SupportedClasses property
      is removed. That was the one that told you which classes (like Connection, Command,
      etc) the provider actually implemented. Gone from machine.config entries too. Wonder
      why...
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=c783b51a-862b-4d0e-ac95-33af58bc25dd" />
      </body>
    </content>
  </entry>
  <entry>
    <title>TechEd 2005 - I'll be there too</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=1629f2b2-f20e-4223-a600-58acb201104a" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=1629f2b2-f20e-4223-a600-58acb201104a</id>
    <issued>2005-05-08T16:52:44.3281250-07:00</issued>
    <modified>2005-05-08T16:52:44.4843750-07:00</modified>
    <created>2005-05-08T16:52:44.3281250-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Saw another <a href="http://sqljunkies.com/WebLog/ktegels/">Kent post on TechEd 2005</a>.
      I'll be there too (mixed marketing slogan message with SQLPass). I'm doing a <a href="http://www.msteched.com/content/sessions.aspx">talk</a> on
      “SQLCLR vs. T-SQL: Best Practices for Development in the Database”. Some
      folks on newgroups lately think that Microsoft may have mis-positioned this
      feature a bit. I disagree with this assessment. Come to the talk and see why.
   </p>
        <p>
      Gotta get some new logos on <a href="http://staff.develop.com/bobb/">my homepage</a>.
      After all, no one ever accused me of being a master of shameless self-promotion. Maybe
      an apprentice.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=1629f2b2-f20e-4223-a600-58acb201104a" />
      </body>
    </content>
  </entry>
  <entry>
    <title>SQLPass - I'll be there</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=22c85c6a-939d-4167-b41d-290ce179017d" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=22c85c6a-939d-4167-b41d-290ce179017d</id>
    <issued>2005-05-08T16:37:29.9687500-07:00</issued>
    <modified>2005-05-08T16:37:30.1406250-07:00</modified>
    <created>2005-05-08T16:37:29.9687500-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Catching up on blog-reading. <a href="http://sqljunkies.com/WebLog/ktegels/archive/2005/04/27/12942.aspx">Kent
      Tegels wondered </a>if I was speaking at <a href="http://www.sqlpass.org/events/summit05/index.cfm">SQLPass
      Community Summit</a>. Yep, I am.
   </p>
        <p>
      I'm doing a 2-day pre-con on (what else) What's new in SQL Server 2005 for developers.
      Also a tutorial session on XQuery for the “main conference”. I got “rained
      out” (to put it mildly) at last year's conference, maybe I'll have better luck
      this year.
   </p>
        <p>
      See you there.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=22c85c6a-939d-4167-b41d-290ce179017d" />
      </body>
    </content>
  </entry>
  <entry>
    <title>How to make a DBA smile</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=d44f04ed-ea07-4a3c-98e5-d308e2ce3680" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=d44f04ed-ea07-4a3c-98e5-d308e2ce3680</id>
    <issued>2005-05-08T16:30:59.2031250-07:00</issued>
    <modified>2005-05-08T16:30:59.3750000-07:00</modified>
    <created>2005-05-08T16:30:59.2031250-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Speaking of SQL Profiler brought this to mind. The number one feature that brings
      a smile to every DBA's face:
   </p>
        <p>
      GRANT ALTER TRACE TO [somedev]
   </p>
        <p>
      No longer do you have to listen to developers ask “make me SA so I can run the
      trace”. Actually, brings a smile to devs too, no longer do they have to beg
      for it. Just brings the gate over to a more granular permission level. You still do
      have to ask for ALTER TRACE now...
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=d44f04ed-ea07-4a3c-98e5-d308e2ce3680" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Mailing the graphic showplan to a friend</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=62f678b0-aec1-4f9e-844e-68c794d5d8ba" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=62f678b0-aec1-4f9e-844e-68c794d5d8ba</id>
    <issued>2005-05-08T16:06:23.9375000-07:00</issued>
    <modified>2005-05-08T16:06:24.1406250-07:00</modified>
    <created>2005-05-08T16:06:23.9375000-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I've always liked the graphic showplan in SQL Server query analyzer. The biggest hassle
      with it came when you wanted to send the plan to a friend. Or maybe MS support, but
      support is your friend too... right? You could send screenshots (which had the annoying
      habit of never displaying those hover-over stats) or go back to textual showplan.
   </p>
        <p>
      SQL Server 2005 has XML showplan and I'd once gone as far as to attempt to write a
      transform to display things nicely. No need. You can do the following from SQL Server
      Management Studio.
   </p>
        <p>
      1. Turn on the XML showplan<br />
         -- show estimated plan<br />
         SET SHOWPLAN_XML ON<br />
         GO
   </p>
        <p>
         -- or execute statement and show real plan<br />
         SET STATISTICS XML ON<br />
         GO
   </p>
        <p>
      2. This puts out your showplan as an XML data type column. Click the hyperlink to
      display the file.
   </p>
        <p>
      3. Save the XML showplan file with the magic suffix .SQLPlan 
   </p>
        <p>
      4. Now when you double-click on the .SQLPlan file, it opens in SSMS as the interactive
      showplan with the hover-over stats. 
   </p>
        <p>
      Cool, eh? You can do a variation of this with SQL Profiler too. In fact its easier
      with SQL Profiler. Now you can mail the .SQLPlan to a friend. With full fidelity.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=62f678b0-aec1-4f9e-844e-68c794d5d8ba" />
      </body>
    </content>
  </entry>
  <entry>
    <title>What happened to SNAC tracing in beta2?</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=c0c3f63e-6491-46ab-9257-f74ff72ac623" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=c0c3f63e-6491-46ab-9257-f74ff72ac623</id>
    <issued>2005-04-25T07:36:24.1875000-07:00</issued>
    <modified>2005-04-25T07:36:24.4843750-07:00</modified>
    <created>2005-04-25T07:36:24.1875000-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Since .NET 2.0 beta2 was released I've received a few inquiries about what happened
      to tracing SNAC (that's SQL Native Client). Looking at the adonetdiag.mof file, the
      SQLNCLI.1 entry (that's SNAC) was removed. I also got a solution/workaround from Glenn
      Johnson, who asked the question, then provided the answer faster than I could fly
      from Portland to San Jose and figure it out myself.
   </p>
        <p>
      The workaround for this is to:<br />
      1. Start with adonetdiag.mof that was posted in my article. <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnadonet/html/tracingdataaccess.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnadonet/html/tracingdataaccess.asp</a><br />
      2. Edit this .mof file to replace to entries for System.Data.SNI.B1 with System.Data.SNI.1
      from the new .mof file provided with beta2 . This file is in the Framework directory
      where .NET is installed.<br />
      3. Also change the file "ctrl.guid.adonet.beta1" from the article downloads to put
      in the new GUID for System.Data.SNI.1 (replace System.Data.SNI.Beta1). Run this scripts
      from the article as before.
   </p>
        <p>
      What appears to have happened is that:<br />
      a. SQLNCLI.1 entry was removed from adonetdiag.mof (SNAC is not part of .NET, so this
      makes sense)<br />
      b. The GUID for SNI tracing has changed.
   </p>
        <p>
      Happy tracing. Thanks Glenn.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=c0c3f63e-6491-46ab-9257-f74ff72ac623" />
      </body>
    </content>
  </entry>
  <entry>
    <title>A first demo of the combined data provider</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=6cac2fe3-dbf1-4f4c-b828-8a5fb3e8180e" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=6cac2fe3-dbf1-4f4c-b828-8a5fb3e8180e</id>
    <issued>2005-04-24T22:26:30.6718750-07:00</issued>
    <modified>2005-04-24T22:26:30.9062500-07:00</modified>
    <created>2005-04-24T22:26:30.6718750-07:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      When I did my first demonstration with the combined SqlClient and SqlServer provider
      in the April CTP version of SQL Server, I was a bit surprised. I wrote a simple stored
      procedure to run in the server, exactly the way I've always written it to run on the
      client (modulo sending results back to the client):
   </p>
        <p>
      // error handling elided<br />
      SqlConnection conn = new SqlConnection("context connection=true");<br />
      SqlCommand cmd = new SqlCommand("select * from authors", conn);<br />
      conn.Open();<br />
      SqlContext.Pipe.ExecuteAndSend(cmd);<br />
      cmd.Dispose();<br />
      conn.Dispose();
   </p>
        <p>
      I was surprised because this produced the error:
   </p>
        <p>
      System.Security.HostProtectionException: Attempted to perform an operation that was
      forbidden by the CLR host
   </p>
        <p>
      The protected resources (only available with full trust) were: All<br />
      The demanded resources were:SharedState
   </p>
        <p>
      After a little experimentation, I discovered they what was causing my problems was
      using Dispose(). Interestingly, I didn't technically need to use Dispose() (all .NET
      instances are available for garbage collection when the procedure invocation ends)
      and, in addition, using the C#/VB.NET "Using" contruct worked fine.
   </p>
        <p>
      using (SqlConnection conn = new SqlConnection("context connection=true"))<br />
      using (SqlCommand cmd = new SqlCommand("select * from authors", conn))<br />
      {<br />
        conn.Open();<br />
        SqlContext.Pipe.ExecuteAndSend(cmd);<br />
      }
   </p>
        <p>
      After consulting the Reflector, the two methods are different because the "using"
      feature calls IDisposable::Dispose on the SqlCommand/SqlConnection itself (after casting).
      The direct Dispose() call generates a call to ComponentModel.Dispose. Both SqlConnection
      and SqlCommand inherit (eventually) from System.ComponentModel.Component. That's where
      the shared state (and the exception) comes in.
   </p>
        <p>
      Watch out for this. Using "using" (that's Using-End Using in VB.NET) is your best
      bet.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=6cac2fe3-dbf1-4f4c-b828-8a5fb3e8180e" />
      </body>
    </content>
  </entry>
  <entry>
    <title>What do you mean by "unsupported"?</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=e88ee90c-1cfb-4237-9f91-733d396cab38" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=e88ee90c-1cfb-4237-9f91-733d396cab38</id>
    <issued>2005-03-24T11:21:21.8750000-08:00</issued>
    <modified>2005-03-24T11:21:22.0468750-08:00</modified>
    <created>2005-03-24T11:21:21.8750000-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      The last blog entry brings up the question of what I mean when I say something is
      "unsupported" in SQLCLR. Becuase I've said that J# is "unsupported". This doesn't
      mean that it won't ever work or that you couldn't actually get technical support for
      it, given enough time, energy, and money.
   </p>
        <p>
      Technically, its possible to run almost *anything* in SQL Server if you catalog it
      as UNSAFE. But if your library doesn't follow SQL Server's rules for reliability and
      does something that could compromise the stability of the server, its appdomain could
      be unloaded as a last resort. Oh. Only a subset of the BCL are supported; to see this
      subset, create a Visual Studio Database/SQL Server project, and choose "Add Reference".
      Note that only a subset of the base class libraries appear. These are the ones that
      have been hardened according to the SQL Server reliability guidelines. Note that this
      contains the support libraries for VisualBasic.NET and Managed C++ (C# uses no language-specific
      support libraries), but not for J#. Because of the COM interop, they'd have to almost
      completely rewrite it to be compliant. That's what I mean by unsupported, I don't
      mean that it technically isn't accomplishable. Note also that there's no J# Database/SQL
      Server project in Visual Studio. That's a clue. And although *managed* C++ is a supported
      language, you have to compile with a special /safe switch, which enforces reliability limitations.
   </p>
        <p>
      On the other hand, it's always been my contention that the most unsafe CLR code is
      safer than an extended stored procedure. Extended stored procedures are analogous
      to tweaking with the kernel of an operating system; there has to be extended test/maintanance
      plan because, unless you're the SQL Server team, you don't "own" the code you're running
      under. There's now notes in the BOL, under Programming Extended Stored Procedures,
      that read: "This feature will be removed in a future version of Microsoft SQL Server.
      Avoid using this feature in new development work" and "Use CLR Integration instead.".
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=e88ee90c-1cfb-4237-9f91-733d396cab38" />
      </body>
    </content>
  </entry>
  <entry>
    <title>DROP ASSEMBLY change - just a convenience?</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=d0a9bbca-613c-45ee-8d28-844b50a558eb" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=d0a9bbca-613c-45ee-8d28-844b50a558eb</id>
    <issued>2005-03-24T11:13:57.0781250-08:00</issued>
    <modified>2005-03-24T11:13:57.2656250-08:00</modified>
    <created>2005-03-24T11:13:57.0781250-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Looking at the Feb CTPNotes file again, there's another change that caught my eye.
      DROP ASSEMBLY has changed with respect to dependent assemblies. In past, you had to
      drop assemblies one at a time, so if assembly A called assembly B, you first dropped
      A then B. Now dropping A drops B automatically if B has the "is_visible" flag is false
      for B.
   </p>
        <p>
      Although the looks like a convenience change at first, it actually solves a problem
      people run into when they go outside the mainstream of the supported BCL assemblies.
      If, for example, you used a library of your own that had a reference to System.Drawing
      (it's a library that draws an icon, but you don't intend to use this portion in SQL
      Server), this triggered a set of BCL references, some of them circular references.
      The only way to catalog something like this to SQL Server entailed cataloging as UNSAFE
      and (because of dependencies) also cataloging many unsupported base class libraries.
      But you couldn't drop it all because of the circular references.
   </p>
        <p>
      Another example of this is using the J# language. Because J# support libraries use
      COM interop, the most trivial J# program (I just added two numbers together) must
      be cataloged as UNSAFE and results in 4 J# support libraries and 6 or so unsupported
      base class libraries being cataloged as dependencies. It's now possible to drop the
      J# assembly and have it drop all the associated assemblies at the same time.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=d0a9bbca-613c-45ee-8d28-844b50a558eb" />
      </body>
    </content>
  </entry>
  <entry>
    <title>SQL Server unified provider info on DataWorks' team blog</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=13a9f3c8-728d-44ec-8ada-d736e9e206c0" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=13a9f3c8-728d-44ec-8ada-d736e9e206c0</id>
    <issued>2005-03-23T23:16:07.2656250-08:00</issued>
    <modified>2005-03-23T23:16:07.4531250-08:00</modified>
    <created>2005-03-23T23:16:07.2656250-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      The data access team (known as DataWorks) has started up a <a href="http://blogs.msdn.com/dataaccess/">team
      blog</a>. Some of the individual team members, like <a href="http://blogs.msdn.com/angelsb/">Angel
      Saenz-Badillos </a>and <a href="http://blogs.msdn.com/sushilc/">Sushil Chordia</a>,
      have been blogging for a while, this one has posts from all members.
   </p>
        <p>
      One of the first posts was information about the upcoming <a href="http://blogs.msdn.com/dataaccess/archive/2005/03/22/400459.aspx">SqlClient
      and SqlServer provider unification by Pablo Castro</a>. The unified provider isn't
      in Feb CTP, but will be in an upcoming release soon. Pablo mentions that SqlConnection
      and other classes that can be shared between providers will be, but that SqlContext
      will still be retained for in-database- specific classes. By my calculations, that
      leaves (as in-database-specific):
   </p>
        <p>
      SqlPipe - encapsulates a data stream back to the client<br />
      SqlTriggerContext - provides information in a SQLCLR trigger<br />
      WindowsIdentity - used for impersonation when accessing external resources (e.g. files)
      where you need a Windows identity
   </p>
        <p>
      The only thing that I'll miss is the SqlDefinition/SqlExecutionContext classes. I'd
      been told those won't be in for this time; hopefully they're in the next major release.
   </p>
        <p>
      They'll also be an upcoming in-depth article when the unified provider ships. 
   </p>
        <p>
      Thanks, Pablo! And Alyssa!
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=13a9f3c8-728d-44ec-8ada-d736e9e206c0" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Service Broker's new poison message handling</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=f69f29a6-a8a3-419d-84d2-7830800ca865" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=f69f29a6-a8a3-419d-84d2-7830800ca865</id>
    <issued>2005-03-23T21:32:16.3593750-08:00</issued>
    <modified>2005-03-23T21:32:16.5000000-08:00</modified>
    <created>2005-03-23T21:32:16.3593750-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      In this last entry on Service Broker enhancements I inadvertantly referred to the
      new poison message handling as poison conversation handling. Well, maybe it wasn't
      so inadvertant. So what's the difference between Service Broker's poison message handling
      and traditional poison message handling?
   </p>
        <p>
      A poison message is a fact of life in transactional messaging. When a message is received
      from a queue, often some database action occurs as part of the same transaction. If
      the database action fails (say, insert of a row based on a field in the message that
      happens to be a duplicate key) the message is put back on the queue. Where it is received
      again... If the database condition that caused the first rollback to happen hasn't
      been resolved, the transaction will roll back again..and again..hence the term posion
      message.
   </p>
        <p>
      Usually poison message handling shunts the message off to a dead letter queue. Where
      it can be safely ignored while the application goes on. Oh. The problem with this
      is: suppose the message you are ignoring is a million-dollar order. Or the executive's
      December check. The database transaction may have rolled back because overflow occurred
      on an internal variable (especially with extremely large dollar figures). I've personally
      seen the “executive December check overflows payroll counters“ one, back
      in the days of COBOL. They used fixed point decimal just like SQL/RDBMSs do today.
   </p>
        <p>
      Since the primitive concept of Service Broker is the conversation, not the message,
      the message should not be ignored. 
      <br />
      You could lose the million dollar order. Or produce cranky executives. The programmer
      who designed such an app (and didn't watch the dead letter queue) could be fired.
      There's something wrong with the conversation, it should be shut down.
   </p>
        <p>
      The new "posion message handling" actually goes further than that. After 5 receives
      of the same message, Service Broker shuts down *the queues on both sides of the conversation*.
      You can recover from this by:<br />
      1. Either end the conversation or recieve the message without a rollback<br />
      2. And reenable the queues
   </p>
        <p>
      You can still implement your own poison message handling, using any of the suggestions
      we described in our "First Look" book. You have 4 retries to do something on your
      own, before the automatic poison behavior kicks in.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=f69f29a6-a8a3-419d-84d2-7830800ca865" />
      </body>
    </content>
  </entry>
  <entry>
    <title>New Service Broker features in the Feb CTP</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=249cccff-c6e1-491d-82fe-664673823c3b" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=249cccff-c6e1-491d-82fe-664673823c3b</id>
    <issued>2005-03-23T20:33:43.7187500-08:00</issued>
    <modified>2005-03-23T20:33:43.8906250-08:00</modified>
    <created>2005-03-23T20:33:43.7187500-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I've been doing some experimenting with the new SQL Server Service Broker features
      in Feb CTP. You can read about them in the CTPNotes.doc file; I won't repeat the information
      here. The features are:
   </p>
        <p>
      1. Improved Endpoint Security - authentication option NONE is not longer supported<br />
      2. DEFAULT message type and contract<br />
      3. Poison conversation handling
   </p>
        <p>
      DEFAULT message type and contract came about due to feedback that the DDL to create
      a simple broker applications consisted of too many pieces. You needed to define MESSAGE
      TYPEs, CONTRACT, QUEUE, and SERVICE to define the simplest application. The first
      time this behavior change was described to me (it was some of my students
      among those who complained about the complexity after all), I thought they were going
      to loosen things up a bit to work without a contract. But broker uses contracts to
      enforce conversation integrity. In order to receive a message, a service has to be
      defined with a contract that's enforced when messages are being put on the queue.
      No contract, no user messages can be received. Hmmm...how would they do it?
   </p>
        <p>
      You can now define a broker SERVICE by only defining QUEUE and SERVICE objects. However,
      the SERVICE must be defined to use a new built-in contract named [DEFAULT]. This contract
      specifies that a built-in MESSAGE TYPE, also called [DEFAULT], can be sent by either
      side (by ANY). When you issue a BEGIN CONVERSATION DIALOG without a contract, it uses
      the [DEFAULT] contract, not NO contract. When you SEND a message without an explicit
      MESSAGE TYPE it sends the [DEFAULT] message type. 
   </p>
        <p>
      So you're NOT using contract-less and message type-less conversations, you're
      using a specific contract and message type called [DEFAULT]. You just don't have to
      define them yourself.
   </p>
        <p>
      There's a code example is the Feb CTPNotes.doc file (which is why you should always
      “read the readme file”), try it out for yourself and see.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=249cccff-c6e1-491d-82fe-664673823c3b" />
      </body>
    </content>
  </entry>
  <entry>
    <title>FOR XML...XMLSCHEMA and schema validation</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=12e6f7e2-b434-44b8-a66c-792989bb80fb" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=12e6f7e2-b434-44b8-a66c-792989bb80fb</id>
    <issued>2005-03-13T04:54:46.0937500-08:00</issued>
    <modified>2005-03-13T04:54:46.3593750-08:00</modified>
    <created>2005-03-13T04:54:46.0937500-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      When reading the CTPNotes file from the new Feb CTP build I stumbled across the fact
      that the XML schema that contains SQL data types (<a href="http://schemas.microsoft.com/sqlserver/2004/sqltypes">http://schemas.microsoft.com/sqlserver/2004/sqltypes</a>)
      is now built-in to the server. Although this may not mean much to most people, it
      gave me the chance to try something that Dan Sullivan thought up for the first rev
      of our SQL Server 2005 class. It works now.
   </p>
        <p>
      One of the enhancements to SELECT...FOR XML is ability to request that the XML it
      produces be prepended by an XML schema that describes it. A recent change allows you
      to choose the namespace for that schema. Dan's idea was to add the prepended schema
      to create a schema collection. After storing the FOR XML outside in an XML schema-valid
      column, you could make updates to the column that would be validated by the schema.
      You'd set this up like this:
   </p>
        <p>
      declare @x xml<br />
      select @x = (select * from authors for xml auto, type, xmlschema('urn:authors')).query('*[1]')<br />
      create xml schema collection authorsxsd<br />
      as @x<br />
      go
   </p>
        <p>
      create table authorsxml (<br />
       id int primary key identity, -- primary key required if XML index needed<br />
       authors xml(authorsxsd))<br />
      go
   </p>
        <p>
      declare @x xml(authorsxsd)<br />
      set @x = (select * from authors for xml auto, type, xmlschema('urn:authors')).query('/*[position()&gt;1]')<br />
      insert authorsxml values(@x)
   </p>
        <p>
      The XML Schema produced in the first step will now validate any information entered
      or updated in the table. 
   </p>
        <p>
      Why the Feb CTP change makes this work is FOR XML....XMLSCHEMA uses the SQL data types
      schema that's now built in. In previous betas, you could use this schema (error: not
      built in) or add the schema manually (error: it is built in [but it wasn't]). Thanks
      SQL Server 2005 XML folks, for this.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=12e6f7e2-b434-44b8-a66c-792989bb80fb" />
      </body>
    </content>
  </entry>
  <entry>
    <title>About the new SQLCLR TVFs</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=0d1d21f5-62a5-4525-82c7-e30cdbb50c55" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=0d1d21f5-62a5-4525-82c7-e30cdbb50c55</id>
    <issued>2005-03-06T03:18:36.9687500-08:00</issued>
    <modified>2005-03-06T03:18:37.2500000-08:00</modified>
    <created>2005-03-06T03:18:36.9687500-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      In the new Feb CTP release, how your implement a table-valued function in SQLCLR has
      been re-architected. This is in the readme (CTPNotes) This was done because implementing
      ISqlReader was quite complicated and overkill for most scenarios. Chapter 3 of our
      book "A First Look at SQL Server 2005 for developers" contains a very simple TVF (Bernoulli)
      implemented using ISqlReader. It contains over 400 lines of code. Many of the methods
      are stubbed-out because they are never used, but must exist to satify the interface
      definition. Using the new implementation this method would be less than 15 lines of
      code.
   </p>
        <p>
      The new TVF implementation requires three pieces:<br />
      1. The SqlFunction attribute with the new field FillRowMethodName.<br />
      2. This attribute is applied to a method that returns either IEnumerable or IEnumerator.<br />
      3. FillRowMethodName points to a DIFFERENT method (in the same class) that has a special
      signature.
   </p>
        <p>
      The methods in steps #2 and #3 have to be public static. Many of the collection classes
      in the BCL (e.g System.Array) implement IEnumerable or IEnumeration already, or you
      can write your own implementation. 
   </p>
        <p>
      The FillRowMethodName method has the following signature:
   </p>
        <p>
      public static void FillIt(Object o, out int col1 , out int col2...)<br />
         where the first arg is object returned by method in step #2<br />
         where the varargs arguments (col1, col2....) are the columns that will
      be returned.
   </p>
        <p>
      MoveNext is called on the underlying IEnumerator (in each case) until it returns false.
      Each time MoveNext returns a value, the FillRowMethod is called. This generates the
      rows. The number of columns is determined by the exact signature of the FillRowMethod.
      In this example, a 2-column table is returned.
   </p>
        <p>
      Interestingly, the 2-nth arguments in your FillRowMethohd must be declared as "out"
      variables in C#. In my cursory testing, if they are declared as "ref", the method
      failed with the error: "argument n cannot be NULL" when the TVF implementation calls
      your FillRowMethod. This is interesting for VB.NET programmers because there is no
      direct variable qualifier keyword that corresponds to C#'s out. Or is there?
   </p>
        <p>
      When .NET was first released a friend of mine, Jose Mojica, published "The C# &amp;
      VB.NET Conversion Pocket Reference". And it names the following VB.NET
      equivalent for "out":
   </p>
        <p>
      Imports System.Runtime.InteropServices<br />
      ' signature of a FillRowMethod<br />
      Shared Sub FillIt(o as Object, &lt;Out()&gt; ByRef col1 as Integer, &lt;Out()&gt;
      ByRef col2 as Integer...)
   </p>
        <p>
      Works great, Jose, my VB.NET TVF is working fine. If you're doing cross language work
      in .NET, I highly recommend this book.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=0d1d21f5-62a5-4525-82c7-e30cdbb50c55" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Where 'ya been dude?</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=529f4816-8c2f-4b3a-a06b-dd46319582fd" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=529f4816-8c2f-4b3a-a06b-dd46319582fd</id>
    <issued>2005-03-05T01:58:21.8281250-08:00</issued>
    <modified>2005-03-05T01:58:22.0156250-08:00</modified>
    <created>2005-03-05T01:58:21.8281250-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Hi all. Not much blogging out of me lately. I've been on vacation and, in between,
      I've been teaching SQL Server 2005 at Microsoft Sydney to some of Australia and New
      Zealand's finest, including Russell Darroch, Greg Low, Chris Hewitt and Brent Challis.
      During the class Greg worked up his all-encompasing trigger to prevent cataloging
      objects in the master database. Probably partially inspired by seeing my do this a
      few times by mistake in demos. Some other folks in the class worked on *their* application
      specific features inspired by the encryption built-ins (e.g. encryptbykey), XQuery
      functionality, FOR XML PATH, and Service Broker. Thanks folks, I had a great time.
   </p>
        <p>
      More people answer the question "what's the feature you most want to hear about?"
      asking about Service Broker each class. It's amazing to see Broker's "recognition
      curve" increase steadily since I started teaching SQL Server 2005 in...uh...August
      2003. And to watch momentum building for this release in general.
   </p>
        <p>
      By now, I'm sure you've heard that there's a new CTP (Commnunity Technology Preview)
      released this week. I've got the CTPNotes file. Be SURE to read this one carefully.
      There's a lot of new stuff in this build. I'll be home mid-week to start on it in
      earnest. 
   </p>
        <p>
      Right now I'm just back from watching the sun go down at Manly Beach. Morning was
      spent navigating the waves and getting myself sunburnt, then it started sprinkling
      rain around 3. Cleared up right after dinner. It's going to be hard to leave summer..
      oh that's right.. its autumn here already.
   </p>
        <p>
      More technical content shortly. Got some blog comment responses to catch up on too...later.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=529f4816-8c2f-4b3a-a06b-dd46319582fd" />
      </body>
    </content>
  </entry>
  <entry>
    <title>First release of Service Broker Explorer</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=4b842441-7e96-42fb-b7c3-5bbea1d714c7" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=4b842441-7e96-42fb-b7c3-5bbea1d714c7</id>
    <issued>2005-02-16T22:29:21.1250000-08:00</issued>
    <modified>2005-02-16T22:29:21.2968750-08:00</modified>
    <created>2005-02-16T22:29:21.1250000-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      My cohort, Dan Sullivan, has released the Service Broker Explorer on his <a href="http://www.sqlservicebroker.com/forums">Service
      Broker Developer's Spot </a>website. It a graphic user interface for Service Broker
      that has some “topology map” features and configuration features and some
      management features for Service Broker objects. According to Dan:
   </p>
        <p>
      “It lets you drill into Sevice Broker and add and control elements of Service
      Broker with a GUI. It's just meant for use to learn about Service Broker, it is not
      for use in a production system.“
   </p>
        <p>
      Version 1 of what promises to be a very cool utility.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=4b842441-7e96-42fb-b7c3-5bbea1d714c7" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Query plan guides in the SQL Server 2005 BOL</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=d13cce58-a916-4053-8b00-0df2666e04af" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=d13cce58-a916-4053-8b00-0df2666e04af</id>
    <issued>2005-02-16T22:20:09.6406250-08:00</issued>
    <modified>2005-02-16T22:20:09.8281250-08:00</modified>
    <created>2005-02-16T22:20:09.6406250-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Just catching up on my blogging before a little vacation next week. 
   </p>
        <p>
      Browsing through the SQL Server BOL from the December CTP, I came across some information
      on something called "plan guides". There is info on some stored procedures that create
      and manage plan guides, a database option (in ALTER DATABASE) and a system view that
      lists plan guides. However, none of this these are active yet in the actual product.
      Let's hope this is another example of documentation being ahead of things (a la EXCEPT
      and INTERSECT support), because these sound interesting. According to BOL...
   </p>
        <p>
      A plan guide is a database object that associates query hints with certain queries
      in the database. You can create a plan guide (using sp_createplanguide) for a SQL
      statement or batch. The statement can be standalone or specified to be part of a certain
      stored procedure. The plan guide specifies an OPTION clause specifying query hints
      to be applied whenever the statement is executed.
   </p>
        <p>
      Plan guides must first be "enabled" on in a database (using ALTER DATABASE) before
      they can be used. Then you turn them "on and off" by sp_controlplanguide enable/disable.
      When a matching query is detected the hints are automatically “put in place“. 
   </p>
        <p>
      Sounds VERY cool for query plan afficianados. You can have configurable query hinting
      without touching your queries in the application code. And turn it on or off at will. Only
      thing is, NONE of it works in the December CTP. Any of the stored procedures produce
      "not found" message, as does the ALTER DATABASE keyword and the system view. Maybe
      the BOL IS a little ahead again.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=d13cce58-a916-4053-8b00-0df2666e04af" />
      </body>
    </content>
  </entry>
  <entry>
    <title>UDM data access - is it all done with mirrors?</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=9321ddfa-f7ff-4f29-b87d-4acab3a9c063" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=9321ddfa-f7ff-4f29-b87d-4acab3a9c063</id>
    <issued>2005-02-16T21:54:13.7187500-08:00</issued>
    <modified>2005-02-16T21:54:13.9218750-08:00</modified>
    <created>2005-02-16T21:54:13.7187500-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I had a few spare cycles to do some reading recently, and thought I would check out
      the new Unified Dimensional Model (UDM) that can be used with Analysis Services 2005.
      I started by listening to a webcast by Amir and Ariel Netz. Interesting stuff about
      datamarts, data warehouse, and specialized metadata model proliferation. And the strengths
      of reporting against both relational and OLAP data. Although MOLAP cubes are still
      with us, AS2005 seems to be becoming a reporting clearinghouse, a "UDM server".
   </p>
        <p>
      The only thing that struck me a bit strange was the concept of using live RDBMSs to
      feed UDM data caches as an adjunct to or replacement for datamarts and data warehouses.
      I've been spending a lot of time lately talking to DBAs who are concerned that features
      such as SQLCLR and in-database web services might blur the "focus" of a database,
      and make management more complex because of resource contention/sharing. I'd think
      that a UDM connection to a live database (rather than a reporting only database copy)
      might complicate management, sharing, and contention issues even more.
   </p>
        <p>
      Reading more about this in SQL Server BOL, there IS a section on using database mirroring
      and snapshots to support reporting. So maybe they're not talking about a reporting
      connection to a live OLTP database, something that hasn't been done (with OLTP performance
      in mind) for a while. Maybe it's all done with mirrors.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=9321ddfa-f7ff-4f29-b87d-4acab3a9c063" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Don't try this at home...yet</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=46d6d573-06a0-4409-b491-f478cd5d53bd" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=46d6d573-06a0-4409-b491-f478cd5d53bd</id>
    <issued>2005-02-11T08:15:13.2187500-08:00</issued>
    <modified>2005-02-11T08:15:13.3750000-08:00</modified>
    <created>2005-02-11T08:15:13.2187500-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      In the last blog entry I talked about using System.Transactions in SQLCLR code. But
      don't try this yet, the keyword here is *will* be used. I base this on a few bugs
      that I filed on System.Transactions/SQLCLR being closed as “this will be fixed
      in beta 3”. And a statement on a public newsgroup by Pablo Castro (who would
      know better than Pablo?) that you'd roll back in a SQLCLR trigger by using: Transaction.Current.Rollback().
   </p>
        <p>
      But don't try this yet. Even in the latest CTPs, using SQLCLR and System.Transactions
      yields some nasty messages referring to methods in EnterpriseServices.dll and fails.
      If I had to guess, this support would be completed about the same time as the
      merge of the SqlClient and SqlServer data providers. Watch this space.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=46d6d573-06a0-4409-b491-f478cd5d53bd" />
      </body>
    </content>
  </entry>
  <entry>
    <title>System.Transactions, promotable transactions, and composition</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=3fa4c7fc-2184-4b0d-99bf-e93c75783e8b" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=3fa4c7fc-2184-4b0d-99bf-e93c75783e8b</id>
    <issued>2005-02-09T15:52:24.9062500-08:00</issued>
    <modified>2005-02-11T08:16:03.0625000-08:00</modified>
    <created>2005-02-09T15:52:24.9062500-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      There's been a lot of interest in the new System.Transactions.dll assembly lately.
      Especially from users of SQL Server 2005. This is based around two functionality points.
   </p>
        <p>
      The first point of interest is that you will use System.Transactions to
      use transactions in SQLCLR procedural code in SQL Server 2005. In the beta 2 implementation
      of the SqlServer data provider, transactional coding had to use two different code
      paths based on whether a transaction was already started before your procedure was
      called. There was a section in the "First Look at SQL Server 2005 for Developers"
      book on this, transaction handling seemed rather complex. Using System.Transactions will
      make this simpler and more elegant.
   </p>
        <p>
      The second point is that SQL Server 2005 has a feature known as promotable transactions.
      When you use a single connection to SQL Server 2005 and a System.Transactions TransactionScope,
      a local transaction is started. If SQL Server 2000 is used, or more than one database
      connection is used, the same TransactionScope starts a distributed transaction. Which
      is a few times slower than a local transaction. 
   </p>
        <p>
      After starting a local transaction with SQL Server 2005, another connection is opened
      in the same TransactionScope, the original local transaction is promoted to a distributed
      transaction, because now a distributed transaction is needed. Hence the name promotable
      transactions.
   </p>
        <p>
      It is important to remember, however, that the transaction is still scoped to the
      *connection*. The usual cool TransactionScope demo shows a local transaction on SQL
      Server 2005 instance #1 being promoted to distributed when you open a second connection
      to a *different* database instance. It will be also be promoted if you open a second
      SqlConnection to *the same instance*.  Each connection has a different transaction
      space (lock space), even if you are using promotable transactions. Therefore, you
      need a distributed transaction with two connections to the same database. Even if
      the connection string and other environment is exactly the same. 
   </p>
        <p>
      To "knit" two lock spaces togther you'd need something fairly drastic, a la sp_getbindtoken
      and sp_bindsession. And they're not doing that.
   </p>
        <p>
      The reason why this is puzzling (I was recently reminded by a student from a recent
      class) is that, in MTS/COM+ you could flow transactions by composing method calls,
      like this:
   </p>
        <p>
      void DoTransfer(int accta, int acctb, double amt)<br />
      {<br />
        DoWithdrawal(accta, amt);<br />
        DoDeposit(acctb, amt);<br />
      }
   </p>
        <p>
      Both DoWithdrawal and DoDeposit would open a connection in MTS/COM+. System.Transactions
      has some COM+-like transaction composition properties. But if both DoWithdrawal and
      DoDeposit each open a separate SqlConnection with enlist=true in the connection string
      (its the default), promotable transactions won't help, they'll be running a *distributed*
      transaction. If you really want promotable to mean: multiple operations, one database
      == local transaction, you'll have to pass the SqlConnection object around too. This
      makes things complex, because SqlConnections aren't "agile". They don't pass from
      process to process, for example.
   </p>
        <p>
      Transaction is scoped to the connection (modulo sp_bindsession).
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=3fa4c7fc-2184-4b0d-99bf-e93c75783e8b" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Tracking the pesky appdomain</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=a6c40649-5219-49f2-8e1a-e555b3974d5f" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=a6c40649-5219-49f2-8e1a-e555b3974d5f</id>
    <issued>2005-02-07T08:19:40.0781250-08:00</issued>
    <modified>2005-02-07T08:19:40.2343750-08:00</modified>
    <created>2005-02-07T08:19:40.0781250-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      People (especially DBAs) want to see what those pesky appdomains are doing in SQLCLR.
   </p>
        <p>
      Back in beta1 there was a system function, master.sys.fn_appdomains(), that showed
      which appdomains were running and which assemblies were loaded in the appdomains,
      number of bytes used, etc. In beta2 this view stopped working and, although you can
      watch appdomains being created and destroyed in the SQL Server log, I'd always missed
      master.sys.fn_appdomains().
   </p>
        <p>
      You can get this information and more in the Dec CTP build:
   </p>
        <p>
      -- appdomains<br />
      select * from sys.dm_clr_appdomains<br />
      -- loaded assemblies<br />
      select * from sys.dm_clr_loaded_assemblies
   </p>
        <p>
      -- You can even get managed code execution statistics for currently executing queries<br />
      select command, exec_managed_code from sys.dm_exec_requests
   </p>
        <p>
          <br />
      master.sys.fn_appdomains is still around, but it doesn't return anything any more.
      Look for more CLR statistics in the dynamic management views (and elsewhere) in future
      betas.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=a6c40649-5219-49f2-8e1a-e555b3974d5f" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Back home again</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=53d39ec8-6ea8-4fe0-a799-a76e37b67838" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=53d39ec8-6ea8-4fe0-a799-a76e37b67838</id>
    <issued>2005-02-07T08:17:42.6093750-08:00</issued>
    <modified>2005-02-07T08:17:42.7968750-08:00</modified>
    <created>2005-02-07T08:17:42.6093750-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I'm back home again after being on the road three weeks out of the last four. Internet
      access was good, except for one hotel. I watched the person in front of me at checkin:
   </p>
        <p>
      Guest: How do you access the high-speed internet you mention in your ad?<br />
      Clerk: Unplug the phone jack from the wall, replace it with your PC plug.<br />
      Guest: Then what?<br />
      Clerk: Dial your ISP.<br />
      Guest: I don't have an ISP here.<br />
      Clerk: There is a list of them on the internet.
   </p>
        <p>
      I didn't listen any further.
   </p>
        <p>
      During my travels, it appears that I acquired a throat infection that makes it difficult
      to talk. This gives me a chance to use one an analogy from Ball Four by Jim Bouton.
      He was speaking of baseball pitchers, but... An instructor with a throat infection
      is "like a tiddly-winks champion with a hangnail". 
   </p>
        <p>
      Anyhow, back home, got real high-speed internet. Technical content coming...
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=53d39ec8-6ea8-4fe0-a799-a76e37b67838" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Fun with static XQuery evaluation - 4 - answers and wrapup</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=65a4d98f-7c69-4b26-b396-dc70d60e2a5b" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=65a4d98f-7c69-4b26-b396-dc70d60e2a5b</id>
    <issued>2005-01-27T11:03:05.4531250-08:00</issued>
    <modified>2005-01-27T11:03:05.6093750-08:00</modified>
    <created>2005-01-27T11:03:05.4531250-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Here's the answers to the question from Fun With static XQuery evaluation - 2
   </p>
        <p>
      -- start with a schema collection
   </p>
        <p>
      CREATE XML SCHEMA COLLECTION ages AS<br />
      '&lt;xs:schema<br />
         xmlns:xs="<a href="http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</a>"<br />
         targetNamespace="urn:ages"<br />
         xmlns:tns="urn:ages"&gt;<br />
      &lt;xs:element name="age" type="xs:int"/&gt;<br />
      &lt;/xs:schema&gt;<br />
      '<br />
      GO
   </p>
        <p>
      DECLARE @x xml(ages)<br />
      SET @x = '&lt;age&gt;12&lt;/age&gt;'<br />
      -- fails ??!<br />
      SELECT @x.query('string(/age)')<br />
      GO
   </p>
        <p>
      This fails because there can be more than one &lt;age&gt; element and fn:string requires
      a singleton or empty sequence. 
   </p>
        <p>
      --- These work ---
   </p>
        <p>
      -- this query restricts it to the first age element<br />
      DECLARE @x xml(ages)<br />
      SET @x = '&lt;age&gt;12&lt;/age&gt;'<br />
      SELECT @x.query('string(/age[1])')<br />
      GO
   </p>
        <p>
      -- this restricts the variable to XML documents. Fragments disallowed. 
      <br />
      -- This means there can be only ONE (or zero) age elements.<br />
      -- No subscript is needed on the query then.<br />
      DECLARE @x xml(document ages)<br />
      SET @x = '&lt;age&gt;12&lt;/age&gt;'<br />
      SELECT @x.query('string(/age)')<br />
      GO
   </p>
        <p>
      The second one was a bit harder if you haven't run across the (document schemacollection)
      construct. Remember that XML data type can contain documents or fragments. Putting
      "document " before the schema collection name in any typed XML declaration restricts
      instances to an XML document (ie, single root element). The default is "content" so:
   </p>
        <p>
      declare @x xml(content ages)    -- use ages xml schema collection,
      allow fragments or documents<br />
      declare @x xml(document ages) -- disallow fragments; documents only<br />
      declare @x xml(ages)              
      -- equals using "content"
   </p>
        <p>
      Note that you can only enforce "document only" using this keyword with TYPED XML.
      It's not supported on untyped XML instances. You can do the equivalent enforcement
      with an untyped XML column in a table by using an XML check constraint, like this:
   </p>
        <p>
      create table foo (<br />
        xmlcol xml constraint mycontr 
      <br />
               xmlcol.value('count(/*)', 'int')
      = 1 and xmlcol.exist('/text()')=0
   </p>
        <p>
      Hope you've enjoy this foray into static typing and XQuery. Because this is a "implementation
      decision" you won't find much about this in the W3C spec. The best information about
      this is in the excellent <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsql90/html/sql25xmlbp.asp">XML
      Best Practices for Microsoft SQL Server 2005 </a>document. 
   </p>
        <p>
      BTW, in case you collect W3C specs for your own offline reference (like I do), bear
      in mind that the final SQL Server 2005 implementation of XQuery will be aligned with
      the W3C July 2004 XQuery spec series. XQuery is still a W3C "work in progress".
      SQL Server 2005 implements a subset of the functions and operators, adds functions
      to access T-SQL variables and SQL columns, and also implements static typing. So it's
      not a 1-to-1 match with the spec, but if you like W3C specs, July 2004 is the one
      you want. For now.
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=65a4d98f-7c69-4b26-b396-dc70d60e2a5b" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Fun with static XQuery evaluation - 3</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=b57c03c6-b0cd-4165-be17-742c724e42f9" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=b57c03c6-b0cd-4165-be17-742c724e42f9</id>
    <issued>2005-01-26T23:30:56.2343750-08:00</issued>
    <modified>2005-01-26T23:30:56.3593750-08:00</modified>
    <created>2005-01-26T23:30:56.2343750-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      After the last two entries, you might be thinking "I guess I can never use text()
      as a node test with typed XML again". Not so. The error message reads: 'text()' is
      not supported on simple typed or 'http://www.w3.org/2001/XMLSchema#anyType' elements.
      So what's left? Mixed content, for one thing. Mixed content consists of a mixture
      of text and also embedded subelements.
   </p>
        <p>
      If we change the schema to allow mixed content (this schema also allows a particular
      subelement):
   </p>
        <p>
      CREATE XML SCHEMA COLLECTION mixedage AS<br />
      '&lt;xs:schema<br />
      xmlns:xs="<a href="http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</a>"<br />
      targetNamespace="urn:ages"<br />
      xmlns:tns="urn:ages"&gt;<br />
        &lt;xs:complexType name="age" mixed="true"&gt;<br />
          &lt;xs:complexContent mixed="true"&gt;<br />
            &lt;xs:restriction base="xs:anyType"&gt;<br />
               &lt;xs:sequence&gt;<br />
                 &lt;xs:element name="dogyears"
      type="xs:int"/&gt;<br />
               &lt;/xs:sequence&gt;<br />
            &lt;/xs:restriction&gt;<br />
          &lt;/xs:complexContent&gt;<br />
        &lt;/xs:complexType&gt;
   </p>
        <p>
      &lt;xs:element name="age" type="tns:age"/&gt;<br />
      &lt;/xs:schema&gt;<br />
      '
   </p>
        <p>
      Then the text() node test works with typed XML just fine:
   </p>
        <p>
      DECLARE @x xml(mixedage)<br />
      SET @x = '<br />
      &lt;ag:age xmlns:ag="urn:ages"&gt;This is the age in dog years&lt;dogyears&gt;3&lt;/dogyears&gt;&lt;/ag:age&gt;'<br />
      -- now it works OK<br />
      SELECT @x.query('<br />
      declare default namespace "urn:ages";<br />
      /age/text()')<br />
      GO
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=b57c03c6-b0cd-4165-be17-742c724e42f9" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Fun with static XQuery evaluation - 2</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=0e4e03c5-7970-48a9-8991-faba034d1c77" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=0e4e03c5-7970-48a9-8991-faba034d1c77</id>
    <issued>2005-01-26T16:36:58.8906250-08:00</issued>
    <modified>2005-01-26T16:36:59.0625000-08:00</modified>
    <created>2005-01-26T16:36:58.8906250-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Reference back to the previous entry. Now that we know the rules, let's try them out:
   </p>
        <p>
      -- snip --
   </p>
        <p>
      Data(),text() and string() accessors
   </p>
        <p>
      XQuery has a function fn:data() to extract scalar, typed values from nodes, a node
      test text() to return text nodes, and the function fn:string() that returns the string
      value of a node. Their usages are sometimes confusing. Guidelines for their proper
      use in SQL Server 2005 are as follows. Consider the XML instance &lt;age&gt;12&lt;/age&gt;. 
   </p>
        <p>
      Untyped XML: The path expression /age/text() returns the text node "12". The function
      fn:data(/age) returns the string value "12" and so does fn:string(/age).
   </p>
        <p>
      Typed XML: The expression /age/text() returns static error for any simple typed &lt;age&gt;
      element. On the other hand, fn:data(/age) returns integer 12, while fn:string(/age)
      yields the string "12".
   </p>
        <p>
      -- snip --
   </p>
        <p>
      Try this:
   </p>
        <p>
      DECLARE @x xml<br />
      SET @x = '&lt;age&gt;12&lt;/age&gt;'<br />
      -- works as expected<br />
      SELECT @x.query('data(/age)')<br />
      GO
   </p>
        <p>
      DECLARE @x xml<br />
      SET @x = '&lt;age&gt;12&lt;/age&gt;'<br />
      -- fails<br />
      -- Msg 2211, Level 16, State 1, Line 6<br />
      -- XQuery [query()]: Singleton (or empty sequence) required, found operand of type
      'element(age,xdt:untypedAny) *'<br />
      SELECT @x.query('string(/age)')<br />
      GO
   </p>
        <p>
      Oh. This message looks familiar. It turns out that XQuery functions are strongly typed
      also. Here's the definition of fn:string and fn:data:
   </p>
        <p>
      fn:string($arg as item()?) as xs:string
   </p>
        <p>
      fn:data($arg as item()*) as xdt:anyAtomicType*
   </p>
        <p>
      The "item()*" means that data takes a sequence of 0-n items. "item()?" means that
      string only takes a sequence of 0-1 item. Let's fix it then.
   </p>
        <p>
      SELECT @x.query('string(/age[1])')
   </p>
        <p>
      Cool. Here's the test for comprehension. Let's try this with typed XML.
   </p>
        <p>
      -- start with a schema collection
   </p>
        <p>
      CREATE XML SCHEMA COLLECTION ages AS<br />
      '&lt;xs:schema<br />
         xmlns:xs="<a href="http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</a>"<br />
         targetNamespace="urn:ages"<br />
         xmlns:tns="urn:ages"&gt;<br />
      &lt;xs:element name="age" type="xs:int"/&gt;<br />
      &lt;/xs:schema&gt;<br />
      '<br />
      GO
   </p>
        <p>
      DECLARE @x xml(ages)<br />
      SET @x = '&lt;age xmlns="urn:ages"&gt;12&lt;/age&gt;'<br />
      -- fails as expected<br />
      SELECT @x.query('<br />
      declare default namespace "urn:ages";<br />
      /age/text()')<br />
      GO
   </p>
        <p>
      DECLARE @x xml(ages)<br />
      SET @x = '&lt;age xmlns="urn:ages"&gt;12&lt;/age&gt;'<br />
      -- works as expected<br />
      SELECT @x.query('<br />
      declare default namespace "urn:ages";<br />
      data(/age)')<br />
      GO
   </p>
        <p>
      DECLARE @x xml(ages)<br />
      SET @x = '&lt;age&gt;12&lt;/age&gt;'<br />
      -- fails ??!<br />
      SELECT @x.query('string(/age)')<br />
      GO
   </p>
        <p>
      Why does the last query (against strongly typed XML) fail, even though there is a
      schema? How can you fix it? There are two different "right answers". 
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=0e4e03c5-7970-48a9-8991-faba034d1c77" />
      </body>
    </content>
  </entry>
  <entry>
    <title>Fun with static XQuery evaluation - 1</title>
    <link rel="alternate" type="text/html" href="http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=a330d9f2-c297-45fa-8fd1-b01a076edfe7" />
    <id>http://staff.develop.com/bobb/weblog/PermaLink.aspx?guid=a330d9f2-c297-45fa-8fd1-b01a076edfe7</id>
    <issued>2005-01-26T15:22:09.3906250-08:00</issued>
    <modified>2005-01-26T15:22:09.6250000-08:00</modified>
    <created>2005-01-26T15:22:09.3906250-08:00</created>
    <content type="text/html" mode="xml">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      There's been lots of puzzled faces lately when I try to explain doing XQuery against
      strongly typed XML (XML typed by a SCHEMA COLLECTION) vs untyped XML. The largest
      FAQ is why when I have this document:
   </p>
        <p>
      &lt;person&gt;<br />
        &lt;name&gt;bob&lt;/name&gt;<br />
        &lt;age&gt;51&lt;/age&gt;<br />
      &lt;/person&gt;
   </p>
        <p>
      using the value function (after assignment to @person) @person.value('/person/age',
      'int') returns my favorite error:
   </p>
        <p>
      Msg 2389, Level 16, State 1, Line 6<br />
      XQuery [value()]: Operator 'value()' requires a singleton (or empty sequence), found
      operand of type 'xdt:untypedAtomic *'
   </p>
        <p>
      Huh? Although you know by looking at the document that there is only one age element,
      the XQuery parser uses static evaluation. It doesn't read your document (or read your
      mind) and assumes there can be more than one age element. After all, there's no schema
      to enforce the singleton age element, I could have 3 or 4 ages. It doesn't want to
      guess and be wrong at execution time. Using:
   </p>
        <p>
      @person.value('/person[1]/age[1]', 'int')
   </p>
        <p>
      works. I can see why age[1] is required, but why person[1]? Doesn't XML have a single
      root element? Actually, no. SQL Server 2005 supports fragments (well-formed, multiple
      root) as well as documents. Fragment support is part of the XQuery 1.0/XPath 2.0 data
      model.
   </p>
        <p>
      Most people get by that. The real fun starts when you do examples using untyped XML
      and XPath expressions with the text() node test. text() works just fine when using
      untyped XML, but fails against typed XML with simple content. Here's an example (the
      result of a discussion with Dan Sullivan):
   </p>
        <p>
      CREATE XML SCHEMA COLLECTION root AS<br />
      '&lt;xs:schema<br />
         xmlns:xs="<a href="http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</a>"<br />
         targetNamespace="urn:geo"<br />
         xmlns:tns="urn:geo"&gt;<br />
      &lt;xs:element name="Root" type="xs:string"/&gt;<br />
      &lt;/xs:schema&gt;<br />
      '<br />
      GO
   </p>
        <p>
      -- UNTYPED<br />
      -- this works<br />
      DECLARE @x  xml<br />
      set @x = '&lt;g:Root xmlns:g="urn:geo"&gt;asdf&lt;/g:Root&gt;'<br />
      select @x.query('<br />
       declare namespace g="urn:geo"<br />
       /g:Root/text()')
   </p>
        <p>
      -- TYPED<br />
      -- Msg 9312, Level 16, State 1, Line 4<br />
      -- XQuery [query()]: 'text()' is not supported on simple typed 
      <br />
      -- or 'http://www.w3.org/2001/XMLSchema#anyType' elements, 
      <br />
      -- found 'element(g{urn:geo}:Root,xs:string) *'.
   </p>
        <p>
      DECLARE @x  xml(root)<br />
      -- same document<br />
      set @x = '&lt;g:Root xmlns:g="urn:geo"&gt;asdf&lt;/g:Root&gt;'<br />
      select @x.query('declare namespace g="urn:geo"<br />
      /g:Root[1]/text()')
   </p>
        <p>
      But why? Isn't text() a node test that returns the value of a text() node. After casting
      about in XQuery specs, and SQL BOL, I finally came across this in the XML Best Practices
      paper.
   </p>
        <p>
      -- snip --
   </p>
        <p>
      Data(),text() and string() accessors
   </p>
        <p>
      XQuery has a function fn:data() to extract scalar, typed values from nodes, a node
      test text() to return text nodes, and the function fn:string() that returns the string
      value of a node. Their usages are sometimes confusing. Guidelines for their proper
      use in SQL Server 2005 are as follows. Consider the XML instance &lt;age&gt;12&lt;/age&gt;. 
   </p>
        <p>
      Untyped XML: The path expression /age/text() returns the text node "12". The function
      fn:data(/age) returns the string value "12" and so does fn:string(/age).
   </p>
        <p>
      Typed XML: The expression /age/text() returns static error for any simple typed &lt;age&gt;
      element. On the other hand, fn:data(/age) returns integer 12, while fn:string(/age)
      yields the string "12".
   </p>
        <p>
      -- snip --
   </p>
        <p>
      Well, that was confusing. But now I think I get it. When does a element not have a
      text() node (or more preicsely, not allow the text() node test)?? When it's a strong-typed
      query using a simple type element...that's when. But why? Although I know the rules
      now, I'm still somewhat baffled.
   </p>
        <p>
      This is getting pretty long, more on this topic in a bit...
   </p>
        <img width="0" height="0" src="http://staff.develop.com/bobb/weblog/aggbug.ashx?id=a330d9f2-c297-45fa-8fd1-b01a076edfe7" />
      </body>
    </content>
  </entry>
</feed>