检查是否已经存在SQL Server登录名


176

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

我发现以下代码实际上将登录名添加到数据库中,但是我想将其包装在IF语句中(以某种方式)以检查登录名是否首先存在。

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

我了解我需要查询系统数据库,但不确定从哪里开始!


10
这是一个重要的问题,但是用措辞来说,它似乎缺少一个重要的区别:用户与登录。乔恩(Jon)链接到的潜在重复对象实际上似乎与用户有关。该问题的标题为“用户”,但在问题代码和接受的答案中处理登录信息。我相应地编辑了标题和问题。
LarsH 2013年

1
只是为了通过@LarsH添加评论,登录名与SQL Server实例关联,而用户与特定数据库关联。可以通过服务器登录名创建数据库用户,因此他们可以访问特定的数据库。看到这篇出色的文章,实际上是整个系列的一部分(SQL Server安全性的Stariway)
反向工程师

Answers:


141

这里

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

6
您应该使用QUOTENAME防止SQL注入。攻击者可以传递@loginName,例如x] with password ''y'';\r\ndrop table foo;\r\n
Remus

2
为什么必须创建一个字符串声明然后使用sp_executesql而不是直接输入CREATE LOGIN [@loginName] FROM ...?原谅我的无知,我想学习...
LarsH 2013年

4
@LarsH:因为CREATE LOGIN不能使用参数作为登录名,所以需要将其创建为字符串,这需要字符串文字。不知道为什么会这样,但是我发现很难做到这一点。
Joseph Bongaarts 2014年

@JosephBongaarts:好的,谢谢。我想这就像SELECT语句中的表名。也许是为了减少容易受到攻击的表面区域,尽管我不知道这会有所帮助。
LarsH 2014年

1
我认为QUOTENAME()是四处走动@loginName,而不是整个陈述,然后您就可以摆脱周围的手册[和]分隔符@loginName
brianary 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.