views:

2545

answers:

5

I need to check if a specific user already exists on the SQL Server, and if it doesn't, then I need to add it.

I have found the following code to actually add the user to the database, but I want to wrap this in an IF statement (somehow) to check if the user exists first.

CREATE LOGIN [myUsername] WITH PASSWORD=N'myPassword', 
DEFAULT_LANGUAGE=[us_english], 
CHECK_EXPIRATION=OFF, 
CHECK_POLICY=OFF 
GO

I understand that I need to interrogate a system database, but not sure where to start!

+8  A: 

From here

If not Exists (select loginname from master.dbo.syslogins 
    where name = @loginName and dbname = 'PUBS')
Begin
Select @SqlStatement = QUOTENAME('CREATE LOGIN [' + @loginName + '] 
FROM WINDOWS WITH DEFAULT_DATABASE=     [PUBS], DEFAULT_LANGUAGE=[us_english]')

EXEC sp_executesql @SqlStatement
End
John Nolan
+1. Better answer than mine. Good answer.
David Stratton
+1: quicker and more complete than my solution :)
Marc
you should use QUOTENAME to prevent sql injection. Attacker can pass a @loginName like `x] with password ''y'';\r\ndrop table foo;\r\n`
Remus Rusanu
Good stuff, thanks guys!
Brett Rigby
+2  A: 

This works on SQL Server 2000.

use master
select count(*) From sysxlogins WHERE NAME = 'myUsername'

on SQL 2005, change the 2nd line to

select count(*) From syslogins WHERE NAME = 'myUsername'

I'm not sure about SQL 2008, but I'm guessing that it will be the same as SQL 2005 and if not, this should give you an idea of where t start looking.

David Stratton
+3  A: 

Try this (replace 'user' with the actual login name):

IF NOT EXISTS(
SELECT name 
FROM [master].[sys].[syslogins]
WHERE NAME = 'user')

BEGIN 
 --create login here
END
Marc
@Marc: Sorry but you're wrong. Table [syslogins] keeps logins and table [sysusers] keep users.
abatishchev
+9  A: 

As a minor addition to this thread, in general you want to avoid using the views that begin with sys.sys* as Microsoft is only including them for backwards compatibility. For your code, you should probably use sys.server_principals. This is assuming you are using SQL 2005 or greater.

Bomlin
Tested, works, and more current than the other answers. +1 to you as well.
David Stratton
good to know, thanks!
Marc
Yeah, with 2005 Microsoft took away direct access to the system tables. To keep from breaking old code, they include views that had the same name as the old tables. However, they are only meant for older code and newer code should iuse the new views. In BOL, do a search on Mapping System Tables to find out what you should use.
Bomlin
+4  A: 

Here's a way to do this in SQL Server 2005 and later without using the deprecated syslogins view:

IF NOT EXISTS 
    (SELECT name  
     FROM master.sys.server_principals
     WHERE name = 'TConnect.User')
BEGIN
    CREATE LOGIN [TConnect.User] WITH PASSWORD = N'password'
END

The server_principals view is used instead of sql_logins because the latter doesn't list Windows logins.

If you need to check for the existence of a user in a particular database before creating them, then you can do this:

USE your_db_name

IF NOT EXISTS
    (SELECT name
     FROM sys.database_principals
     WHERE name = 'Bob')
BEGIN
    CREATE USER [Bob] FOR LOGIN [Bob] 
END
Derek Morrison
Nice one, thanks!
Brett Rigby