Visual Studio 2010 Database Project Deploy to Different Environments - database

I've got a Database project which works fine for my local MSSQL 2008 database.
It has a script under scripts/post-deployment that inserts standing data configuration into a settings table, and other tables. I've got 1 file for each table, e.g. a Setting.sql file to insert data into the Settings table.
The settings will be different depending on the database I deploy to.
How can I script this? Basicaly I would like to be able to have say 2 files,
Prod.Setting.sql and Dev.Setting.sql and VS 2010 would use the appropriate script depending on what database (environment) I am deploying to.

Completely doable but there two options and a few steps involved. You can have a complete duplicate set of scripts, one for each configuration. Or, you can have one set of scripts, the contents of which take into account the configuration you are using. I'll go with the first, and I'll keep it simple.
Create two solution configurations, or use Debug and Release if you like. I'll use these for the example.
For each configuration, create a new .sqlcmdvars file.
Database_Release.sqlcmdvars
Database_Debug.sqlcmdvars
Switch your solution configuration to each and in the database project properties change the variables file drop down to point at the corresponding file you created.
In each of those files you can define variables to be used during deployment. Create a new variable in each one
$(DeploymentConfiguration)
And set its value in each one to either Debug or Release
Then in any of your Pre or Post deployment scripts you can do something like so:
IF '$(DeploymentConfiguration)' = 'Debug'
BEGIN
PRINT 'Executing Debug deployment'
:r .\Debug\SomeNeededScript.sql
END
IF '$(DeploymentConfiguration)' = 'Release'
BEGIN
PRINT 'Executing Release deployment'
:r .\Release\Anotherscript.sql
END

Related

Access Build variables inside Pre and Post deployment scripts SSDT

I have just set up an SSDT project which I want to use to create local databases on the SQL server hosted locally on my machine.
I want to add some pre- and post- deployment SQL scripts for initialization and cleanups.
Since, the server and the database name can change, I have defined two build variables using the project properties each for the target server and target database.
However, I can't seem to access them inside the post deployment scripts.
The syntax below won't build the project -
use [$(TargetDatabaseName)]
This builds, but then fails while publishing -
use ['$(TargetDatabaseName)']
and the error says the ''myTargetDB'' doesn't exist (myTargetDB was passed as a value at the time of publishing)
This might be a trivial thing but I am just not able to get around it. I am on SQL server 2016 if that matters.
Make sure that you put both scripts in SQLCMD mode. See the image below surrounding with red.
Once your target variable is defined, see surrounding with blue in the image above, it can be safely used in the PostDeployment script, see the image below surrounding with blue.
If you have any questions, feel free to contact me.
There is a predefined variable, $(DatabaseName), for the name of the target database. You don't need to create your own; and even if you do, you would need to set the same value to both of them.
Not sure about the target server. In most cases, SQL scripts are generated with the assumption that connection to the correct server is already established. Sure, you can change the current server using something like :connect $(TargetServerName), but I think it will only lead to confusion (and I'm not sure it will work, actually).
The only exception I can think of is that you can't use SQLCMD variables to parameterise the logical/physical names of the database files - these have to be hardcoded.
All other variables, if declared in the project properties, should be accessible everywhere. Below is a fragment of a post deploy from one of my projects:
use [master];
go
print 'Switching database ownership to sa...';
GO
alter authorization on database::[$(DatabaseName)] to [sa];
go
use [$(DatabaseName)];
go
print 'Creating database master key...';
go
-- Create database master key
create master key encryption by password = '$(DMK_Key)';
go
print 'Running database setup...';
go
exec dbo.init_database;
go
It is possible, however, that you are trying to reference another database, located on a different server. If that's the case, you need to follow a different approach, namely: built a project for that remote database and add its DACPAC to the list of project references, using the Add database reference... menu. There, you will be able to specify variables for both the (linked) server and the database name.

How to create database using Database Project in Visual Studio if doesn't exists?

I have a Database project for my personal project and I am trying to deploy my code to my DEV server. I frequently delete and re-create my DEV Server. Right now, DEV Server is newly created with SQL Server. Every time I want to deploy my code I have to manually create Database Project and then publish database project. I want to automate creation of Database with database project deployment.
Right now, I have a script that creates database, but I have to execute it manually. And this is working perfectly but I want to automate this step as well.
Is this even possible? If yes, then how? Please explain step by step. Also what will we mention for Initial Catalog in connection string?
Edit:
I tried to create Database by using
CREATE DATABASE LocalDbTest
in Pre-Deployment Script. But it didn't work. It is creating Database, but then tables are not getting created tables under it. Since I used master database as default database, it is creating table under master. It is not letting me select LocalDbTest database as default because it is not yet created, so I have to select Master as my default database. I tried to Change Database by:
USE LocalDbTest
GO
I used it just after creating Database but this didn't work because when generating script it is changing back to default database. This part is coming automatically when generating script.
USE [$(DatabaseName)];
GO
Also Visual Studio is not letting me add database name in front of table name like:
CREATE TABLE [LocalDbTest].[dbo].[TestTable]
I am getting error:
When you create an object of this type in a database project, the object's name must contain no more than two parts.
If you have a script ready for database creation, you can use the Pre-build event to call SQLCMD and run your script.
Edit:
If you have trouble pointing to a database that does not exist, you may have to manually edit the publish profile (ex. dev.publish.xml) and set the TargetDatabaseName element explicitly. You can also set CreateNewDatabase element to True if you want to be recreated every time it gets published.
Answer:
You can use a publish profile and hardcode the target database in it.

2 Separate DACPAC files for test and production

I have a VS2015 database project (sqlproj) and I created a lot of test data. I added a parameter to the PostDeploymentScript.sql file and when I need an empty database, I set it false and when I publish it doesn't include test data. When I need a demo database I set it true and when I publish, it also adds test data after deployment.
On the other hand, I want to create two different DACPAC files to prevent manual process and build both of them automatically at once. I searched a little bit and found several articles like this:
http://www.techrepublic.com/blog/data-center/auto-deploy-and-version-your-sql-server-database-with-ssdt/
but I couldn't apply what he said. What am I missing?
I created an (almost) empty database project (Lets say Base.sqlproj) which adds lookup table data after deployment. I created another DB project (Base_Plus_TestData.sqlproj) and added a database reference for the first database.
What I need is, if client needs to deploy empty database I'd like to give them the Base.DACPAC. If client needs to deploy a demo database with test data, I want to give them Base_Plus_TestData.DACPAC.
What should I do for this purpose and what am I doing wrong?
There a couple of extra options over what you already do with a switch to include data, I would choose the first :)
1 - Just give customers who want demo data a script to run after deploying the database (you could do something like use a powershell script/.net app to deploy your data and optionally the data)
2 - The post deploy script can be edited in a dacpac, you could build your project, copy the dacpac and then edit the post deploy script to include your data on one of the dacpacs.
3 - Create a separate ssdt project that references your main database project with a "same database" reference and the extra post deploy script - wheb you build you will get two dacpacs you can deploy either together if you want data or just the database.
If you also have data in your original dacpac to deploy you will need to copy it into the "with data" dacpac.
Ed

Scripting FileTables

Scenario:
I have 3 environments that I am using, Dev, UAT and Live. Each of which having it's own database, MyDb_Dev, MyDb_UAT, MyDb_Live.
Then I have a VS2012 Database project in my solution that contains all my scripts. This works nicely when I make changes to my model database (MyDb_Model) that is located locally.
What I want to do:
I want to use the FileTables in SQL 2012 (which I understand how to set up), however I don't know how to script them to be able to configure the options to handle my environments. When I generate the scripts, it will hard code the name to be MyDb_Model as the FileGroup. Also, that said, when I do try and publish to my Dev database, it's complaining about the database options not being able to take the new scripts. When I script include the options of the Model database, it'll complain when I try to publish to my Dev database because of duplicating names.
Question:
Can you script FileTables (with the database options) using the database project in V2012 to be configurable or do I need to manually make my own scripts?
Prefered:
Compare MyDb_Model to Database project.
Publish to MyDb_Dev as a newly created database.
Sounds like you'll want project variables to handle this where the variable contains the environment-specific text for each. You'd then use that variable in your objects instead of the hard-coded paths. The following would create a FileTable called "DocumentStore" and use the value for a variable called "FileTableDirectoryVariable" that you set up in your Project Properties - SQLCMD Variables. Set each of those in your Publish Profiles to use the correct directory, and you should be good. If you're using different filegroups for these tables, you should be able to tweak the FileGroup setting in a similar manner using a SQLCMD Variable.
CREATE TABLE DocumentStore AS FileTable
WITH (
FileTable_Directory = '$(FileTableDirectoryVariable)',
FileTable_Collate_Filename = database_default
);
GO

Deploy Visual Studio 2010 Database Project

I have a Visual Studio 2010 Database project, from which I want to generate a script
that simply puts up this database to another machine. The problem is that i can't find a
solution for this.
As I started the project, I imported the shema from a database on my development pc.
The Schema Objects were generated and all tables and scripts where under 'Schema Objects -> Schemas -> dbo'. Over the time, some things changed, some where added. And by using right-click -> deploy,
the changes were made to my local database successfully.
But now I want to deploy to another machine. The problem is, that in the release folder of the project, there is only a xml dbschema file containing all tables and scripts that i can't import
with sql management studio (or i just can't find out how) and the a deployment script which is nothing more than some checks followed by the pre- and post- deployment script, but without any tables or scripts in it.
So please, how do i export the database from Visual Studio, so i can easily put it up on another machine?
Marks--
You likely have already resolved this, but I thought I should answer your questions for the benefit of others.
Yes, you can deploy from Visual Studio to different machines. You can also do it from the command line, using VSDBCMD. And you can create a WIX project to give a wizard for others to install it with.
If you can connect to the target database from your dev PC, you can deploy to it. To do this:
Select another Configuration from the Solution Configuration drop down. Normally, the Project will come with "Debug" and "Release" baked in. You can add another configuration to allow you to deploy to various targets by clicking "Configuration Manager."
Right-click your Project and select 'Properties', or simply double-click Properties under the project.
Click the Deploy tab. Notice that the Configuration: drop-down shows the same selected configuration as "active."
Change the Deploy Action to "Create a deployment script (.sql) and deploy to the database."
Next to Target Connection String, click "Edit" and use the dialog to create your deployment connection to the target database.
Fill in the Target database name, if different.
For each Deployment Configuration (e.g., Debug, Release, etc.), you will probably want a separate Deployment configuration file. If you click "New," you can create one for the current configuration. The new file will open, and you can check and uncheck important things about the deployment.
Note: If you check Always re-create the database, the script will DROP and CREATE your database. You will lose all your data on the target! Be careful what you select here. Most people leave that unchecked for a Production target. I check it for Development or Local because I want a fresh copy there.
Save your changes to the file and to Properties.
To deploy to the target, be sure to select the correct Configuration. Click Build/Deploy [My Database Name]. You probably should experiment with this so you are familiar with how it works before trying it on a live environment.
Good practices: build a similar environment to production ("Staging") and deploy there first, to test the deployment, and always back up the database before deploying, in case something goes wrong.
For more info, please see:
Working with Database Projects
Walkthrough: Put an Existing Database Schema Under Version Control
Visual Studio 2010 SQL Server Database Projects
Is it's possible to point your Visual Studio to your new target database? 1. Properties of your Database project, Deploy tab, set the fields in Target Database Settings.
Now when you generate a deploy script, the resulting SQL file will be the various CREATe / ALTER / DROP etc that will align the target database with your schema.
You could always create an empty database and then do a schema compare in Visual Studio between your database project and the new empty database. You can amend the generated schema update script to also create the database (since the script will be to update an existing empty database)

Resources