How to disable dropping and creating views and functions when publishing database project? - sql-server-data-tools

When I publish Visual Studio database project targeting SQL Server 2012 it generates script containing drop views and functions statements and then creating these views and functions, although there are no changes in these views and functions in DB project at all comparing to database. How can I disable this behavior?
I would like to have publish output equal to what I get when I generate script after schema compare (project to database), so only affect objects for which there are changes.

Are you absolutely sure that there are no differences? Even a difference in the "NOT FOR REPLICATION" options can cause issues. Do a compare of the live database against your project and see what is different (Tools - SQL - Compare Schema). If there are differences, fix them. Otherwise, you shouldn't be seeing anything to actually change. As Keith noted, check to make sure you don't have the "always re-create" option enabled. That could be giving you trouble, though it doesn't usually drop individual items, but the entire database. You may also want to check collations - if those are different you could have issues.

Make sure the "Always re-create database" option is unchecked in the Advanced publish settings.

Finding the reason for why SSDT thought the scheme was different I think is the first point of call. SQL Scheme compare is your friend here. (In VS under Tools => SQL => New Scheme Comparison...)
Computed column definitions and constraint definitions were definitely candidates, as was potentially column ordering. Ironically I did have one issue with a computed column but it was not the definition, it was the fact that I didn't add NOT NULL to the end of the column definition (which is the default of course) but SSDT saw that as different everytime.

Related

Duplicate column issue in migration scripts in .net microservice module. I have to resolve duplicate column in my migration which already executed

In .net core microservices, another team works on open source modules, and I extend their modules in my project. I already added one column in a Entity and then same column is added by open source team. Now duplicate column error is showing.
I can not alter open source migration files and my column is already in production.
How to resolve this issue please suggest.
i think we are dealing with multiple smells here.
each microservice should have its own Datarealm
by the sound of it you extended a Table of an object which was generated by the opensource service
But this does not help you, the question is can you merge the Data which is in this column.
If so you might get away with a simple copy/update.
What you need todo is:
Create a new Column With a different Name
Copy your existing Data into the new column
Drop your column
Execute your Migration
Copy your Data back into the column
Test your application very carefully, if the logic which you have implemented for the from you generated Data works as intended
Drop your backup column
Depending on the amount of Data this will lead to a downtime, so plan ahead and have a rollback strategy ready if something goes wrong.
Personal Opinion to Prevent those Smells
Every time i needed an opensource project in my projects in the past i wrote a wrapper around it, this has multiple benefits.
For one if the api of the project changes you only have to update it in exactly one place, which improves the maintainability.
Because it has a wrapper it automatically gets a own Database and if i need to extend an entity which i get from one of those opensource projects, i usually do it via Foreign Keys with a different Table. Which then gets linked via a view.
Yes this costs some performance, but in the end it was worth it every time.

Is it possible to exclude objects/object types from sqlpackage?

I would like to exclude certain object, for example all logins & users, from extract or publish operation of sqlpackage.exe.
This is possible from within Visual Studio, so I hope it is also possible from the sqlpackage.exe.
Or is it not possible?
The reason is that I would like to be able to auto-deploy to various environments/servers, where the logins & users are different.
NOTE: Logins & Users is only an example, the question is more general.
It is now. Please update the tools and look at this post.
http://blogs.msdn.com/b/ssdt/archive/2015/02/23/new-advanced-publish-options-to-specify-object-types-to-exclude-or-not-drop.aspx
I solved this problem by creating a DeploymentPlanModifier contributor (following their SchemaBasedFilter sample) that I pass-in through in an argument (/p:AdditionalDeploymentContributors) for SQLPackage.exe, it looks for any drop operations of security object types.
(Code on Prevent dropping of users when publishing a DACPAC using SqlPackage.exe)
Your best bet at this point is to look at doing this in post-deploy scripts and excluding all logins/users from your projects. We have similar issues where each environment has a different set of logins/users and SSDT just does not handle this well out of the box. I've written about the process we use on my blog (borrowed heavily from Jamie Thomson).
http://schottsql.blogspot.com/2013/05/ssdt-setting-different-permissions-per.html
I'll also note that the user "pavelz" left a comment briefly describing the process they use w/ composite projects - main project for objects and sub-projects for permissions. That could work as well.
The only issue we have run into with the post-deploy process is if you enable publishing to drop permissions/logins not in the project, you could have some down time until you re-add the permissions at the end. Once set, I highly recommend turning off those options.
Sadly, as of now sqlpackage.exe utility does not have any option of excluding a specific object. However, it does have options to exclude an entire object type.
All of the same options available inside Visual Studio can be used in SqlPackage.exe. See "Publish Parameters, Properties and SQLCMD variables" in the documentation for a full list of options you can pass. They generally look like "/p:IgnoreUserSettingsObjects=True" and are passed alongside the regular arguments when calling SqlPackage.

How to avoid code duplication for non-data structures (views, stored procedures etc)

My project contains a lot of objects like views and stored procedures which are being changed quite frequently. Now I have to create new SQL script on every update which contains complete source code of changed objects despite I've actually changed only few rows. It leads to massive code duplication and I also found it difficult to review these changes.
I'd like to have only one actual version of SQL script for every object like view or procedure and recreate these objects every time I redeploy the database. As result I could change existing source file (like in Java or C programming) instead of creating a new update every time I need to alter view or procedure.
Is there a possibility to execute some scripts every time I migrate the database with Flyway?
I'm not sure why that got so many downvotes, it's a perfectly understandable and valid question. Perhaps it's because it closely resembles this open question:
Migrating Stored Procedures with Flyway
We are actually starting to push against this issue now. We've been using flyway for development and testing (and love it). But we've come to a point where we're starting to have to use procs/triggers/views (p/t/v's) and the fundamental disconnect between how we did it before, and how we must use flyway, is starting to be a strain.
Before, for a given database object (let's say it's a procedure), there'd be one source file. And if you needed to change the proc 'n' times, there would be 'n' versions of the same file in your VCS. Diff tools work great, IDE's all understand this, merges detect when two developers working in separate branches make changes to the proc, etc, etc. You know, old school.
But with flyway, any one proc with 'n' changes is now scattered across 'n' files. Instead of "one object in one file with 'n' versions", you have "one objecct in 'n' files with one change each". I now need to do a text search in my IDE for any instance of "proc_name" if I want to know the history of changes to the proc. The VCS knows nothing about it. Devs can each make a migration in their own branches that succeed when each is deployed, but leave the proc with a missing update.
I'm not saying any of this to complain about flyway, and I fully realize it's not a simple area. I'd almost say it's unsolveable (by flyway).
We're scheming how to handle this problem, and I'd be very interested to know how others have handled it.
Repeatable migrations are supported by Flyway 4.0, now.
Just add sql files starting with "R" without any version information to your migration folder:
R__Blue_cars.sql
You have to ensure, that the script could be repeatable migrated.
This is usually done by "CREATE OR REPLACE" clauses in your DDL statements.
https://flywaydb.org/documentation/migration/repeatable

Best way for "database specific" sql scripts with Flyway

I started to use Flyway in my current project for database migrations and I like it very much. I currently use Oracle in PROD- and Derby in TEST-Environment.
Pretty soon, I did run in the problem of database specific sql commands, e.g.
ALTER TABLE T1 MODIFY F1 VARCHAR(256); on Oracle vs
ALTER TABLE T1 ALTER F1 SET DATA TYPE VARCHAR(256); on Derby.
I can't see a way to write a "vendor neutral alter table modify column datatype" sql.
What's the best way to deal with this problem using Flyway?
You can use the flyway.locations property.
In test in would look like this:
flyway.locations=sql/common,sql/derby
and in prod:
flyway.locations=sql/common,sql/oracle
You could then have the common statements (V1__Create_table.sql) in common and different copies of the DB-specific statements (V2__Alter_table.sql) in the db-specific locations.
An even better solution, in my opinion, is to have the same DB in prod and test. Yes, you do lose a bit of performance, but on the other hand you also eliminate another difference (and potential source of errors) between the environments.
The differences in SQL between Oracle and some of these desktop databases is minor. Is it possible for a developer to insert custom code to do some light-weight dynamic stripping of the SQL at runtime based on the environment (e.g. remove tablespace designation)?
I prefer this approach to relying on each developer to manually keep two sets of SQL in sync.

Why altering of a column is not permitted through query but easily done is server explorer

I am having a question i.e when i tried to alter a data type of a table by query or by modifying the data type directly i used to get some errors stating this can not be done. But where as if i open the same table in server explorer from visual studio and modify the data type it was easily done with out any errors.
I tried to modify the primary key which is a foreign key for some tables from data type int to varchar using Management Studio it throw me some errors.
But the same thing when i done through Server explorer from Visual Studio it was done in a fraction.
Can any one tell what was the difference
I think I had this issue (at least with sql server 2008):
Take a look at Tools->Options->Designers.
uncheck "Prevent saving changes that require table re-creation"
and try again.
You can see more info here about when it occurs if the option is checked.
Without seeing your specific error, all I can say is that the UI does far more than a simple command. It sometimes creates temporary storage and the copies data as it needs to, to make the experience pleasant. You should use the scripting function in the UI to capture the change and see what it's doing?
It can be done using a query, because that's exactly what SQL Server does. However, the script is considerably more complex than a simple ALTER TABLE statement; generally involving creating a temporary table with the changed datatype, copying the data from the original table, dropping the original table, then renaming the temporary table.
When modifying the structure of a table in the Design view in SSMS there is an option to generate the script for the change(s), so you can run it on multiple servers, etc. This will show you the exact process that is actually happening behind the scenes.

Resources