2009-09-04 17 views
137

Muszę sprawdzić, czy określone logowanie już istnieje na serwerze SQL, a jeśli nie, to muszę go dodać.Sprawdzanie, czy login SQL Server już istnieje

Znalazłem następujący kod, aby rzeczywiście dodać login do bazy danych, ale chcę zawinąć to w instrukcji IF (jakoś), aby sprawdzić, czy login istnieje wcześniej.

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

Rozumiem, że muszę przesłuchać bazę danych systemu, ale nie wiem od czego zacząć!

+0

która wersja programu SQL Server? – pjp

+10

Jest to ważne pytanie, ale w sformułowaniu wydaje się brakować ważnego wyróżnienia: użytkownik kontra login. Potencjalny duplikat, z którym Jon jest powiązany, wydaje się być naprawdę o użytkownikach. To pytanie mówi "użytkownik" w tytule, ale zajmuje się logowaniem w kodzie pytającym i akceptowaną odpowiedzią. Odpowiednio zredagowałem tytuł i pytanie. – LarsH

+1

Wystarczy, że dodasz komentarz do @LarsH, ** loginy ** są powiązane z instancją serwera SQL, a ** użytkownicy ** są powiązani z określoną bazą danych. Użytkownicy bazy danych mogą być tworzone na podstawie loginu serwera, dzięki czemu mają dostęp do określonej bazy danych. Zobacz [ten znakomity artykuł] (http://www.sqlservercentral.com/articles/Stairway+Series/109975/) i tak naprawdę cała seria jest częścią (Stariway to SQL Server Security) – DaveBoltman

Odpowiedz

116

Od 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. Lepsza odpowiedź niż moja. Dobra odpowiedź. – David

+6

należy użyć QUOTENAME, aby zapobiec iniekcji sql. Osoba atakująca może przekazać @loginName, takie jak 'x] z hasłem '' y ''; \ r \ ndrop table foo; \ r \ n' –

+0

Dobre rzeczy, dzięki chłopaki! –

5

To działa na SQL Server 2000.

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

na SQL 2005, 2nd zmienić linię do

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

nie jestem pewien o SQL 2008, ale domyślam się, że to będzie to samo co SQL 2005, a jeśli nie, to powinien dać ci pojęcie o wh zacznij szukać.

8

Spróbuj tego (zastąpić „user” z rzeczywistą login):

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

BEGIN 
    --create login here 
END 
+0

@Marc: Przepraszam, ale się mylisz. Tabela [syslogins] przechowuje loginy, a tabela [sysusers] zachowuje użytkowników. – abatishchev

27

W niewielkim dodatkiem do tego wątku, w ogóle chcesz unikać poglądy, które zaczynają się sys.sys * jako Microsoft dołącza je tylko w celu zapewnienia kompatybilności wstecznej. Dla twojego kodu powinieneś prawdopodobnie użyć sys.server_principals. Zakłada to, że używasz SQL 2005 lub nowszego.

+0

Testowane, działające i bardziej aktualne niż inne odpowiedzi. +1 do ciebie również. – David

+0

dobrze wiedzieć, dzięki! – Marc

+0

Tak, w 2005 r. Microsoft zabrał bezpośredni dostęp do tabel systemowych. Aby nie zepsuć starego kodu, zawierają widoki, które miały taką samą nazwę jak stare tabele.Są one jednak przeznaczone tylko dla starszego kodu, a nowszy kod powinien wykorzystywać nowe widoki. W BOL, szukaj w mapowaniu tabel systemowych, aby dowiedzieć się, co powinieneś użyć. – Bomlin

246

Oto sposób to zrobić w SQL Server 2005, a później bez używania widoku nieaktualne syslogins:

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

Widok server_principals jest używany zamiast sql_logins ponieważ ten ostatni nie wymienia logowania Windows.

Jeśli trzeba sprawdzić dla istnienia użytkownik w danej bazie danych przed ich tworzenia, a następnie można to zrobić:

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

Fajna, dzięki! –

+15

Najlepsza odpowiedź, brak dynamicznego sql, ani żadne wycofane użycie widoku. Dzięki! –

+4

W przypadku SQL Azure dwie docelowe tabele to sys.sql_logins i sys.sysusers - może być miło uwzględnić to w odpowiedzi. – Brett

4

co dokładnie chcesz sprawdzić logowania lub użytkownika? login jest tworzony na poziomie serwera, a użytkownik jest tworzony na poziomie bazy danych, więc login jest unikalny na serwerze

również użytkownik jest tworzony przy logowaniu, użytkownik bez logowania jest osieroconym użytkownikiem i nie jest użyteczny jako użytkownik cant przeprowadzenia logowania sQL server bez logowania

może u need to

czek logowania

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

wyżej powrotnej zapytania 'X', jeśli istnieje inny logowania zwróci null

następnie utworzyć logowanie

CREATE LOGIN <username> with PASSWORD=<password> 

tworzy login w serwerze SQL.ale akceptuje tylko silnych haseł

utworzyć użytkownika w każdej bazie danych, którą chcesz do logowania jako

CREATE USER <username> for login <username> 

Przypisanie wykonywania prawa do użytkownika

GRANT EXECUTE TO <username> 

trzeba mieć uprawnienia administratora systemu lub powiedzieć „SA "dla krótkiego

można napisać procedurę sql dla tego w bazie danych

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

Najpierw trzeba sprawdzić istnienie logowania przy użyciu syslogins zobaczyć:

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

Następnie trzeba sprawdzić istnienie bazy danych:

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

Nie wiem - mówię, że "musisz sprawdzić istnienie logowania za pomocą widoku syslogins", a następnie opublikowanie kodu, który nie używa tego widoku, przypomina problem z kopiowaniem i wklejaniem. Ponadto, po pierwszym stwierdzeniu, wiersz "Następnie musisz sprawdzić istnienie bazy danych", używając równoległego formularza, wygląda na to, że prosisz kogoś, aby sprawdził istnienie bazy danych, a nie użytkownika poziomu DB. I musisz określić, że druga partia musi zostać uruchomiona wewnątrz docelowej bazy danych. Ogólnie rzecz biorąc, jest to bardzo słabe wytłumaczenie. A ponieważ dodałeś go pięć lat po najwyższej przegłosowanej odpowiedzi, powiedział to samo, ale lepiej ... –

Powiązane problemy