Is there way to get Visual Studio environment variable in SQL seeding script? - sql

Is there way to access visual studio environment variables such as $(SolutionDir) in T-sql seeding script? Basically, I have a set of seeding script, but I try to avoid reference the hard-code path such as C:\projects**\seeding.sql, instead , I want to use $(SolutionDir)Seeding.sql

Here is the general process for using project variables in SQL in your database project from MSDN:
How to: Define Variables for Database Projects
This depends on what version of Visual Studio you're using (and whether you're using a database project -- highly recommended), but the general idea is you can assign some of your project variables as SQLCMD variables, build a SQLCMD script using those variables and when you run a build, the system will use SQLCMD to invoke your script, applying the variables as necessary to run your script.
Even more to the point, the database project's recommended practice for "seeding" scripts and other post-build artifacts is to designate one SQL script as the post-build script and have it use SQLCMD syntax to invoke other .sql script files.
So in my project (for example) I have this SQL script in a Scripts folder:
:r .\PopulateNumbersTable.sql
:r .\Insert.Dimension.Date.sql
:r .\FillInMetaData.sql
:r .\Permissions.sql
Which then calls each of those scripts (also in the folder using relative paths) which are run in SQLCMD mode. So in PopulateNumbersTable.sql for example, I set the max value of the numbers table as a SQLCMD variable so when the script runs in the post-build it uses that value.
Anyway, check out SQLCMD and VS Database Projects, it basically covers what you're looking for, it's plenty flexible and (for me) pretty easy to understand.

Related

Visual Studio Database Project: Include 'If Exists' checks for all the objects

We use TFS Continuous Integration to handle our staging and deployments of code. In our current environment, we (developers) aren't allowed to manually update databases in Production. A script must be staged and then given to a DBA to run.
By default, the database project builds and outputs a database creation script that will create all the tables and stored procedures. However, it does not include checks to see if the object already exists.
For example, when it attempts to create the Customer table, I would like to have the script check if the table already exists, if it does alter the table.
Is this at all possible?
VS can create a script for just the changes. I think this approach will be better than using existence checks because it will be able to handle column changes, and overall it makes for a shorter and more targeted script.
Right-click the project and select Publish.
Click Edit and enter the connection details for your staging database.
Back on the Publish dialog, click Advanced and make sure "Always re-create database" is not checked.
Back on the Publish dialog, click Generate Script.
What this approach does is compare the objects in the database project to your staging database and generates a SQL script for just what is different. You can even save the publish settings to a file to make it easier to generate future scripts.
Keith is right you need to script the changes rather than just using the create statements.
You basically either need a copy of the production database to run a comparison against or you give the DBA's a way to run the comparison and deploy.
The way I prefer to do it is with TFS is to use SSDT in Visual Studio, I then have a custom build step as part of the .sqlproj file that builds the dacpac, uses sqlpackage.exe to compare the dacpac to the mirror of production (or dev, uat, whatever) - this then outputs a script that will take that version of the database to the same version of the code as the dacpac.
You can adjust this slightly to auto-deploy to dev, uat etc and just create the script in production but the choice of exactly what you do it up to you!
If you can't get a mirror of production or a copy of the schema of production etc, you can give the dacpac to the dbas and and either a batch file or powershell script ot drive sqlpackage.exe to create a script or just go ahead and deploy.
Exactly what works depends on the environment you are in!
Ed

What is the best way to manage "non-SQL Server" SQL objects within Visual Studio 2010?

Visual Studio has a Database Project for Sql Server. This has a number of advantages: it hosts configuration settings, and database objects in one place. The .sql files are part of the regular .NET solutions - visible in the Solution Explorer and editable in Visual Studio. And they have a mechanism for generating a deployment script. With each individual database object in it's own file, the tracking of changes and source control is greatly simplified.
Has anyone had any success with using Database Projects with "non-SQL Server" databases? We use Sybase - which uses T-SQL and is very similar to SQL Server so I'm hopeful.
Or is there an alternative approach? I guess I could use a standard project (.csproj) and call a custom commandline application as part of the post-build to convert the .sql files into a deployment script.
Any ideas would be welcome.
Thanks
OK, I'll answer my own question.
I added all of our SQL objects to their own .sql files within a Visual Studio .dbproj project. However, minor syntactic incompatibilities between the Sybase version of RAISERROR and the Microsoft version of RAISERROR caused the validation code built into Visual Studio to get unhappy. The problem with the database project was that this actually caused a compilation error - which basically made it into a show-stopper.
So I scrapped that idea and added the .sql files to a standard .csproj project file. I then implemented some custom code that would load all of the .sql files, and aggregate them into a deployment script when invoked. I added a call to the custom code to the post build of the .csproj file so that whenever it was compiled - it would output a deployment script - which works like a dream with our build server.
In order to get some of the benefits of the .dbproj, I looked into writing a full SQL parser, but was quickly discouraged by some of the posts on SO. Instead I did some rudimmentary parsing with regex - which got me a few cool features without a lot of effort:
The code could detect dependencies between the various .sql files, and add them to the deployment script in the correct order to avoid sysdepends warnings.
Where there were no dependencies, objects were ordered based on the object type (stored procedure, function, grant statement, etc) and then by name so that the resulting script was always ordered the same - which is very important if you need to diff two versions of the script.
The deployment script can figure out some of the required permissions, so I don't need to keep track of all of the GRANT statements.
Stored procedures that are in the database but not in the script can be dropped automatically - so I don't need to keep track of what state each database is in - we just run the script and everything is in the correct state.
We have a few stored procedures that our automated tests call that shouldn't be deployed. The code can detect these and include them in a Debug build and exclude them in a Release build.
The custom code also generates a diff script that determines what changes the deployment script will make to a database and prints them out. This allows the person who is running the script to get an idea of what it will do. For example, the diff script might tell them that no changes will be made - so they don't need to run the deployment script at all - which is kind of handy if it saves them logging in at 3am to take a database offline and take backups etc.
So the end result is that all of my SQL objects are in separate files making them easy to work with in Visual Studio and manage under source control. For the first time since I started this job, I can look at the history in source control and tell what files have been changed (before this we had one enormous .sql file with absolutely everything in it).

How to run multiple .sql files in Eclipse DTP

I've a list of .sql script files to create Stored Procedures which I'm using the Eclipse DTP to develop. Currently to create/update all these Stored Procedures, I've to open & run
one by one from the Data Perspective.
Is there a way to create a batch file that run the scripts along the lines of
run createSP1.sql
run createSP2.sql
...
run createSPn.sql
and run it in the Eclipse DTP to avail of the DB connection defined there?
why not just create a batch file that merges all of your .sql files together into a single procs.sql file as part of the build process. I don't know what platform you're running on but in Windows you could have a .bat file that does something like this:
type *.sql > proc.sql
then to apply it to the database, why not do it outside Eclipse and connect to the database via the command line. You could bundle this all up as a single batch file that gets the latest version of your stored procedures from source control, merges them into a single file and then applies it to the database.
Part I
As far as I know the developers of Eclipse DTP
have not yet implemented a command line SQL execution
interface through the Eclipse console view.
See the following URL on the eclipse DTP developer forum
http://dev.eclipse.org/newslists/news.eclipse.dtp/msg00304.html
Part II
While the Eclipse DTP people are working on it,
you can use a database specific tool to load
a master SQL file (all SQL proc files
appended together)
There are database specific console
tools that will load your master SQL file
command line.
(ie. SQL*Plus for Oracle, ij for Apache Derby)
Part III
An improvement over DOS batch is using Cygwin bash
or python or perl to merge all of your sql files
together into a master file.
I found that the text processing tools available
in UNIX (awk,sed,cat...) are great for this sort
of thing.

Pre-Deployment in Database project

Visual Studio 2008 Database project for SQL Server 2008
The project has placeholders for Pre-Deployment and Post-Deployment SQL scripts. They work - well, most of the time anyways.
The project has an option to Always-Recreate-Database: drop the existing database and create a fresh hot-from-the-oven database every time.
When I deploy my database the entire SQL Script is put together and executed.
My database is used for replication, and as a part of the Post-Deployment script, I designate the server as a distribution, create the replication and add articles to it.
Therefore, I have to shut off replication. And the logical place to put that was in the Pre-Deploy.
VS2008 wiped the smug grin off my face pretty quickly. If Always-Recreate-Database is checked then it puts the script to drop and recreate the database, then puts my Pre-Deployment script, and then everything else.
Is there any way for me to change the template of the database project so that the Pre-Deployment SQL scripts are executed where they are meant to execute - before any deployment occurs.
This might not be exactly what you're after but it might help you to work around your problem. after a quick look, I think the sequencing of the pre- and post- deployment scripts might be too difficult to change.
As I understand it, there are some hooks in the build project that will allow you to execute your own code before the deployment begins.
Define a PreDeployEvent property in your .dbproj file.
Define a BeforeDeploy target in your .dbproj file.
Either of these should be executed at the right point in time, I think.
If you use the PreDeployEvent property you'll need to specify the single command line to be executed. A crude example:
<PropertyGroup>
<PreDeployEvent>sqlcmd.exe -i myscript.sql</PreDeployEvent>
</PropertyGroup>
If you want more control, use the BeforeDeploy target which will allow you to run one or
more custom msbuild tasks. Here's another crude example:
<Target Name="BeforeDeploy">
<Message Text="BeforeDeploy" Importance="high" />
</Target>
By the way, there are plenty of custom tasks freely available, one example being those at www.msbuildextensionpack.com.

Transact SQL How to to do?

I need to generate a SQL update command in a *.sdf file.
The *.sdf file is deployed using Visual studio. I am looking to generate a script which fills in a table the maximum number of records which is about 2MBytes.
any ideas for how I can do this i.e. connect remotely to the database and script filling in the database with a dummy record? Examples and deployment would be fab :-)
I presume you have a database project in Visual Studio.
In a database project, the post-deployment script is executed in Command mode. You can use the following syntax to execute any commands that you want executed.
:r "filepath\filename.ext"
Visual Studio Team Systems for Database Developers will do this for you.