Downgrading an SQL Server Database Using Scripts

One of my biggest annoyances about SQL Server is the inability to load a database from a later version into a previous one. Database files and backups don’t have any indicators of their version (unless you are OCD enough to enforce naming conventions) so whenever I get a backup file from a client (or from my archive) it’s a crapshoot which server it belongs to.

Worst of all, restoring it to a LATER version IS supported, so if I have an SQL Server 2005 backup and restore it to my local SQL Server 2008, it works fine. Then when I attempt to deploy it to the server it’s supposed to go, I get the dreaded error:

The database ‘DatabaseName’ cannot be opened because it is version XXX. This server supports version XXX and earlier. A downgrade path is not supported.

Which is even more infuriating, because God forbid it says something helpful like “version SQL Server 2005” or “version SQL Server 2008” instead of the cryptic and useless “661” and “655”. 2005 was seven years ago and we still don’t have a better error message for this?

So, to make sure I don’t change the version of the database, I have to first try SQL Server 2005, to ensure that it doesn’t attempt to update it if it’s the wrong version. Then I have to go up the chain through 2008 and 2008 R2 because of course I’m not going to remember which number goes with which version…

Of course, the worst part is when the database was created on a later version of SQL Server, but needs to be deployed to a prior version. It’s a rare situation these days, especially since these days I insist needing help with their database be very clear about their environment.

But alas, sometimes it happens, and of course when it does, it’s a pain in the ass to fix. In some cases you can just use the Copy Database or Import Export tools of SQL Server, but these often fail if you’re trying to sync between SQL Server and SQL Express.

The most sure-fire way I’ve found to do the downgrade is to script the entire database (along with all its data) and run that script on the desired instance.

Unfortunately (again!), this is also prone to fail, espcially if your scripts end up being extremely large, resulting in the error:

Exception of type ‘System.OutOfMemoryException’ was thrown.

Sigh.

So long story short (too late!), the solution is to use the SQLCMD utility which is a command line interface for executing SQL commands. This utitliy will execute scripts one line at a time, ensuring that they complete without throwing a memory error.

So once your scripts are generated, launch the sqlcmd utility and execute the following command:

sqlcmd.exe -S [SERVER] -U [USERNAME] -P [PASSWORD] -i “[c:\FULLPATHTOSCRIPTFILE]”

This of course expects that you have the username and password to the server and can connect to it from that machine. For other connection scenarios, refer to the SQLCMD Utility Reference.

Once the database is loaded, you can finally back that up and deploy it to the desired server.