The Error
So if you are working in SQL Azure, you’ve probably learned the hard way that you can’t just script out your DDL changes in your local SQL Management Studio and run it against your Azure database. It throws in a whole bunch of extra fancy-pants DBA-y stuff that SQL Azure just doesn’t let you use.
For example, say I throw together a simple table in my local database. Depending on your SQL source control approach (you have one, right?), you might script it out in SQL Management Studio and get something like this:
CREATE
TABLE MyWonderfulSampleAzureTable (
[ID] [int] IDENTITY(1,1) NOT NULL,
[GoEagles] [varchar](50) NOT NULL,
[BeatThemGiants] [varchar](50) NOT NULL,
[TheCowboysAreAwful] [bit] NOT NULL,
[AndyReidForPresident] [varchar](50) NULL,
CONSTRAINT [PK_MyWonderfulSampleAzureTable] PRIMARY KEY CLUSTERED
(
[ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
ON [PRIMARY]
GO
Pretty enough, no? Sure, it’s full of a lot of gibberish you don’t really care about, like PAD_INDEX=OFF, but hey if it runs, what’s the problem?
Now, let’s run that against our SQL Azure database:
Msg 40517, Level 16, State 1, Line 10
Keyword or statement option ‘pad_index’ is not supported in this version of SQL Server.
Ooops. This is a pain to fix when you’re deploying a single script. However, when you’re running a whole development cycle worth of these against your production database at 3 AM and it chokes one of these scripts, this is absolutely brutal.
Censorship Brings Peace
So why does this happen? Why can’t SQL Azure handle these types of cool features? Mostly because they just don’t want to. Sure, some of the features missing from SQL Azure are because they just haven’t been implemented yet, but some of them are deliberately disabled to prevent unmitigated chaos.
While you may have a DBA managing your on-premise database who is working in your best interest (or at least your company’s interest), SQL Azure has a much bigger problem to solve. They need to provide a shared SQL environment that does not let any one consumer hose up everyone else. If you’ve ever hosted a SQL database in a high-traffic shared hosting environment, you’ve probably feel the pain of some joker going cookoo-bananas with the database resources.
In other words, what you do in the privacy of your own home is all well and good, but if you are going to go play bocce in the public park, you’re certainly going to have to watch your language and act live a civilized person.
And a lot of these features you don’t really have to care about anyway. No doubt, you are really really smart and know when your indexes should be recompiled, but the reality is that much of the time whatever algorithm the folks on the SQL team came up with is going to be a little bit smarter than you, Mr. SmartyPants.
Anyhow, for your edification, here’s a wealth of information about the stuff you can’t do.
The Manual Workaround
So how do we get our script to run? My general rule of thumb is to rip out all of the WITH stuff and all of the file group references:
CREATE TABLE MyWonderfulSampleAzureTable (
[ID] [int] IDENTITY(1,1) NOT NULL,
[GoEagles] [varchar](50) NOT NULL,
[BeatThemGiants] [varchar](50) NOT NULL,
[TheCowboysAreAwful] [bit] NOT NULL,
[AndyReidForPresident] [varchar](50) NULL,
CONSTRAINT [PK_MyWonderfulSampleAzureTable] PRIMARY KEY CLUSTERED
(
[ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
ON [PRIMARY]GO
See, I had a general rule of thumb for this, because I encountered it a lot. On just about every DDL script I had to generate. And missed a lot of them. Quite the pain in the neck.
The Much Better, Not-So-Manual Workaround
So I was at the a Philly.NET user group meeting last night and Bill Emmert from Microsoft was walking through the options for migrating SQL Server databases, and he showed us this setting that I wish I knew about a year ago:
If you change this to SQL Azure Database, it will change your environment settings to always use create SQL scripts that are compatible with Azure. No more manual script trimming! Unless, of course, you are into that kind of thing, in which case you really wasted the last 10 minutes reading this.
Good Luck.