2009-04-22 21 views
16

Chciałbym utworzyć użytkownika "foo" w bazie danych "mydb", jeśli użytkownik jeszcze nie istnieje. Obecnie mój skrypt wygląda tak:warunkowo utworzyć użytkownika w SQL Server

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

Jednak jeśli użytkownik już istnieje, to nie z komunikatem o błędzie:

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

Jak mogę zmienić skrypt tak, że użytkownik jest tworzony tylko wtedy, gdy jeszcze nie istnieje?

Dzięki!

+0

możliwe duplikat [Sprawdzenie czy logowania SQL Server już istnieje] (http: // stackoverflow.com/questions/1379437/checking-if-a-sql-server-login-already-exists) – bummi

Odpowiedz

13

To co robimy ...

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

dla nowej wersji na SQL Server 2005 Używałbym sys.database_principals zamiast sysusers i trzymałbym się z CREATE USER zamiast sp_grantdbaccess. – Matt

+1

@Matt możesz dodać odpowiedź, która pokazuje to rozwiązanie? –

+0

Trochę stare, ale powinno to być 'sys.server_principals', a nie' sys.database_principals' dla tego przypadku. – codenamezero

25

można zapoznać się z dwóch katalogów systemowych sys.server_principals aby sprawdzić logowania serwera lub sys.database_principals w konkretnej bazy danych dla użytkowników bazy danych:

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

Spodziewam się, że nazwa DB (mydb) pojawi się gdzieś tam, czy brakuje mi czegoś? –

+1

musisz oczywiście znajdować się na bazie danych, np. "użyj mydb" przed sprawdzeniem –

13

Zasadniczo połączenie David's answer i marc_s's answer, zgodnie z wnioskiem z komentarzem Chrisa.

Books Online mówi sp_grantdbaccess:

Ta funkcja zostanie usunięta w przyszłej wersji programu Microsoft SQL Server . Unikaj korzystania z tej funkcji w nowych pracach rozwojowych i planuj, aby modyfikować aplikacje, które obecnie używają tej funkcji. Zamiast tego użyj CREATE USER.

Tak, aby utworzyć użytkownika tylko wtedy, gdy użytkownik nie istnieje, chciałbym zrobić coś takiego:

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

Pomimo przestarzałe, sp_grantdbaccess ma tę zaletę, że jest w stanie wykorzystać parametr lub zmienna lokalna dla nazwy użytkownika/loginu, tak jak w odpowiedzi Dawida. Pierwszą alternatywą, którą mogłem wymyślić, aby uzyskać coś podobnego do pracy z CREATE USER, było użycie dynamicznego SQL. Na przykład:

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

Co ciekawe, Books Online mówi również, że sp_grantdbaccess faktycznie nazywa CREATE USER i zauważyłem w moim testowania, że ​​jeśli nie jawnie przypisać schematu sp_grantdbaccess stworzy jeden nazwany użytkownik, podczas gdy CREATE USER domyślnie użyje "dbo".

0

Poprosiłem dokładnie to samo pytanie dotyczące użytkownika SQL już istniejącego, gdy skrypt działa - to pytanie, a niektóre bardzo przydatne odpowiedzi są tutaj:

Checking if a SQL Server login already exists

Nadzieja to pomaga.

-2
USE MyDB 
GO 

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

Dopóki jedynym potencjalnym błędem jest to, że użytkownik może już się zalogować. – Karlth

+1

Niweczono, ponieważ jeśli pojawi się jakikolwiek inny błąd, taki jak "Zasady haseł" lub "Nieprawidłowe logowanie", błędy te zostaną połknięte przez próbę/chwyt – 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 
Powiązane problemy