Question

When I create a Visual Studio database project for SQL 2012 and synchronise it with an existing database (using Compare Schema), I also synchronise a SQL server login. Visual Studio generates the following script for the login:

CREATE LOGIN [my_user] WITH PASSWORD = 'somesecurepass'

When I try to publish the generated SQL on a server where this login exists, sqlcmd shows me an error:

The server principal my_user already exists.

When I look at the sql script generated by Visual Studio, I see that many objects are wrapped in IF EXISTS statements, but CREATE LOGIN is not wrapped!

I tried to wrap it manually in the SQL script in the project, but then the project does not build and there is an error pointing to IF:

SQL70001: This statement is not recognized in this context.

Now how do I force Visual Studio to generate the login creation script with the IF EXISTS check and also do not lose the synchronisation abilities?

Was it helpful?

Solution

Change the Build Action property of the script file (*.sql) to None. This solves the problem.

The build action property is accessed by right-clicking the sql file in solution explorer, then clicking properties. Alternatively, highlight the file in solution explorer and press 'F4'.

OTHER TIPS

For anyone else who is looking for a complete answer, here is what I did:

  1. In Visual Studio, right-click on your login script, or in my case the linked server script.
  2. Click Properties.
  3. Under Advanced -> Build Action, change it from Build to None.
  4. In your PreDeployment script, add a line to run this script. For me, I moved my linked server script to be in the same folder as PreDeployment script. Then I can just do

    :r .\linkedserver.sql

  5. When you deploy your decpac, your login script or linked server script will be executed successfully.

Not sure if I understand the question correctly, but I came here because of a similar scenario. After wasting a few hours with "if" and "try catch" here is my answer:

Looking at DacPac exclude users and logins on export or import I found there should be an option to exclude logins. I found that you can change the publish settings for a database project, but these settings are stored in the *.user file, which I normally don't put into source control. Looking further, I found command line options for sqlpackage.exe https://blogs.msdn.microsoft.com/ssdt/2015/02/23/new-advanced-publish-options-to-specify-object-types-to-exclude-or-not-drop/. This seems to work quite nicely, also given that you can get sqlpackage.exe from NuGet (see https://blogs.msdn.microsoft.com/ssdt/2016/08/22/releasing-ssdt-with-visual-studio-15-preview-4-and-introducing-ssdt-msbuild-nuget-package/). So there is nothing in the way to build on a CI machine and deploy the result to a server.

Edit: This is on VS2015 with respective SSDT.

I have exactly the same problem and the solution from me was to have a pre-deployment script deleting users:

IF EXISTS(SELECT TOP 1 1 FROM master.sys.server_principals WHERE name = 'my_user') BEGIN
   DROP LOGIN [my_user]
END

The problem is that maybe you have changed the password, permissions, or settings of the LOGIN [my_user] since it was created, and after droping and creating it, you will lost that customized settings.

IF NOT EXISTS
(
SELECT [Column Name Where Username Is Stored] 
FROM [Table Name That Holds The Login's] 
WHERE name = 'my_user'
)
BEGIN 
CREATE LOGIN [my_user] WITH PASSWORD = 'somesecurepass'

ELSE....

And then you can write an else statement to handle it however you want whether that be updating the password to the new one or simply returning a message saying that the user already exists. Let me know if you need help writing that part.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top