I have created 2 SQL Server Database Projects in VS 2013 and imported schemas from 2 databases that reside on the same SQL instance. Both databases have SQL Users, let's say [MyUser1] and [MyUser2], that use a single SQL Login, let's say [MyLogin]. The issue is both projects want to create the SQL Login and this causes the error
"SQL71508 The model already has an element that has the same name MyLogin"
DB1 Project
CREATE LOGIN [MyLogin] WITH PASSWORD = N'xyz';
CREATE USER [MyUser1] FOR LOGIN [MyLogin];
DB2 Project
CREATE LOGIN [MyLogin] WITH PASSWORD = N'xyz';
CREATE USER [MyUser2] FOR LOGIN [MyLogin];
I've tried:
Removing CREATE LOGIN from one of the projects. Issue is then CREATE USER generates an error because it wants the CREATE LOGIN for the Login to exist.
To find a way to ignore the error, but all I've found is how to ignore warnings.
Using the following to check if Login already exists, however an error is generated at the "If" indicating, "SQL700001 The statement is not recognized in this context".
If Not Exists (Select name From master.sys.server_principals Where name = 'MyLogin')
Begin
CREATE LOGIN [MyLogin]
WITH PASSWORD = N'xyz';
End
Does anyone have any thoughts on how to correct or work around this issue? Thanks!
Also, my primary reason for creating the DB2 project was due to views in DB1 that are based on tables in DB2. Without the DB2 project referenced in the DB1 project, the SQL to create the views generated errors about not finding the tables in DB2. So, if anyone has any thoughts on how to workaround this issue, that would be helpful too.
Never add the same item twice in SSDT projects. Where the same item exists in more than one project, create a master project for the server.
Leave the users alone, just move the logins to a common project.
Think inheritance when designing SSDT projects. Do not forget to include the IncludeCompositeObjects switch for deployments of each individual database.
Related
I've inherited a very old app that runs on SQL Server 2005. I'm trying to move this app to Azure.
One thing the stored procedures in this app do is create new database logins and new users. I know that many of the functions and system procedures it uses no longer exist in SQL Server, or in Azure.
Is there some equivalent of procedures like sp_addlogin, sp_droplogin, sp_grantdbaccess, sp_revokedbaccess etc. which can be executed from a user database (the procedures are there and must run there)?
I see lots of articles that talk about "connect to master", but how do I do that from within a stored procedure on my custom database?
For example, the "create login" command has to be run in master, but my procedures are in a user database. How do I do that?
Any help would be appreciated. If what I'm trying to do isn't possible, I'd appreciate knowing that, too.
I'm not sure where you get the idea that CREATE LOGIN has to be run in the master database. Seems to work just fine when run from a user database:
use master
go
drop database if exists StackOverflow;
create database StackOverflow;
go
use StackOverflow;
go
if exists(select * from sys.syslogins where name=N'StackOverflow')
drop login [StackOverflow];
create login StackOverflow
with password='St4ck0verflow',
default_database = StackOverflow;
create user StackOverflow
from login StackOverflow
with default_schema = dbo;
I am working on a Database project in VS2013 that contains a C# SQL CLR stored procedure.
The assembly owner is [servername\User123]
The database owner is also [servername\User123] (Being the database owner, this user obviously already exists on the server. I managed a successful publish of the database by commenting out the code in my SQL CLR procedure and publishing, the following occurs after I un-comment-out that code.)
If I try to build the project in VS, I get the error:
Error 1 SQL71501: Assembly: [DatabaseProject] has an unresolved reference to object [servername\User123].
...caused by:
CREATE ASSEMBLY [DatabaseProject] AUTHORIZATION [servername\User123]
FROM 0x4D5A90000300000004000000FFFF0000B8000etcetcetcetc
WITH PERMISSION_SET = EXTERNAL_ACCESS
GO
So, if in VS I add a create user script in the \Security folder:
CREATE USER [servername\User123] FOR LOGIN [servername\User123] WITH DEFAULT_SCHEMA = dbo
GO
GRANT CONNECT TO [servername\User123]
Then I can build the project.
However, if I then try to Publish the database, I get the error:
Creating [servername\User123]...
(47,1): SQL72014: .Net SqlClient Data Provider: Msg 15063, Level 16, State 1, Line 1 The login already has an account under a different user name.
(47,0): SQL72045: Script execution error. The executed script:
CREATE USER [servername\User123] FOR LOGIN [servername\User123];
An error occurred while the batch was being executed.
Is there a "right" way to do this?
This issue is due to a simple misunderstanding of how SQL Server handles the "owner" of the database as a database "principal". The concept of "database owner" shows up in two different ways:
As a database-level User having the name of dbo and a principal_id of 1. Now, what server-level Login maps to this particular User (i.e. "principal") is simply a matter of the value in the SID field in sys.database_principals:
SELECT sdp.*
FROM [sys].[database_principals] sdp
WHERE sdp.[principal_id] = 1;
This field will map to the SID field in sys.server_principals:
SELECT sdp.*, '---' AS [---], ssp.*
FROM [sys].[database_principals] sdp
INNER JOIN [sys].[server_principals] ssp
ON ssp.[sid] = sdp.[sid]
WHERE sdp.[principal_id] = 1;
Pay attention to the following fields in sys.database_principals:
type
type_desc
authentication_type
authentication_type_desc
Seeing as how your database is currently owned by a Windows Login, run the query immediately above (the 2nd query--the one with both tables). Next, change the database to be owned by sa. Next, open up a NEW query tab. Finally, run the same query in this new window (so that you can easily compare the "before" and "after" results), making sure to pay close attention to the 4 fields noted above, as well as the sid field. (Please note that it is possible to create Users without Logins and those will not show up, obviously, in a query that JOINs to sys.server_principals, but this question is dealing specifically with Logins).
From all of this you should see that specifying a Login to be the "owner" of a database does not, in fact, create a User for that Login: it merely updates the definition of the dbo User. Hence, the Login that owns the database does technically exist in that database, but always with the name of dbo instead of its actual name. This is why you are getting the following error:
The login already has an account under a different user name.
As a Database Role that any User in the database can be added to in order to be given those permissions.
To fix:
Remove your CREATE USER script from the \Security folder.
Use AUTHORIZATION [dbo] instead.
In my database I have two schema - default .dbo and another called .ptx
Almost all tables in the two schema are identical. We need two schema to handle data separately for two different products. How I switch between these two schema is by changing the SQL server login user from application level. i.e., we have two SQL users ANF_DEFAULT and ANF_PTX. If the product is default the user is ANF_DEFAULT and if the product is PTX, I switch the user to ANF_PTX and create the SqlConnection accordingly.
Everything has been working good so far, the two schema were populated correctly. But suddenly after we move in to a new production environment, the PTX product data goes in to the .dbo schema instead of the .ptx schema. This is still working fine in my local environment but the issue is visible in production. The only visible change is that I use SQL Server 2008, where as the production runs SQL Server 2012, but I think this is hardly the issue. I also checked the properties of the ANF_PTX user:
USE [ANX_GLF]
GO
/****** Object: User [ANF_PTX] Script Date: 8/27/2014 5:29:04 AM ******/
CREATE USER [ANF_PTX] FOR LOGIN [ANF_PTX] WITH DEFAULT_SCHEMA=[PTX]
GO
Please help me figure out the issue here.
I figured out the reason for this issue. Apparently, in the new deployment, the _CMS user looked fine, with its default schema being pointed to .cms. However, the problem was with the login FMSI_APP_CMS in the SQL Server. In this login, the FMSI_APP_CMS user was assigned to the super admin role. When the user is a super admin, its default schema is ignored and it always points to the .dbo schema. When the superadmin role was removed from the login, the schema switch was working fine again. More information about this can be found in the following:
http://msdn.microsoft.com/en-us/library/ms176060.aspx
Here it says:
"he value of DEFAULT_SCHEMA is ignored if the user is a member of the sysadmin fixed server role. All members of the sysadmin fixed server role have a default schema of dbo."
I'm looking at the Database Project in VS2010, the idea being that I want something I can use to keep track of the database schema (in source control) and the ability to generate "new install" scripts, and change scripts.
When I create a new database project wizard and import my existing database schema, it won't "build". I get the error:
SQL03006: User: [scanner] has an
unresolved reference to Login
[scanner].
The SQL that generates this error:
CREATE USER [scanner] FOR LOGIN
[scanner];
The user "scanner" is a login defined in the database I imported. I have no idea what it's teling me, and google isn't throwing much up. Any ideas?
The Login is actually defined in the master database of the server install. The CREATE USER statement needs to point at an existing Login otherwise it errors. The Database Project is not aware of the Login at the server level. Either you can create a Server Project to handle the Logins, or you can turn off the checking of Security objects in your Database Project. See the answer by Demetri M for more details: http://social.msdn.microsoft.com/Forums/eu/vstsdb/thread/1f8226fe-b791-4344-8735-3d38307e8664
I'm using Visual Studio 2012 for a SQL Server 2008 R2 database project. The options listed by #Judah don't appear to work anymore.
They now appear to be Settings that you configure while doing a Schema Compare:
Right click database project >
Choose 'Schema Compare' >
Choose the 'Settings' gear icon >
Choose the 'Object Types' tab >
Logins are Non-Application-scoped. Database roles, Permissions, Role Memberships, and Users are all Application-scoped.
Unfortunately, the only way that I can find to preserve these is to save the schema compare. This can be a little inconvenient if you're sharing this on a team and would like project/database (or server) settings for any schema compare.
It gets the job done, though.
You can change the create user scripts to create roles.
So instead of "Create user userName for login loginName;"
use "Create Role [userName] authorization dbo;"
This is a hack, but as long as you aren't having to deal with users and roles in your project, you can happily do the following:
GRANT EXECUTE
ON OBJECT::[dbo].[sp_name] TO [userName];
Apparently, this issue is still occurring on VS2017 database projects as well.
I've managed to solve it by first creating the login and then create the user.
-- Windows Account
CREATE LOGIN [Domain\Username]
FROM WINDOWS WITH DEFAULT_LANGUAGE = [us_english];
GO
CREATE USER [Domain\Username] FOR LOGIN [Domain\Username];
GO
-- Sql Acccount
CREATE LOGIN [sql_account] WITH PASSWORD = 'Ch#ngeth1spA$swurD'
GO
CREATE USER [sql_account]
FROM LOGIN [sql_account]
WITH DEFAULT_SCHEMA = dbo
GO
-- Then set the sql file Build Action to "Build"
In the database project open the 'Security' folder (assuming that's how your database was imported). For each user profile that is causing an issue, set the build action to 'None' in the properties panel. You will also have to remove them from any other files in which they appear, including Permissions.sql and RoleMemberships.sql.
When I try to create a SQL Server Login by saying
CREATE LOGIN [ourdomain\SQLAccessGroup] FROM WINDOWS;
I get this error
The server principal 'ourdomain\SQLAccessGroup' already exists.
However, when I try this code
DROP LOGIN [ourdomain\SQLAccessGroup]
I get this error
Cannot drop the login 'ourdomain\SQLAccessGroup', because it does not exist or you do not have permission.
The user that I am executing this code as is a sysadmin. Additionally, the user ourdomain\SQLAccessGroup does not show up in this query
select * from sys.server_principals
Does anyone have any ideas?
We are still struggling to understand the HOW of this issue, but it seems that [ourdomain\SQLAccessGroup] was aliased by a consultant to a different user name (this is part of an MS CRM installation). We finally were able to use some logic and some good old SID comparisons to determine who was playing the imposter game.
Our hint came when I tried to add the login as a user to the database (since it supposedly already existed) and got this error:
The login already has an account under a different user name.
So, I started to examine each DB user and was able to figure out the culprit. I eventually tracked it down and was able to rename the user and login so that the CRM install would work. I wonder if I can bill them $165.00 an hour for my time... :-)
is this when you are restoring from a backup or something? I've found that the following works for me in situations when I'm having problems with user accounts in sql
EXEC sp_change_users_login ‘Auto_Fix’, ‘user_in_here’
This happened to me when I installed SQL Server using a Windows username and then I renamed the computer name and the Windows username from Windows. SQL server still has the old "Computername\Username" in its node of Server->Security->Logins.
The solution is to go to Server->Security->Logins and right-click -> rename the old Windows user and use the new MachineName\Username.
I faced similar issue and i believe the issue was as a result of trying to recreate a login account after deleting an existing one with same name.
Just go through the various databases on the server using SQL Studio.
Example steps:
DBName ->Security->users
at this level for each of the databases, you may see the name of the user account there. Delete all occurrence in each Database as well as its occurrence in the top level Security settings at
Security->Logins
When done, try recreating the login account again and you should be fine.
I had the same story as Shadi.
On the top I can add that it can be also done by query:
ALTER LOGIN "oldname\RMS" WITH name="currentname\RMS"