How are the different collation settings related and applied in the SQL Server project type in Visual Studio 2010? - visual-studio-2010

In the Project Settings tab of the project properties page there is an option called Collation for database model.
There is also an option in the project settings (the .sqlsettings file) called Database collation.
And then in the Deploy tab of the project properties page there is a link to the Deployment configuration file which has an option called Deployment comparison collation.
I'm confused, but more importantly, even though I have set that last option to Use the collation of the server the deployment script always contains the following statement:
ALTER DATABASE [$(DatabaseName)] COLLATE Latin1_General_CI_AS;
Which results in the following error:
ALTER DATABASE failed. The default
collation of database 'Database'
cannot be set to Latin1_General_CI_AS.
Ideally I don't want to think about collation, and always follow what is set at the target database level, but somehow the various options of the SQL Server project make it hard to predict what's going to happen at actual deployment.
Can you explain what each of these options do and how they interact with and/or override each other?

While I cannot shed much light on what the plethora of different collation settings do, I can point out one setting that helped me when searching for a remedy to the ALTER DATABASE COLLATE always being in the deployment script.
In the Database Project => Properties => Database.sqldeployment settings there is a ScriptDatabaseCollation that when unticked, fixed my issue.

I believe the COLLATE Latin1_General_CI_AS that you are seeing is coming from the Default Collation specified in your Project Setting. This can be accessed via:
Project Properties > Project Settings > Edit the Catalog properties file
This will open the Database.sqlsettings and you will see the first entry is the Default database collation that your project uses when generating scripts.
The Deployment Comparison Collation is used for the database comparing models when you deploy the project. I think this only functions if you are deploying directly to a database and not if you are using the default settings of generating a .sql script file.
As eddie noted, there is a setting in the Database.sqldeployment file that when unchecked, removes the annoying collation specifier from the CREATE and ALTER scripts.

Related

Database project: database references do not work

In a database project DB2 has references to DB1. When I make a dacpac of DB1 and add a reference to the dacpac in DB2, then the project compiles without error.
Since DB1 and DB2 are in the same solution anyhow, I am trying to add a database reference instead of the reference to the dacpac. Since DB1 and DB2 may reside on different servers with different names in production, I added $(parameters) for databases and servers. The project does not compile:
Error 1069 SQL71561: View: xyz has an unresolved reference to object
[$(server)].[$(dbname)].[someschema].[sometable].
The parameters are set correctly. Did I overlook something concerning database references?
First just to verify that the projects themselves are setup correctly.
You have a project in the solution for DB1.
You have a project in the solution for DB2.
To start with a clean slate (often easiest with database references - you cannot edit properties easily after the reference has been added). Remove any existing database references to DB1 from DB2 project.
Do a clean of the solution.
Build DB1 (Verify that a DACPAC has been created for DB1 in \bin\debug etc) and fix any errors if necessary.
In DB2 add a database reference to a solution item. Right click on References, select Add Database Reference. In the dropdown choose the first item (Database project in the current solution). Choose DB1.
At the bottom, select 'Different Database, Different Server' from the dropdown.
Enter the variables again. Verify that the example usage at the bottom indicates 'SELECT * FROM [$(server)].[$(dbname)].[Schema1].[Table1]' (Or similar depending on your choice of variable names). Take note of that sample and copy that to a note or clip somewhere.
That should resolve the issues. You have already changed the views \ procs to reference the variables.
I think the easiest rule here is if you aren't sure, delete the reference and add it again. There is no easy way to edit variable names etc. In addition, if DB1 build fails, then you will still get reference errors like above.
I hadn't noticed that the referenced database projects in my solution did not compile in Visual Studio because of compile errors. Once the referenced projects compiled, the reference to those projects also worked.
Being able to extract a dacpac in Visual Studio is no indication for the circumstance that the project compiles; when extracting a dacpac directly from a database the external references of that database will be valid while the database project must be provided with those references first.

Allow (once) column drop in database project

I would like to drop one column in existing table. When I simply remove it from table's create script it will cause error (data loss...) on deployment. I would like to allow (in this case) column drop. How you would do that?
To disable the data loss error:
Click the Options icon in your schema comparison file.
Uncheck "Block on possible data loss".
The setting will change for just that 1 schema comparison and it will be saved within the schema comparison file. If you only want to do this once then you'll need to re-enable the option after you drop the column.
We did this by creating a PreDeployment script to drop the column. Reasoning is we do not want to allow data loss for all objects in the database.
You can create automated version checks to do this only once (see my answer to another post Nontrivial incremental change deployment with Visual Studio database projects for steps how to automate this with SSDT.)
Or you can just supply the script to devops and include instructions in your install manual to run it once for a specific release.
After the release has gone live, you can delete the PreDeployment script.

How to make Visual studio schema comparison igonore database references

We are using Visual studio 2010 and our database scripts are in a database project.
We have two databases DB1 and DB2. DB1 uses DB2.
I created a database project for each of databases and added DB2's .dbschema file as a "Database Reference" to DB1's project.
So my code for my view in DB1 is like
CREATE VIEW dbo.myView
AS
SELECT * FROM [$(DB2Ref)].dbo.SomeTable
GO
Until here all is fine.
But when i make a schema comparison between actual DB1 database and DB1 database project, comparison finds a difference between "myView" in project and "myView" in database.
Is there a way to make schema comparisons igonore these referenced database variables ?
Yo can set the Default for the SQL CMD Variable in the project settings to the actual database name. The schema compare in visual studio will then know that there is no change.
Unfortunately if you compare against different databases with different names, you'll need to change this Default each time to the database you're comparing to.
Setting SQL Cmd variable Default
SQL Schema Compare of View - the top is without the default defined and thus the object is marked as a change, and the bottom with the variable defined and thus marked as no-action
Sorry not enough rep to add images or more than 3 links yet

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!!

How to create incremental scripts to update database schemas using 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.

Resources