2009-09-04 5 views
137

Мне нужно проверить, существует ли на SQL Server определенный логин, а если нет, то мне нужно добавить его.Проверка наличия существующей регистрации SQL Server

Я нашел следующий код, чтобы фактически добавить логин в базу данных, но я хочу обернуть это в инструкции IF (каким-то образом), чтобы проверить, существует ли вход в систему первым.

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

Я понимаю, что мне нужно допросить системную базу данных, но не знаю, с чего начать!

+0

какая версия SQL Server? – pjp

+10

Это важный вопрос, но, как говорится, он пропустил важное различие: пользователь и логин. Потенциальный дубликат, с которым Джон связан, по-видимому, связан с пользователями. Этот вопрос говорит «пользователь» в заголовке, но касается входа в код вопроса и в принятом ответе. Я отредактировал название и вопрос соответственно. – LarsH

+1

Просто добавьте комментарий @LarsH, ** логины ** связаны с экземпляром SQL-сервера, а ** пользователи ** связаны с конкретной базой данных. Пользователи базы данных могут быть созданы из логинов сервера, поэтому они имеют доступ к конкретной базе данных. См. [Эту замечательную статью] (http://www.sqlservercentral.com/articles/Stairway+Series/109975/), и на самом деле весь ряд является частью (Stariway to SQL Server Security) – DaveBoltman

ответ

116

От 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. Лучший ответ, чем мой. Хороший ответ. – David

+6

вы должны использовать QUOTENAME для предотвращения внедрения sql. Атакующий может передать имя @loginName как 'x] с паролем '' y ''; \ r \ ndrop table foo; \ r \ n' –

+0

Хороший материал, спасибо, ребята! –

5

Это работает на SQL Server 2000.

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

на SQL 2005, измените 2-й линии в

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

Я не уверен, что SQL 2008, но я предполагаю, что он будет таким же, как SQL 2005, а если нет, это должно дать вам представление о wh пока я не начну смотреть.

8

Попробуйте это (замените «пользователя» с действительным именем пользователя):

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

BEGIN 
    --create login here 
END 
+0

@Marc: Извините, но вы ошибаетесь. Таблица [syslogins] сохраняет логины, а таблица [sysusers] сохраняет пользователей. – abatishchev

27

В качестве небольшого дополнения к этой теме, в общем, вы хотите, чтобы избежать использования взглядов, которые начинаются с sys.sys *, как Microsoft только включает их для обратной совместимости. Для вашего кода вы, вероятно, должны использовать sys.server_principals. Предполагается, что вы используете SQL 2005 или выше.

+0

Протестировано, работает и более актуально, чем другие ответы. +1 к вам. – David

+0

приятно знать, спасибо! – Marc

+0

Да, с 2005 Microsoft отняла прямой доступ к системным таблицам. Чтобы не нарушать старый код, они включают представления, которые имеют то же имя, что и старые таблицы.Однако они предназначены только для более старого кода, а новый код должен использовать новые представления. В BOL выполните поиск в таблицах систем отображения, чтобы узнать, что вы должны использовать. – Bomlin

246

Вот способ сделать это в SQL Server 2005, а затем, не используя устаревшие syslogins просмотра:

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

server_principals вид используется вместо sql_logins, поскольку последний не список логинов Windows.

Если вам необходимо проверить наличие пользователя в конкретной базе данных, прежде чем создавать их, то вы можете сделать это:

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

Ницца, спасибо! –

+15

Лучший ответ, не задействованный динамический sql, ни использование устаревшего представления. Благодаря! –

+4

В случае SQL Azure двумя целевыми таблицами являются sys.sql_logins и sys.sysusers - возможно, было бы неплохо включить это в ответ. – Brett

4

что вы точно хотите проверить, для входа в систему или пользователя? логин создается на уровне сервера, и пользователь создается на уровне базы данных, поэтому логин уникален на сервере

также пользователь создан против входа в систему, пользователь без входа в систему - это осиротевший пользователь и не полезен как u косяк выполнять логин SQL сервера без авторизации

может быть, и нужно это проверить

для входа

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

выше обратного запроса «X», если существует еще Войти обратный нуль

затем создать логин

CREATE LOGIN <username> with PASSWORD=<password> 

это создает логин в SQL Server.но он принимает только сильные пароли

создать пользователь в каждой базе данных, которую вы хотите для Войти как

CREATE USER <username> for login <username> 

правопреемника выполнять права пользователя

GRANT EXECUTE TO <username> 

Вы должны иметь права сисадмина или сказать «са 'для краткости

Вы можете написать процедуру sql для этого в базе данных

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

Сначала вы должны проверить логин существование с помощью syslogins просмотра:

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

Затем вы должны проверить наличие базы данных:

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

Я не знаю, что «вам нужно проверить существование входа в систему с помощью представления syslogins», тогда публикация кода, который не использует это представление, выглядит как проблема с копированием и вставкой. Кроме того, после первого утверждения строка «Тогда вам нужно проверить существование вашей базы данных», используя параллельную форму, похоже, что вы просите кого-то проверить наличие базы данных, а не пользователя уровня БД. И вам нужно указать, что вторая партия должна быть запущена внутри целевой БД. В целом, это просто очень плохое объяснение. И так как вы добавили его через пять лет после того, как самый высокий ответ на ответ сказал то же самое, но лучше ... –

1

Вы можете использовать встроенную функцию:

SUSER_ID ([ 'myUsername' ]) 

via

IF [value] IS NULL [statement] 

как:

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

Смежные вопросы