سؤال

We have existing databases under source control in SQL Server Database Projects with a number of these databases referencing each other.

Getting these into projects and source control was challenging enough though I'm finding it difficult to setup Dev/Test environments without using a new SQL server instance.

At the moment we have a copy of the databases on a test SQL instance which is being used as part of continuous deployment. What I am looking to do is to develop in a branch and work against databases with a Dev prefix on the same instance, though realise that these would be referencing the databases used for continuous deployment.

Would this be possible by using Databases variables in Database References rather than just the name, if so how and is there a way to share SQLCMD variables across projects? Are there any alternative ways to consider?

هل كانت مفيدة؟

المحلول

I would tend to suggest using multiple publish.xml files as described here Jamie Thompson blog

The database names (or a prefix) could then be stored as SQLCMD variables.

Each publish file would then be built and published as a build artifact - you'd need to code a custom powershell or batch job to pick the correct file based on the server name. (You could use the server name as a switch here)

You would need to set up the publish file for each environment once, but once that job is done, it won't need doing again.

نصائح أخرى

In a former life I managed a rather large implementation with a ton of identical databases, along with some control databases, on different servers in each environment. We had a lot of cross-database queries that had to work the same whether in dev, QA, test, pre-production, production, etc. My solution - rather than have some script that updated all the server and cross-database references - was to use synonyms.

In Dev, where everything was on one server:

CREATE SYNONYM dbo.ControlTable FOR ControlDB.dbo.ControlTable;

In QA, where the control table was on another server:

CREATE SYNONYM dbo.ControlTable FOR ControlServerQA.ControlDB.dbo.ControlTable;

Now all the code in any database on either environment that needed the control table simply referenced dbo.ControlTable, and we kept synonyms out of our automated syncs / deploys (except in the case where a synonym actually changed).

If we moved that table do a different database, or had a differently named database, or moved that database to a different server, we didn't have to touch any code - we just dropped and re-created the synonym.

In your case, the synonyms in your dev project / dev database could just be:

CREATE SYNONYM dbo.tTableName FOR DevPrefixDB.SchemaName.TableName;

And in your production database:

CREATE SYNONYM dbo.tTableName FOR DefaultDbName.SchemaName.TableName;

If you want to make the synonym name the same name as the object name, you could put the synonyms in their own schema:

CREATE SCHEMA syn;
GO
CREATE SYNONYM syn.TableName FOR DefaultDbName.SchemaName.TableName;

And again in the dev db it would just be:

CREATE SCHEMA syn;
GO
CREATE SYNONYM syn.TableName FOR DevPrefixDB.SchemaName.TableName;

(Now just keep the synonyms - or that schema - as a separately deployable thing from the project to avoid crossing wires.)

I blogged about synonyms here. They're a very useful but under-used feature:

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى dba.stackexchange
scroll top