Let's say I have a table like so:
CREATE TABLE Foo
(
Id INT IDENTITY NOT NULL PRIMARY KEY,
Data VARCHAR(10) NOT NULL,
TimeStamp DATETIME NOT NULL DEFAULT GETUTCDATE()
);
Now let's say I build this in a SQL Server Database Project, and I publish this in version 1.0 of my application. The application is deployed, and the table is used as expected.
For the 1.1 release, the product owners decide they want to track the source of the data, and this will be a required column going forward. For the data that already exists in the database, if the Data
column is numeric, they want the Source
to be 'NUMBER'. If not, it should be 'UNKNOWN'.
The table in the the database project now looks like this:
CREATE TABLE Foo
(
Id INT IDENTITY NOT NULL PRIMARY KEY,
Data VARCHAR(10) NOT NULL,
Source VARCHAR(10) NOT NULL,
TimeStamp DATETIME NOT NULL DEFAULT GETUTCDATE(),
);
This builds fine, but deploying an upgrade would be a problem. This would break if data exists in the table. The generated script will create a temporary table, move data from the old table into the temp one, drop the old table, and rename the temp table to the original name... but it won't if there's data in that table, because it would fail to assign values to the non-nullable column Source
.
For trivial refactors, the refactor log tracks changes in the schema, and maintains awareness of the modified database objects, but there doesn't seem to be a way to do this when you get your hands a little dirty.
How can the Database Project be leveraged to replace the default script for this change with a custom one that properly captures the upgrade logic? There must be some way to address this issue.