2009-04-22 11 views
16

Vorrei creare un utente "pippo" nel database "mydb" se l'utente non esiste già. Attualmente il mio script è simile al seguente:creare in modo condizionale l'utente in SQL Server

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

Tuttavia, se l'utente esiste già, questo non riesce con un messaggio di errore:

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

Come posso cambiare lo script in modo che l'utente viene creato solo se non esiste già?

Grazie!

+0

possibile duplicato del [Verificando un account di accesso di SQL Server esiste già] (http: // StackOverflow.it/questions/1379437/check-if-a-sql-server-login-already-exists) – bummi

risposta

13

Questo è ciò che facciamo ...

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

per il nuovo sviluppo su SQL Server 2005 Io userei sys.database_principals invece di sysusers e stick con CREATE USER invece di sp_grantdbaccess. – Matt

+1

@Matt potresti aggiungere una risposta che mostri questa soluzione? –

+0

Un po 'vecchio, ma dovrebbe essere "sys.server_principals" e non "sys.database_principals" per questo caso. – codenamezero

25

È possibile consultare i due cataloghi sys.server_principals di sistema per verificare la presenza di accessi server o sys.database_principals nel database specifico per gli utenti del database:

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

Mi aspetto che il nome del DB (mydb) appaia da qualche parte, mi manca qualcosa? –

+1

devi essere sul tuo db, ovviamente, ad es. "usa mydb" prima del controllo –

13

sostanza che unisce David's answer e marc_s's answer, come richiesto da un commento di Chris.

documentazione in linea dice di sp_grantdbaccess:

Questa funzionalità verrà rimossa in una versione futura di Microsoft SQL Server . Evitare di utilizzare questa funzione nel nuovo lavoro di sviluppo e pianificare modificare le applicazioni che attualmente utilizzano questa funzionalità. Utilizzare invece CREATE USER.

Quindi solo a creare un utente se l'utente non esiste già, mi piacerebbe fare qualcosa di simile:

/* 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 

Nonostante sia deprecato, sp_grantdbaccess ha il vantaggio di essere in grado di utilizzare un parametro o una variabile locale per il nome utente/login, come nella risposta di David. La prima alternativa che potevo pensare per ottenere qualcosa di simile a lavorare con CREATE USER era usare SQL dinamico. Per esempio:

/* 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 

Abbastanza interessante, documentazione in linea dice anche che in realtà chiama sp_grantdbaccessCREATE USER, e ho notato nel mio test che, se non si assegna in modo esplicito uno schema, sp_grantdbaccess creerà uno chiamato dopo che l'utente, mentre CREATE USER utilizzerà 'dbo' per impostazione predefinita.

0

ho chiesto esattamente la stessa domanda per quanto riguarda l'utente SQL già esistente quando lo script viene eseguito - la questione, e alcune risposte molto utili sono qui:

Checking if a SQL Server login already exists

Spero che questo aiuti.

-2
USE MyDB 
GO 

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

Fintanto che l'unico errore potenziale è che l'utente può già effettuare il login. – Karlth

+1

Downvoted perché se viene generato un altro errore, come "Password Policy" o "Login non valido", questi errori verranno inghiottiti da 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