检查SQL Server登录是否已存在

Bre*_*gby 165 sql-server login

我需要检查SQL Server上是否已存在特定登录,如果不存在,则需要添加它.

我发现以下代码实际上将登录添加到数据库,但我想将其包装在IF语句中(不知何故)以检查登录是否存在.

CREATE LOGIN [myUsername] WITH PASSWORD=N'myPassword', 
DEFAULT_LANGUAGE=[us_english], 
CHECK_EXPIRATION=OFF, 
CHECK_POLICY=OFF 
GO
Run Code Online (Sandbox Code Playgroud)

我知道我需要询问系统数据库,但不知道从哪里开始!

Der*_*son 278

这是在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
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

  • 最佳答案,没有涉及动态sql,也没有任何弃用的视图用法.谢谢! (17认同)
  • 对于SQL Azure,两个目标表是sys.sql_logins和sys.sysusers - 可能很高兴将其包含在答案中. (7认同)

Joh*_*lan 135

这里开始

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
Run Code Online (Sandbox Code Playgroud)

  • 你应该使用QUOTENAME来防止sql注入.攻击者可以使用密码"y"传递像@ x一样的@loginName;\r \ndrop table foo;\r \n` (6认同)
  • 为什么需要将语句创建为字符串然后使用sp_executesql,而不是直接输入`CREATE LOGIN [@loginName] FROM ...`?请原谅我的无知,我想学习... (3认同)
  • @LarsH:需要以字符串形式创建语句,因为CREATE LOGIN不能使用参数作为登录名,它需要一个字符串文字.不知道为什么会这样,但我发现它的真实性很难. (3认同)
  • +1.比我的答案更好.好答案. (2认同)

小智 30

作为此线程的次要补充,通常您希望避免使用以sys.sys*开头的视图,因为Microsoft仅包含它们以实现向后兼容性.对于您的代码,您应该使用sys.server_principals.这假设您使用的是SQL 2005或更高版本.


Mar*_*arc 8

试试这个(用实际的登录名替换'user'):

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

BEGIN 
    --create login here
END
Run Code Online (Sandbox Code Playgroud)


Hüd*_*üda 8

您可以使用内置功能:

SUSER_ID ( [ 'myUsername' ] )
Run Code Online (Sandbox Code Playgroud)

通过

IF [value] IS NULL [statement]
Run Code Online (Sandbox Code Playgroud)

喜欢:

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
Run Code Online (Sandbox Code Playgroud)

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


Hen*_*yer 8

为了处理登录名、角色、用户等之间的命名冲突,您应该type根据Microsoft sys.database_principals 文档检查该列

为了处理用户名等中的特殊字符,请相应地使用N'<name>'[<name>]

创建登录

USE MASTER
IF NOT EXISTS (SELECT 1 FROM master.sys.server_principals WHERE 
[name] = N'<loginname>' and [type] IN ('C','E', 'G', 'K', 'S', 'U'))
    CREATE LOGIN [<loginname>] <further parameters>
Run Code Online (Sandbox Code Playgroud)

创建数据库用户

USE [<databasename>]
IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE 
[name] = N'<username>' and [type] IN ('C','E', 'G', 'K', 'S', 'U'))
    CREATE USER [<username>] FOR LOGIN [<loginname>]
Run Code Online (Sandbox Code Playgroud)

创建数据库角色

USE [<databasename>]
IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE 
[name] = N'<rolename>' and Type = 'R')
    CREATE ROLE [<rolename>]
Run Code Online (Sandbox Code Playgroud)

将用户添加到角色

USE [<databasename>]
EXEC sp_addrolemember N'<rolename>', N'<username>'
Run Code Online (Sandbox Code Playgroud)

授予角色权限

USE [<databasename>]
GRANT SELECT ON [<tablename>] TO [<rolename>]
GRANT UPDATE ON [<tablename>] ([<columnname>]) TO [<rolename>]
GRANT EXECUTE ON [<procedurename>] TO [<rolename>]
Run Code Online (Sandbox Code Playgroud)

SQL 在 SQL Server 2005、2008、2008 R2、2014、2016、2017、2019 上测试过


Vin*_*ius 7

这是针对 Azure SQL 的:

IF (EXISTS(SELECT TOP 1 1 FROM sys.sql_logins WHERE [name] = '<login>'))
    DROP LOGIN [<login>];
Run Code Online (Sandbox Code Playgroud)

来源:如何检查 Azure SQL 数据库中是否已存在数据库用户


Dav*_*vid 6

这适用于SQL Server 2000.

use master
select count(*) From sysxlogins WHERE NAME = 'myUsername'
Run Code Online (Sandbox Code Playgroud)

在SQL 2005上,将第二行更改为

select count(*) From syslogins WHERE NAME = 'myUsername'
Run Code Online (Sandbox Code Playgroud)

我不确定SQL 2008,但我猜它会和SQL 2005一样,如果没有,这应该会让你知道从哪里开始寻找.


Aks*_*ita 5

您到底要检查登录名或用户什么?在服务器级别创建登录名,并在数据库级别创建用户,因此登录名在服务器中是唯一的

还针对登录创建了一个用户,未登录的用户是一个孤立用户,并且由于您无法在未登录的情况下无法执行sql server登录而没有用

也许你需要这个

检查登录

select 'X' from master.dbo.syslogins where loginname=<username>
Run Code Online (Sandbox Code Playgroud)

如果存在登录名,则以上查询返回“ X”,否则返回null

然后创建一个登录名

CREATE LOGIN <username> with PASSWORD=<password>
Run Code Online (Sandbox Code Playgroud)

这会在sql server中创建一个登录名。但是它仅接受强密码

在要登录的每个数据库中创建一个用户

CREATE USER <username> for login <username>
Run Code Online (Sandbox Code Playgroud)

向用户分配执行权限

 GRANT EXECUTE TO <username>
Run Code Online (Sandbox Code Playgroud)

您必须具有SYSADMIN权限,或简称为“ sa”

您可以在数据库上为此编写一个sql过程

create proc createuser
(
@username varchar(50),
@password varchar(50)
)
as
begin
if not exists(select 'X' from master.dbo.syslogins where loginname=@username)
begin
 if not exists(select 'X' from sysusers where name=@username)
 begin
exec('CREATE LOGIN '+@username+' WITH PASSWORD='''+@password+'''')
exec('CREATE USER '+@username+' FOR LOGIN '+@username)
exec('GRANT EXECUTE TO '+@username)
end
end
end
Run Code Online (Sandbox Code Playgroud)