2009-04-22 7 views
16

Je souhaite créer un utilisateur 'foo' dans la base de données 'mydb' si l'utilisateur n'existe pas déjà. À l'heure actuelle mon script ressemble à ceci:créer un utilisateur sous SQL Server sous conditions

USE [mydb] 
CREATE USER [foo] FOR LOGIN [foo] 
GO 

Toutefois, si l'utilisateur existe déjà, cela ne fonctionne pas avec un message d'erreur:

Msg 15023, Level 16, State 1, Line 2 
User, group, or role 'jsrvpp' already exists in the current database. 

Comment puis-je changer le script afin que l'utilisateur est créé uniquement si elles n'existe pas déjà?

Merci!

+0

double possible de [Vérification si une connexion SQL Server existe déjà] (http: // stackoverflow.com/questions/1379437/vérification-if-a-sql-server-login-already-exists) – bummi

Répondre

13

C'est ce que nous faisons ...

IF NOT EXISTS (SELECT * FROM DBO.SYSUSERS WHERE NAME = @usrName) 
BEGIN 
    PRINT 'Granting access to the current database to login ' + @usrName + '...' 
    -- Grant access to our database 
    EXEC SP_GRANTDBACCESS @usrName 
END ELSE BEGIN 
    PRINT 'Login ' + @usrName + ' already granted access to current database.' 
END 
+1

pour un nouveau développement sur SQL Server 2005 J'utiliserais sys.database_principals au lieu de sysusers et m'en tenir à CREATE USER au lieu de sp_grantdbaccess. – Matt

+1

@Matt pourriez-vous ajouter une réponse qui montre cette solution? –

+0

Un peu vieux, mais il devrait être 'sys.server_principals' et non' sys.database_principals' pour ce cas. – codenamezero

25

Vous pouvez consulter les deux catalogues système sys.server_principals pour vérifier les connexions de serveur, ou sys.database_principals dans votre base de données spécifique pour les utilisateurs de votre base de données:

use myDB 
GO 

if not exists(select * from sys.database_principals where name = 'foo') 
    -- create your database user 


if not exists(select * from sys.server_principals where name = 'foo') 
    -- you need to create a server login first 

Marc

+0

Je m'attendrais à ce que le nom de la base de données (mydb) apparaisse quelque part, ai-je oublié quelque chose? –

+1

vous devez être sur votre db, bien sûr, par exemple. "use mydb" avant la vérification –

13

Essentiellement combinant David's answer et marc_s's answer, tel que demandé par un commentaire de Chris.

Livres en ligne dit de sp_grantdbaccess:

Cette fonctionnalité sera supprimée dans une future version de Microsoft SQL Server. Évitez d'utiliser cette fonctionnalité dans le nouveau travail de développement , et prévoyez de modifier les applications qui utilisent actuellement cette fonctionnalité. Utilisez CREATE USER à la place.

Donc, pour créer seul un utilisateur si l'utilisateur n'existe pas déjà, je ferais quelque chose comme ceci:

/* Make sure User is created in the appropriate database. */ 
USE mydb 
GO 

/* Users are typically mapped to logins, as OP's question implies, 
so make sure an appropriate login exists. */ 
IF NOT EXISTS(SELECT principal_id FROM sys.server_principals WHERE name = 'foo') BEGIN 
    /* Syntax for SQL server login. See BOL for domain logins, etc. */ 
    CREATE LOGIN foo 
    WITH PASSWORD = 'sufficiently complex password' 
END 

/* Create the user for the specified login. */ 
IF NOT EXISTS(SELECT principal_id FROM sys.database_principals WHERE name = 'foo') BEGIN 
    CREATE USER foo FOR LOGIN foo 
END 

En dépit d'être dépréciée, sp_grantdbaccess a l'avantage de pouvoir utiliser un paramètre ou une variable locale pour l'utilisateur/nom de connexion, comme dans la réponse de David. La première alternative que je pouvais penser pour obtenir quelque chose de similaire à travailler avec CREATE USER était d'utiliser le SQL dynamique. Par exemple:

assez intéressant
/* Make sure User is created in the appropriate database. */ 
USE mydb 
GO 

DECLARE @NewUserName sysname; 
DECLARE @NewUsersLogin sysname; 

SET @NewUserName = 'foo'; 
SET @NewUsersLogin = 'bar'; 

/* Users are typically mapped to logins, as OP's question implies, 
so make sure an appropriate login exists. */ 
IF NOT EXISTS(SELECT principal_id FROM sys.server_principals WHERE name = @NewUsersLogin) BEGIN 
    /* Syntax for SQL server login. See BOL for domain logins, etc. */ 
    DECLARE @LoginSQL as varchar(500); 
    SET @LoginSQL = 'CREATE LOGIN '+ @NewUsersLogin + 
     ' WITH PASSWORD = ''sufficiently complex password'''; 
    EXEC (@LoginSQL); 
END 

/* Create the user for the specified login. */ 
IF NOT EXISTS(SELECT principal_id FROM sys.database_principals WHERE name = @NewUserName) BEGIN 
    DECLARE @UserSQL as varchar(500); 
    SET @UserSQL = 'CREATE USER ' + @NewUserName + ' FOR LOGIN ' + @NewUsersLogin; 
    EXEC (@UserSQL); 
END 

, Livres en ligne dit aussi que sp_grantdbaccess appelle en fait CREATE USER, et j'ai remarqué dans mes tests que si vous n'attribuez pas explicitement un schéma, sp_grantdbaccess va créer un nom de l'utilisateur, alors que CREATE USER utilisera 'dbo' par défaut.

0

j'ai posé exactement la même question concernant l'utilisateur SQL déjà existant lorsque le script est exécuté - la question et des réponses très utiles sont ici:

Checking if a SQL Server login already exists

Hope this helps.

-2
USE MyDB 
GO 

BEGIN TRY 
    CREATE USER [foo] FOR LOGIN [foo] 
END TRY 
BEGIN CATCH 
-- User exists - do nothing 
END CATCH 
+1

Tant que la seule erreur potentielle est que l'utilisateur peut déjà se connecter. – Karlth

+1

Downvoted, car si une autre erreur est soulevée, comme "Password Policy" ou "Invalid Login", ces erreurs seront avalées par le Try/Catch – Raffaeu

1
USE [*Database_Name*]; 
GO 

DECLARE @isUserExist int, @SQL NVARCHAR(max) 
SELECT @isUserExist = COUNT(*) from sys.sysusers where name = *User_Name* 
--Checking for User Existence 
IF(@isUserExist = 0) 
BEGIN 
    SET @SQL = 'CREATE USER ' + QUOTENAME(*User_Name*) + ' FOR LOGIN ' + QUOTENAME(*User_Name*); 
    EXECUTE(@SQL); 
END 
Questions connexes