Question

In Visual Studio, say you've got a SQL 2008 Database Project and you add a non-nullable column to a table. When you go to deploy the database now, if that table has data in it it should fail. (Right?) How would you write custom logic so that during the update you can set this column to "x" or use a more advanced query or cursor to update the entire table and fill in the new column? This is something you would only want to happen once - at the same time the column was added to the database. Is there any support for this?

Was it helpful?

Solution 5

Here's what I ended up doing.

  1. Add version info to the database (e.g. in a SystemSettings table).
  2. Create a script for the next version (e.g. 1.1.0.0.sql).
  3. In the Scripts\Post-Deployment\Script.PostDeployment.sql file, add the following:

DECLARE @versionMajor INT;
DECLARE @versionMinor INT;
DECLARE @versionBuild INT;
DECLARE @versionRevision INT;

SELECT TOP 1
    @versionMajor = VersionMajor,
    @versionMinor = VersionMinor,
    @versionBuild = VersionBuild,
    @versionRevision = VersionRevision
FROM SystemSettings;

IF (@versionMajor <= 1 AND @versionMinor < 1)
BEGIN
:r "..\Upgrade\1.1.0.0.sql"
END

This will run the 1.1.0.0 script if the database version is lower. The 1.1.0.0 script updates the database version numbers as its final step. Future updates simply require you to add another IF block.

OTHER TIPS

I would add a nullable column, run an UPDATE command to populate it, and alter the column to NOT NULL. Although I do use Visual Studio 2010, I do not use it to deploy. Instead, I deploy with SQL Compare - it generates a SQL script, which is easy to tweak.

Here is how I do it.

In the Schema Viewer open the table creation script and add the new columns like so:

[first_name]        varchar( 32 )   NOT NULL default ' ',
[last_name]         varchar( 32 )   NOT NULL default ' ',

Because they have a *default value * they can deploy successfully.

Then in my post install script I check for ' ' values in the table and run an update to populate them if so. Alternately the code could fix it.

update mytable
set newcolumn = 'x'
where newcolumn is null;

I have done a lot of research on this type of topic, and sadly it seems to be an area where VSDB projects are lacking. A good place to start looking is the Visual Studio ALM Rangers guide to VSDB projects; they have a hands-on-lab detailing their recommended best-practice for doing exactly what you ask about (it involves using pre and post-deployment scripts to copy data to and from transient tables). Additionally, Barclay Hill's blog has an article pertaining to your question (he's the Sr. Program manager for Data Tools), which is the same as the guide.

This recommended method seems to me as having a very high maintenance cost if you have to be able to update multiple different versions of a target database, but if you only have one database (or one version of the schema) to update, it is pretty workable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top