This post is intended for those who are already familiar with SQL Server and want to get started working with SQL Azure. One of the best ways to get up and running quickly is to migrate an existing SQL Server database to SQL Azure. I chose the AdventureWorksDW2008R2 database because it’s optimized for building sample queries and reports.
So think through what you are doing in terms of the databases you create, editions, sizes and the amount of data you move in and out.
It’s also important to note that SQL Azure does not support all SQL Server data types and features. This can complicate the process of migrating your database. Make sure you understand all of the Guidelines and Limitations before you get started.
It’s worth noting that I tried a few approaches before I found something that worked, which I call the brute force approach. Here’s a quick overview of some of my initial attempts. Please note that at the time of this writing I was working with SQL Server 2008 R2 RTM tools and SQL Azure Service Update 4.
At this point I was going to build my own custom Integration Services package, but I decided not to because I needed to migrate more than just schema and data. I wanted to migrate all of the objects in the database as well.
After my initial attempts were unsuccessful, I resorted to what always works best for me and that’s the brute force approach. Doing things this way gave me a much better understanding of the differences between SQL Server and SQL Azure, and now I have a nice library of routines I can use for future projects which I’ll share with you in this post.
Here’s an outline of the brute force approach. More detail is provided in the sections that follow.
In this step you will install SQL Server 2008 R2 and the AdventureWorksDW2008R2 database.
In this step you will provision an empty SQL Azure database that you will use to migrate all of the AdventureWorksDW2008R2 database objects contained in your local SQL Server instance.
In this step you will generate a DDL script capable of recreating all of the objects in your source database. DDL stands for “Data Definition Language” which is shorthand for the various Transact-SQL commands used to create database objects such as tables, views and stored procedures.
In this step you will execute the DDL Script you generate against the AdventureWorksDW2008R2 database you provisioned in SQL Azure. Once completed, all of the tables, views, stored procedures and other objects from your source database will exist in your newly provisioned SQL Azure database. At this point there will be no data in the tables.
In this step you will create two stored procedures in the SQL Azure AdventureWorksDW2008R2 database that will simplify the process of migrating your data.
Use the following procedure to create the stored procedures. The source code for the CreateMigrationAssistantProcedures.sql Transact-SQL script file referenced in the instructions is included at the end of this section. To execute the script, you will use the sqlcmd utility, which is a command-prompt utility useful for performing batch operations against SQL Server and SQL Azure.
Here’s the source code for the CreateMigrationAssistantProcedures.sql script referenced above:
These two stored procedures iterate through objects (foreign keys and indexes) in system catalog views. For each iteration I dynamically construct a Transact-SQL command to enable or disable the object, then execute the dynamically constructed command. I hope you find them useful.
In this step you will use the bcp command-line utility to import data from a “native” file into your destination SQL Azure data base. This step will need to be done once for each table in the AdventureWorkdsDW2008R2 database (with the exception of the three tables we excluded in step 3). When you complete this step, all of your data should be loaded.
@ECHO OFF
SET SourceSqlServerName=localhost
SET DestSqlServerName=myserver.database.windows.net
SET DestSqlUserName=mysqladminuser@myserver
SET DestSqlUserPassword=mysqladminuserpassword
SET SqlDbName=AdventureWorksDW2008R2
ECHO ******************************
ECHO Creating Migration Assistant Procedures
ECHO ******************************
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -i CreateMigrationAssistantProcedures.sql -b
IF ERRORLEVEL 1 GOTO ABORT
ECHO ******************************
ECHO Disabling Foreign Key Constraints
ECHO ******************************
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "EXECUTE [dbo].[SetForeignKeyEnabledStatus] 0" -b
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.AdventureWorksDWBuildVersion
ECHO ******************************
ECHO Disabling Nonclustered Indexes
ECHO ******************************
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "EXECUTE [dbo].[SetIndexEnabledStatus] 0" -b
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.DimAccount
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.DimCurrency
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.DimCustomer
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.DimDate
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.DimDepartmentGroup
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.DimEmployee
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.DimGeography
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.DimOrganization
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.DimProduct
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.DimProductCategory
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.DimProductSubCategory
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.DimPromotion
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.DimReseller
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.DimSalesReason
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.DimSalesTerritory
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.DimScenario
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.FactAdditionalInternationalProductDescription
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.FactCallCenter
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.FactCurrencyRate
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.FactInternetSales
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.FactInternetSalesReason
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.FactResellerSales
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.FactSalesQuota
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.FactSurveyResponse
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
SET TableName=dbo.ProspectiveBuyer
ECHO ******************************
ECHO Migrating data for %TableName%
ECHO ******************************
bcp %SqlDbName%.%TableName% out %TableName%.dat -n -S %SourceSqlServerName% -T
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "DELETE %TableName%;" -b
bcp %SqlDbName%.%TableName% in %TableName%.dat -n -S %DestSqlServerName% -U%DestSqlUserName% -P%DestSqlUserPassword% -E
if exist %TableName%.dat DEL %TableName%.dat
IF ERRORLEVEL 1 GOTO ABORT
ECHO ******************************
ECHO Enabling Nonclustered Indexes
ECHO ******************************
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "EXECUTE [dbo].[SetIndexEnabledStatus] 1" -b
SET TableName=dbo.AdventureWorksDWBuildVersion
IF ERRORLEVEL 1 GOTO ABORT
ECHO ******************************
ECHO Enabling Foreign Key Constraints
ECHO ******************************
sqlcmd -S %DestSqlServerName% -U %DestSqlUserName% -P %DestSqlUserPassword% -d %SqlDbName% -Q "EXECUTE [dbo].[SetForeignKeyEnabledStatus] 1" -b
IF ERRORLEVEL 1 GOTO ABORT
GOTO ENDBATCH
:ABORT
ECHO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ECHO Batch aborted due to error condition
ECHO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
GOTO ENDBATCH
:ENDBATCH
ECHO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ECHO Batch execution completed
ECHO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!