2009-04-22 35 views
16

Tôi muốn tạo người dùng 'foo' trong cơ sở dữ liệu 'mydb' nếu người dùng chưa tồn tại. Hiện nay kịch bản của tôi trông như thế này:có điều kiện tạo người dùng trong SQL Server

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

Tuy nhiên nếu người dùng đã tồn tại, điều này không thành công với một thông báo lỗi:

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

Làm thế nào tôi có thể thay đổi kịch bản để người dùng chỉ được tạo ra nếu họ không tồn tại?

Cảm ơn!

+0

thể trùng lặp của [Kiểm tra nếu một SQL Server đăng nhập đã tồn tại] (http: // stackoverflow.com/questions/1379437/check-if-a-sql-server-login-đã tồn tại) – bummi

Trả lời

13

Đây là những gì chúng tôi làm ...

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

cho phát triển mới trên SQL Server 2005 Tôi muốn sử dụng sys.database_principals thay vì sysusers và gắn bó với CREATE USER thay vì sp_grantdbaccess. – Matt

+1

@Matt bạn có thể thêm câu trả lời cho thấy giải pháp này không? –

+0

Một chút cũ, nhưng nó phải là 'sys.server_principals' và không phải' sys.database_principals' trong trường hợp này. – codenamezero

25

Bạn có thể tham khảo hai hệ thống catalog sys.server_principals để kiểm tra thông tin đăng nhập máy chủ, hoặc sys.database_principals trong cơ sở dữ liệu cụ thể của bạn cho người sử dụng cơ sở dữ liệu của bạn:

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

Tôi hy vọng tên của DB (mydb) xuất hiện ở đâu đó, tôi có thiếu gì đó không? –

+1

bạn phải có trên db của bạn, tất nhiên, ví dụ: "sử dụng mydb" trước khi kiểm tra –

13

Về cơ bản kết hợp David's answermarc_s's answer, theo yêu cầu của một bình luận từ Chris.

Books Online nói về sp_grantdbaccess:

Tính năng này sẽ được gỡ bỏ trong một phiên bản tương lai của Microsoft SQL Server. Tránh sử dụng tính năng này trong công việc phát triển mới và lập kế hoạch để sửa đổi các ứng dụng hiện đang sử dụng tính năng này. Thay vào đó, hãy sử dụng CREATE USER.

Vì vậy, để chỉ tạo một người dùng nếu người dùng không tồn tại, tôi muốn làm một cái gì đó như thế này:

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

Mặc dù không được dùng nữa sp_grantdbaccess không có lợi thế là có thể sử dụng một tham số hoặc biến cục bộ cho tên người dùng/tên đăng nhập, như trong câu trả lời của David. Việc thay thế đầu tiên tôi có thể nghĩ đến để có được một cái gì đó tương tự để làm việc với CREATE USER là sử dụng SQL động. Ví dụ:

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

Điều thú vị đủ, sách trực tuyến cũng nói rằng sp_grantdbaccess thực sự gọi CREATE USER, và tôi nhận thấy trong thử nghiệm của tôi rằng nếu bạn không chỉ định rõ ràng một lược đồ, sp_grantdbaccess sẽ tạo ra một trong những tên sau khi người dùng, trong khi CREATE USER sẽ sử dụng 'dbo' theo mặc định.

0

Tôi hỏi chính xác cùng một câu hỏi liên quan đến việc sử dụng SQL đã tồn tại khi kịch bản chạy - các câu hỏi, và một số câu trả lời rất hữu ích đang ở đây:

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

Miễn là lỗi tiềm năng duy nhất là người dùng đã có thể đăng nhập. – Karlth

+1

Bị bỏ qua vì nếu có bất kỳ lỗi nào khác được nêu ra, như "Chính sách mật khẩu" hoặc "Đăng nhập không hợp lệ", các lỗi này sẽ bị nuốt bởi 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 
Các vấn đề liên quan