55

I'm working with SQL Server 2012. I want to check if a user exists before adding it to a database.

This is what I have tested:

USE [MyDatabase]
GO

IF NOT EXISTS (SELECT name 
                FROM [sys].[server_principals]
                WHERE name = N'IIS APPPOOL\MyWebApi AppPool')
Begin
    CREATE USER [IIS APPPOOL\MyWebApi AppPool] 
    FOR LOGIN [IIS APPPOOL\MyWebApi AppPool] WITH DEFAULT_SCHEMA=[dbo]
end
ALTER ROLE [db_owner] ADD MEMBER [IIS APPPOOL\MyWebApi AppPool]
GO

But, this code SELECT name FROM [sys].[server_principals] doesn't return if that user exists in MyDatabase.

How can I check if an user exists in MyDatabase?

Paul White
  • 94,921
  • 30
  • 437
  • 687
VansFannel
  • 1,873
  • 5
  • 23
  • 36

4 Answers4

45

Use sys.database_principals instead of sys.server_principals.

So the final query would look like this (accounting for the user filter):

USE [MyDatabase]
GO

IF NOT EXISTS (SELECT [name]
                FROM [sys].[database_principals]
                WHERE [type] = N'S' AND [name] = N'IIS APPPOOL\MyWebApi AppPool')
Begin
    CREATE USER [IIS APPPOOL\MyWebApi AppPool] 
    FOR LOGIN [IIS APPPOOL\MyWebApi AppPool] WITH DEFAULT_SCHEMA=[dbo]
end
ALTER ROLE [db_owner] ADD MEMBER [IIS APPPOOL\MyWebApi AppPool]
GO
CodeZombie
  • 103
  • 4
Chris Aldrich
  • 4,916
  • 5
  • 34
  • 55
28

I use SUSER_ID() and USER_ID() for this kind of things:

-- Check SQL Server Login
IF SUSER_ID('SomeLogin') IS NULL
    CREATE LOGIN SomeLogin WITH PASSWORD = 'SomePassword';

-- Check database user
IF USER_ID('SomeUser') IS NULL
    CREATE USER SomeUser FOR LOGIN SomeLogin;
spaghettidba
  • 11,376
  • 31
  • 42
19

Further refinement as this would make a more optimal read-

USE [MyDatabase]
GO

IF DATABASE_PRINCIPAL_ID('IIS APPPOOL\MyWebApi AppPool') IS NULL
BEGIN
    CREATE USER [IIS APPPOOL\MyWebApi AppPool] 
    FOR LOGIN [IIS APPPOOL\MyWebApi AppPool] WITH DEFAULT_SCHEMA=[dbo]
END
ALTER ROLE [db_owner] ADD MEMBER [IIS APPPOOL\MyWebApi AppPool]
GO
Moiz Tankiwala
  • 293
  • 2
  • 6
2

If you're using resistered servers you can check many servers at once and return a true/false with:

SELECT @@servername,    
    CASE 
        WHEN EXISTS(SELECT name FROM sys.database_principals WHERE name = 'LoginName') THEN 1 
        ELSE 0 
    END AS YesNo
Sir Swears-a-lot
  • 3,253
  • 3
  • 30
  • 48