SQL Azure Gets A Refresh

The SQL Azure Team Blog has an update on some changes in the CTP2.  First and foremost, the product is now feature complete.  Second, if you have been using the October CTP you have now been provisioned over to the go-live production clusters.

Additional Transact-SQL enhancements have been made as well, with Table Value Parameters being the most interesting to me.

PDC 2009 will see lots of discussion about SQL Azure so if you are making the trip to Los Angeles be sure to catch a session.

One more note on SQL Azure, if you are using Visual Studio 2010 beta check out the SQL Azure Explorer on CodePlex.  The add-in gives you the ability to navigate your instance as you would a normal SQL Server instance.  Good stuff!


Posted by: whitneyw
Posted on: 10/15/2009 at 3:10 PM
Tags:
Categories: SQL Server | SQL Azure
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Declarative Database Development

If you are doing any project work where you are responsible for moving data objects through multiple environments you will want to check out the post today on Gert Drapers blog.  You can get the slides from his recent presentation at the New England SQL Server Users Group.  Very interesting reading.


Posted by: whitneyw
Posted on: 9/15/2009 at 9:28 AM
Tags:
Categories: SQL Server
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Do you use batch terminators in your TSQL?

If not, you need to start.  As Aaron Bertrand mentions in his blog today this will become mandatory in a future version (hopefully vNext) of SQL Server.

If you are looking at this post with a puzzled look I am referring to ending SQL statements with a semicolon.  In SQL Server 2008 these terminators are only required with CTEs, MERGE, and Service Broker. 

I have been a fan of them for a long time.  They add to the clarity of code as well as now making your code future proof.  Double win!


Posted by: whitneyw
Posted on: 9/3/2009 at 2:57 PM
Tags: ,
Categories: SQL Server | Transact SQL
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

SQL Server Best Practices ? a reminder

I tend to get pulled into a lot of discussions around best practices in regards to SQL Server.  I am always a little shocked (and saddened) that so few people seem to be aware of the SQL Server Best Practices site.  This site is loaded with white papers and other content from various Microsoft groups and MVPs.

Do yourself a favor and head on over there once you have read whatever you were looking for on this blog.  No rush though, take your time.  ;)


Posted by: whitneyw
Posted on: 8/11/2009 at 11:08 AM
Tags:
Categories: SQL Server
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

AtlantaMDF Slides and Code Samples

As promised, here is the Powerpoint and code samples from tonight's AtlantaMDF meeting.  Thanks to everyone who came out and for all the great questions!

 

AtlantaMDF_Aug10_CDC.zip (1.31 mb)


Posted by: whitneyw
Posted on: 8/10/2009 at 11:02 PM
Tags:
Categories: SQL Server | User Groups
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Entity Framework SQL Improvements On The Way

As a guy that came up through the data side of the house I am very accustomed to writing stored procedures as the interaction between database and application.  On my current project we are using L2SQL for that interaction and while most things have been acceptable I would not call it a pleasant experience.  Most of my concern has come from actually looking under the covers at the generated SQL and being absolutely appalled at some of the things I have seen.  In those cases we have fallen back to stored procedures, which in an odd way has been disappointing as I had hoped we would only do one or the other.

I have hope for the future based on a post on the ADO.NET team blog about improvements they are making in the generated SQL of Entity Framework.  I believe that EF will be the future for most data driven applications (whether you find that idea palatable or not) so I am happy to see early realization that version one has a long way to go in terms of generating quality SQL.

I am curious though to hear from the fine readers of this blog if you are still in stored procedure land or if your development team(s) kicked the tires on either EF or L2SQL.


Posted by: whitneyw
Posted on: 8/6/2009 at 10:55 PM
Tags:
Categories: SQL Server | Entity Framework
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

SQL Azure Documentation Available

There are a couple sites available to you to get more detail on the upcoming SQL Azure CTP.  You can check the documentation site here or the product/service page here.

I'm very intrigued by this CTP and see a lot of focus going that way for me.  The overall reception of this CTP might not be in the realm of a SQL Server offering but I think there will be some fascinating discussion if nothing else.


Posted by: whitneyw
Posted on: 8/6/2009 at 12:03 AM
Tags:
Categories: SQL Server | SQL Azure | SQLServerPedia Syndication
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

AtlantaMDF - August 10

I will be speaking to the AtlantaMDF group about one of my favorite topics, Change Data Capture,  on Monday August 10th.  If you will/can be near the Microsoft office in Alpharetta swing on by.


Posted by: whitneyw
Posted on: 8/2/2009 at 10:46 PM
Tags: ,
Categories: SQL Server | User Groups
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Transact SQL To Find Missing Foreign Keys

One of the more important structures in a database are foreign keys.  Referential Integrity (RI) rarely gets the publicity it deserves and is often pushed aside during the development period of a data driven application.  Before a database leaves development (I would argue conceptual design, but I’m a stickler) we should confirm that all possible RI is in place.  But how do we quickly do this without spending hours looking through Object Explorer?

Here are a couple queries that make use of the catalog views to point out potential misses in RI (Note, these queries assume SQL 2005 or higher).

First, we simply want to find tables that contain no foreign keys.

--Tables with no foreign keys
SELECT OBJECT_SCHEMA_NAME(t.[object_id], db_id()) AS SchemaName
    ,t.name AS ObjectName
FROM sys.tables AS t
    LEFT JOIN sys.foreign_key_columns AS fkc ON fkc.parent_object_id = t.[object_id]
WHERE fkc.constraint_column_id IS NULL
ORDER BY SchemaName, ObjectName;

This first query will simply point out objects for us.  This is okay if you were the original author of the database and you know where potential references exist.  If you were not the original author then we need to go a step further and see if there are primary key columns that could be referenced.

--Tables with no foreign keys that have potential matches
SELECT OBJECT_SCHEMA_NAME(t.[object_id], db_id()) AS SchemaName
    ,t.name AS ObjectName
    ,c.name AS ColumnName
    ,OBJECT_SCHEMA_NAME(pc.[object_id], db_id()) AS PotentialMatchSchemaName
    ,OBJECT_NAME(pc.[object_id]) AS PotentialMatchObjectName    
    ,pc.name PotentialMatchColumnName
FROM sys.tables AS t
    INNER JOIN sys.columns AS c ON c.[object_id] = t.[object_id]
    LEFT JOIN sys.foreign_key_columns AS fkc ON fkc.parent_object_id = t.[object_id]
    INNER JOIN (
                SELECT c.[object_id], c.column_id, c.name
                FROM sys.columns AS c
                    INNER JOIN sys.index_columns AS ic ON ic.column_id = c.column_id
                        AND ic.[object_id] = c.[object_id]
                    INNER JOIN sys.indexes AS i ON i.index_id = ic.index_id 
                        AND ic.[object_id] = i.[object_id]
                WHERE i.is_primary_key = 1    
                ) AS pc ON pc.name LIKE '%' + c.name +'%' 
                    AND pc.[object_id] <> c.[object_id] 
                    AND pc.column_id <> c.column_id
WHERE fkc.constraint_column_id IS NULL
ORDER BY SchemaName
    ,ObjectName
    ,c.column_id
    ,PotentialMatchSchemaName
    ,PotentialMatchObjectName
    ,PotentialMatchColumnName;

With this query, we can look through potential matches and see if the primary key of those objects are the same value in our child object.

We could go even one step further and dynamically generate the foreign key creation.

--Dynamically build the foreign key for matches
SELECT OBJECT_SCHEMA_NAME(t.[object_id], db_id()) AS SchemaName
    ,t.name AS ObjectName
    ,c.name AS ColumnName
    ,OBJECT_SCHEMA_NAME(pc.[object_id], db_id()) AS PotentialMatchSchemaName
    ,OBJECT_NAME(pc.[object_id]) AS PotentialMatchObjectName    
    ,pc.name PotentialMatchColumnName
    ,'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], db_id())) 
    + '.' + QUOTENAME(t.name) 
    + ' ADD CONSTRAINT FK_' 
    + t.name + '_' + OBJECT_NAME(pc.[object_id]) 
    + '_' + pc.name AS CreateFKStatement
FROM sys.tables AS t
    INNER JOIN sys.columns AS c ON c.[object_id] = t.[object_id]
    LEFT JOIN sys.foreign_key_columns AS fkc ON fkc.parent_object_id = t.[object_id]
    INNER JOIN (
                SELECT c.[object_id], c.column_id, c.name
                FROM sys.columns AS c
                    INNER JOIN sys.index_columns AS ic ON ic.column_id = c.column_id
                        AND ic.[object_id] = c.[object_id]
                    INNER JOIN sys.indexes AS i ON i.index_id = ic.index_id 
                        AND ic.[object_id] = i.[object_id]
                WHERE i.is_primary_key = 1    
                ) AS pc ON pc.name LIKE '%' + c.name +'%' 
                    AND pc.[object_id] <> c.[object_id] 
                    AND pc.column_id <> c.column_id
WHERE fkc.constraint_column_id IS NULL
ORDER BY SchemaName
    ,ObjectName
    ,c.column_id
    ,PotentialMatchSchemaName
    ,PotentialMatchObjectName
    ,PotentialMatchColumnName;    

With the queries above in hand you can give yourself a pretty good indication of the work necessary to have solid RI in place for your database.


Posted by: whitneyw
Posted on: 7/15/2009 at 12:44 PM
Tags: ,
Categories: SQL Server | Transact SQL | SQLServerPedia Syndication
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed