How to create incremental scripts to update database schemas using Visual Studio 2010? - visual-studio-2010

I'm trying to use VS 2010 Sql Server Database Project to keep track on changes made on my database and to generate appropriate scripts when a change needs to be deployed from dev to production environment.
I have created my schema comparison between my dev database and the project schema which does a great job. However, I cannot find a way to create incremental scripts, the only things I get are scripts with CREATE statements (Export to Editor option).
Am I doing something wrong?
Thanks in advance.

As part of our auto build process, we store .dbschema files for each environment in source control. During the build, we create the .dbschema file based on the database project and then use vsdbcmd command line call to generate the change script between the project schema and each destination DB schema. If you need specific command line call, let me know.

If you're using "Data Dude" correctly, these are done for you and run when you choose Deploy. Just keep your schema (tables, stored procs, populate scripts etc) as a project item and change it as you need to. The build-and-deploy process will generate the scripts. http://msdn.microsoft.com/en-us/library/ff678491.aspx is a not-bad starting point if you want to get these scripts and run them youself against various staging, production, etc databases.

In the .deploymentmanifest file there are two settings:
<DeployToDatabase>False</DeployToDatabase>
and
<DeployToScript>True</DeployToScript>
Running vsdbcmd will then generate the change scripts without affecting the target database. All you'd need is a version of the database which is the same as the production version, or access to point vsdbcmd at production to generate the script.

Related

Can I automatically generate a change script using a .scmp file?

We're using database projects here at work and for our deployment to the production server, our current process is to manually run a compare using a saved .scmp file that compares the database project to our production database (using a read-only login), then generate a SQL script that we give to our I.T. support guy to run on production. We also do a build to generate our post-deployment script, and we give that one to our guy to run as well.
I'm trying to automate as much of this process as possible (to reduce the chances of mistakes and make it more efficient). I'd like to know if there's a way to automatically generate the sql change script using the predefined options in our .scmp file.
Additionally, is there an easy way to automate the appending of the post-deployment script to the end of the schema change script, so he just has one sql file to run?
Perhaps there's a nice way to do the whole thing with powershell or something.
Ok what you should do is use sqlpackage.exe to create your script from the dacpac that is produced by building the ssdt project.
Create a batch script to call it or make it a part of your CI process.
To filter the output there are some new options like exclude certain types in the latest (March 2015) release of ssdt or use a deployment filter like:
http://agilesqlclub.codeplex.com if you need more flexibility.
Using this you can filter the deployment like the compare and also the pre/post deploy scripts are pre/appended so you kill two birds with one stone!
Ed

How do I deploy specific objects from a Visual Studio database project?

I have a Visual Studio 2010 database project and I'd like to do a partial deployment, i.e. of specified objects. Is this possible? The only options I can see are to either do a full deployment or stop after generating the script.
For example, I'm changing many tables and stored procs but not everything is 100% finished and I'd like to push out a specific stored procedure to my test database, including its permissions, etc.
I read a little bit about SQL Server Data Tools, which apparently supports this, but I'm not clear on whether I'd have to migrate my database project to use that instead (would also need the ok from team lead), or if it's simply a plugin that would allow extra functionality.
Check out Schema Comparisons. They allow you to select the objects you want to deploy. They are available without SQL Server Data Tools.
A "partial deployment" is actually a little dangerous. Consider that you will have just built your database project, your entire database project, complete with the table changes, and it has built with no errors or warnings (right?). Now you want to deploy just your stored procedure, into a database that does not have the table changes.
Your stored procedure got no errors or warnings in the context of all the changes. Are you sure it will get no errors or warnings without those changes?
You should consider a source control solution to this problem. Save a copy of your stored procedure, revert to a version of the code that matches the database you'll be deploying to, then make your stored procedure changes to that. When you deploy, you will be checking to see if the stored procedure makes sense in the context of the database you'll be deploying into.

Staging database version changes in development with RoundhousE

EDITED: from original as frankly it was a poor question first time around....
We have a batch script called DEV.DBDeployment.DropCustomCreate.bat, as the name suggests this drops and creates our db from a fresh, a useful tool in Dev but we don't always want to drop the database, sometimes just get the latest changes.
It's worth noting currently every CI checkin triggers a build in TeamCity which pumps the current Major.Minor.BuildNumber.Revision (e.g. 1.0.123.1568) number in to all AssemblyInfo.cs files within all Visual Studio projects. This obviously allows us to stamp the resultant dll's with the build number, pretty standard stuff for sure. We also overwrite a BuildInfo.txt file in a similar way, most importantly this BuildInfo.txt file is included within every deployment package and sits within the RoundhousE\deployment folder and is referenced by /vf=%version.file% when we run rh.exe as mentioned above from the .bat file. So we're sorted for deploying to existing databases in Test and Prod.
However in dev the AssemblyVersion is always 0.0.0.0 in AssemblyInfo.cs, as is the version number in BuildInfo.txt, therefore how do devs stage their changes locally against their database. For example, with this setup when we run rh.exe all changes will be stamped with the version number 0.0.0.0. Is the expectation that in dev you will always drop and create? If that's the case I'm assuming we need TeamCity to checkin the BuildInfo.txt file so RoundhousE can reference it from source control when executed in dev?
Is there something I'm missing here?
I think we discussed this over here - https://github.com/chucknorris/roundhouse/issues/113
As you saying about the .bat file; that is a tool for roundhouse. You have to run that batch file again and again when you want to run your scripts. If you want to run scripts when you build the roundhouse database project then you have to configure that with certain steps. If you wish I can tell you if you replied.

How to re-deploy, re-create database on each test run

Currently I'm using Visual Studio 2012 RC and SQL Server 2012 RTM.
I'd like to know how to re-deploy/re-create a test database for each test run.
Keep in mind I've a SQL Server database project for the database using Visual Studio 2012's template.
Actually I'm not very sure about an idea I got in my mind, but .testsettings file has Setup and cleanup scripts. Is this the way to go? For example, a PowerShell script reading the database project generated script and executing it against the database?
I guess there're better ways of doing that and it should be an out-of-the-box solution but I ignore it and Google doesn't help me in finding the right solution.
As mentioned you'll probably want to use the VS 2012 .Local.testsettings > Setup and Cleanup scripts to create / tear down you SQL Server database.
For the script you may want to use powershell with a .dacpac (rather than just a T-SQL script), since you are using a SSDT project. Here's a link to some example code - in particular you may want to take a look at the 'Deploy-Dac' command.
If you are unfamiliar with .dacpacs as the (build) output of SSDT-created database projects, take a look at this reference link.
Edit: Although this doesn't answer the question in a plain SQL Server way, an easy Entity Framework approach would be the following: I found that I could create and destroy my database every time correctly by using the DbContext.Database.CreateIfNotExists() and DbContext.Database.Delete() methods in my setup and cleanup phases of my tests.
The fastest solution, while a bit of a hack, is really straightforward. You can set the DB Projects properties under the debugging tab to "always re-created DB". Then test in two clicks, do a debug/build, then run all tests. You should get a freshly built DB on localDB for you tests to be ran against. You can also change the target for the debugging DB (again the DB projects properties) to whatever you want, so you can deploy to a .dacpac, or to an existing SQL DB or wherever. It means testing in two steps, and if your build is long, it may be annoying, but it works. Otherwise, I believe scripting is your only option.

Seriously, overriding the DefaultDataPath in the sqlcmdvars for a SQL Database project deployment

I have an SQL 2008 database project in Visual Studio 2010 that is sync'ed on a regular basis from a schema comparison during the development phase. This same project is also under TFS source control. I have two environments, Debug and Production. Each environment is a single machine that runs both IIS and SQL Server. The production environment however has different data and log paths for the database D:\Data\ and E:\Logs\ versus my development server at the standard c:\program files\sql....\data.
What I'm trying to do is setup the way I transact my deployments from the debug to production environments. I've gotten WebDeploy 2.1 setup and I build my deployment packages in Visual Studio via the right-click context menu on the website project. I want to manually copy deployment packages to the production server via RDP, so there's no over the wire concerns here. The deployment package settings are setup to include all databases configured in Package/Publish SQL tab. In the Package/Publish SQL tab I don't pull data from data/schema from an existing database because I want to deploy from the SQL database project instead. So I just point to the pre-generated .sql script file located in my database project's /sql/release folder. To top it off, I generate the .sql script in the post-build events in the SQL project via VSDBCMD.exe /dd:- /a:Deploy /manifest:... so that a simple solution rebuild all, then website project deploy ensures I always have the latest .sql script in the deployment package.
This is great and all, but I have a major problem here I can't seem to overcome. It has to do with the database data and log files paths being different from debug to production environments. I actually receive an exception during the WebDeploy in IIS on the production server that says it can't find c:\programs files...\MyDatabase.mdf file. And what's scarey is after this exception, the entire database is deleted. The empty databases I create right before doing the deployment. Happen both times I tried messing around with it. I'm not sure how I feel about that, but I'm hoping I could find a reliable solution to this.
I have been feverishly looking for a way to change the paths during a deployment and have found many places that mention changing the paths in the *.sqlfiles.sql files under Schema Objects\Database level objects\Storage\Files because the path it tries to deploy to is the path specified in those because of the Schema Comparisons and Writes from the Debug SQL server database. Changing the paths here will work temporarily, until I do my next schema comparison and write, then the sqlfiles.sql files will get overwritten with the info from the Debug database again. And I don't want to have to remember to never update these files during a schema comparison because any mistake has the potential to delete the production database.
I think my salvation lies in my Release.sqlcmdvars file. It's a tease actually, I can see a place I "could" type the default database path, but it appears to a read-only field as it mentions "Location where database files are created by default (set when you deploy)." It would be grand if I could specify the paths here. Is there any way at all to specify the path in a variable here that would override the paths from the *.sqlfiles.sql files?
In the solution where I work at, there are two custom variables in the sqlcmdvars called Path1 and Path2 that I thought were reserved names that do such that. However, this doesn't work in my solution and the difference between the two solutions are the other solution gets deployed via TFS build controller. Doing the TFS build controller route isn't an option really because I opted out to save money while using a third party source control service.
Any help with this would be great. I have even gone so far as to create separate *.sqlfiles.sql files for debug and release and configured the dbproj file to use one or the other depending on the Configuration, but this doesn't seem to be working either. Also, using the custom PATH1 variable in the sqlfile.sql file like FILENAME = '$(PATH1)\Cameleon_log.ldf', doesn't work either. I seriously think it shouldn't be this difficult. Am I missing something simple here??
Thanks!
Okay, this was an exercise in futility. Apparently with out syncing with the target database during the script generation the script would be exactly what is needed to build the database from scratch. Even if I could override the file paths, the deployment would complain about database objects already existing. I needed to specify the connection string of the target database in the deploy settings so a comparison is done during the script generation and only the relevant differences are added to the script. I really wanted to avoid exposing my production SQL server to the outside world, but it is what it is. No need to override the paths anymore because it looks the database file paths are conveniently ignored during this comparison!!

Resources