2009-09-04 40 views
137

Tôi cần kiểm tra xem một đăng nhập cụ thể đã tồn tại trên Máy chủ SQL chưa, và nếu không, thì tôi cần thêm nó.Kiểm tra xem thông tin đăng nhập SQL Server đã tồn tại chưa

Tôi đã tìm thấy mã sau để thực sự thêm thông tin đăng nhập vào cơ sở dữ liệu, nhưng tôi muốn bọc nó trong câu lệnh IF (bằng cách nào đó) để kiểm tra xem thông tin đăng nhập có tồn tại trước không.

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

Tôi hiểu rằng tôi cần thẩm vấn cơ sở dữ liệu hệ thống, nhưng không chắc bắt đầu từ đâu!

+0

Phiên bản nào của SQL Server? – pjp

+10

Đây là một câu hỏi quan trọng, nhưng như được diễn đạt, dường như nó bỏ lỡ một sự khác biệt quan trọng: người dùng so với đăng nhập. Tiềm năng trùng lặp mà Jon liên quan đến thực sự có vẻ là về người dùng. Câu hỏi này cho biết "người dùng" trong tiêu đề, nhưng đề cập đến thông tin đăng nhập trong mã câu hỏi và trong câu trả lời được chấp nhận. Tôi đã chỉnh sửa tiêu đề và câu hỏi tương ứng. – LarsH

+1

Chỉ cần thêm vào nhận xét của @LarsH, ** thông tin đăng nhập ** được liên kết với một cá thể máy chủ SQL và ** người dùng ** được liên kết với một cơ sở dữ liệu cụ thể. Người dùng cơ sở dữ liệu có thể được tạo từ đăng nhập máy chủ, do đó họ có quyền truy cập vào một cơ sở dữ liệu cụ thể. Xem [bài viết tuyệt vời này] (http://www.sqlservercentral.com/articles/Stairway+Series/109975/) và trên thực tế toàn bộ chuỗi là một phần của (Stariway to SQL Server Security) – DaveBoltman

Trả lời

116

Từ here

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

    EXEC sp_executesql @SqlStatement 
End 
+2

+1. Câu trả lời tốt hơn tôi. Câu trả lời tốt. – David

+6

bạn nên sử dụng QUOTENAME để ngăn chặn tiêm sql. Kẻ tấn công có thể chuyển một @loginName như 'x] bằng mật khẩu '' y ''; \ r \ ndrop bảng foo; \ r \ n' –

+0

Công cụ tốt, cảm ơn các bạn! –

5

này hoạt động trên SQL Server 2000.

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

trên SQL 2005, thay đổi dòng thứ 2 để

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

Tôi không chắc về SQL 2008, nhưng tôi đoán rằng nó sẽ giống như SQL 2005 và nếu không, điều này sẽ cung cấp cho bạn một ý tưởng của wh Không bắt đầu tìm kiếm.

8

Hãy thử điều này (thay thế 'người dùng với tên đăng nhập thực tế):

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

BEGIN 
    --create login here 
END 
+0

@Marc: Xin lỗi nhưng bạn đã sai. Bảng [syslogins] lưu giữ thông tin đăng nhập và bảng [sysusers] giữ người dùng. – abatishchev

27

Như là một bổ sung nhỏ vào chủ đề này, nói chung bạn muốn tránh sử dụng các quan điểm mà bắt đầu với sys.sys * như Microsoft chỉ bao gồm chúng cho khả năng tương thích ngược. Đối với mã của bạn, bạn có lẽ nên sử dụng sys.server_principals. Đây là giả sử bạn đang sử dụng SQL 2005 hoặc cao hơn.

+0

Đã thử nghiệm, hoạt động và hiện tại hơn các câu trả lời khác. 1 cho bạn là tốt. – David

+0

tốt để biết, cảm ơn! – Marc

+0

Vâng, với 2005 Microsoft đã lấy đi quyền truy cập trực tiếp vào các bảng hệ thống. Để tránh phá vỡ mã cũ, chúng bao gồm các chế độ xem có cùng tên với các bảng cũ.Tuy nhiên, chúng chỉ dành cho mã cũ hơn và mã mới hơn nên sử dụng các chế độ xem mới. Trong BOL, thực hiện tìm kiếm trên Bảng Hệ thống Ánh xạ để tìm hiểu những gì bạn nên sử dụng. – Bomlin

246

Dưới đây là một cách để làm điều này trong SQL Server 2005 và sau đó mà không sử dụng syslogins phản đối xem:

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

Quan điểm server_principals được sử dụng thay vì sql_logins vì sau này không liệt kê thông tin đăng nhập Windows.

Nếu bạn cần phải kiểm tra sự tồn tại của một người dùng trong một cơ sở dữ liệu cụ thể trước khi tạo ra chúng, sau đó bạn có thể làm điều này:

USE your_db_name 

IF NOT EXISTS 
    (SELECT name 
    FROM sys.database_principals 
    WHERE name = 'Bob') 
BEGIN 
    CREATE USER [Bob] FOR LOGIN [Bob] 
END 
+0

Đẹp nhất, cảm ơn! –

+15

Câu trả lời hay nhất, không liên quan đến sql động, cũng không sử dụng chế độ xem không dùng nữa. Cảm ơn! –

+4

Trong trường hợp của SQL Azure, hai bảng mục tiêu là sys.sql_logins và sys.sysusers - có thể là tốt đẹp để bao gồm điều này trong câu trả lời. – Brett

4

gì được bạn biết chính xác muốn kiểm tra xem có đăng nhập hay sử dụng? thông tin đăng nhập được tạo ở cấp độ máy chủ và người dùng được tạo ở cấp cơ sở dữ liệu để đăng nhập là duy nhất trong máy chủ

cũng là một người dùng được tạo dựa trên thông tin đăng nhập, người dùng không đăng nhập là người dùng mồ côi và không hữu ích không thể thực hiện đăng nhập máy chủ sql mà không cần đăng nhập

lẽ u cần cái này kiểm tra

để đăng nhập

select 'X' from master.dbo.syslogins where loginname=<username> 

truy vấn trở lại 'X' trên nếu đăng nhập tồn tại khác lại vô

sau đó tạo ra một đăng nhập

CREATE LOGIN <username> with PASSWORD=<password> 

điều này tạo ra một đăng nhập trong máy chủ sql.nhưng nó chỉ chấp nhận mật khẩu mạnh

tạo một người dùng trong mỗi cơ sở dữ liệu bạn muốn để đăng nhập như

CREATE USER <username> for login <username> 

assign thực hiện quyền sử dụng

GRANT EXECUTE TO <username> 

Bạn phải có quyền quản trị hệ thống hay nói 'sa 'cho ngắn

bạn có thể viết thủ tục sql cho điều đó trên cơ sở dữ liệu

create proc createuser 
(
@username varchar(50), 
@password varchar(50) 
) 
as 
begin 
if not exists(select 'X' from master.dbo.syslogins where [email protected]) 
begin 
if not exists(select 'X' from sysusers where [email protected]) 
begin 
exec('CREATE LOGIN '[email protected]+' WITH PASSWORD='''[email protected]+'''') 
exec('CREATE USER '[email protected]+' FOR LOGIN '[email protected]) 
exec('GRANT EXECUTE TO '[email protected]) 
end 
end 
end 
0

Trước tiên, bạn phải kiểm tra sự tồn tại đăng nhập bằng syslogins xem:

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

Sau đó, bạn phải kiểm tra của bạn tồn tại cơ sở dữ liệu:

USE your_dbname 

IF NOT EXISTS 
    (SELECT name 
    FROM sys.database_principals 
    WHERE name = 'your_dbname') 
BEGIN 
    CREATE USER [your_dbname] FOR LOGIN [YourLoginName] 
END 
+0

Tôi không biết - nói rằng "bạn phải kiểm tra sự tồn tại của đăng nhập bằng cách sử dụng chế độ xem syslogins", sau đó đăng mã không sử dụng chế độ xem đó giống như vấn đề sao chép và dán. Ngoài ra, sau câu lệnh đầu tiên, dòng "Sau đó, bạn phải kiểm tra sự tồn tại của cơ sở dữ liệu", sử dụng biểu mẫu song song, có vẻ như bạn đang yêu cầu ai đó kiểm tra sự tồn tại của cơ sở dữ liệu chứ không phải người dùng cấp DB. Và bạn cần xác định rằng lô thứ hai cần phải được chạy bên trong DB mục tiêu. Nhìn chung, đây chỉ là một lời giải thích rất nghèo nàn. Và kể từ khi bạn thêm nó năm năm sau khi câu trả lời upvoted cao nhất cho biết như vậy, nhưng tốt hơn ... –

1

Bạn có thể sử dụng được xây dựng trong chức năng:

SUSER_ID ([ 'myUsername' ]) 

via

IF [value] IS NULL [statement] 

như:

IF SUSER_ID (N'myUsername') IS NULL 
CREATE LOGIN [myUsername] WITH PASSWORD=N'myPassword', 
DEFAULT_LANGUAGE=[us_english], 
CHECK_EXPIRATION=OFF, 
CHECK_POLICY=OFF 
GO 

https://technet.microsoft.com/en-us/library/ms176042(v=sql.110).aspx

Các vấn đề liên quan