7

我是一名开发人员,我很擅长 SQL :) 请在这里帮助我。

我想创建自己的存储过程,在我的 SaaS 数据库中创建租户。为此,我需要为租户创建一个新的 SQL 登录名,然后将其添加到预定义的 SQL 角色中。

我已经为尝试创建登录名感到难过。这是我尝试过的...

CREATE PROCEDURE [MyScheme].[Tenants_InsertTenant]
    @username nvarchar(2048),
    @password nvarchar(2048)

AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    CREATE LOGIN @username WITH PASSWORD = @password
END

消息 102,级别 15,状态 1,过程 Tenants_InsertTenant,第 16 行“@username”附近的语法不正确。

消息 319,级别 15,状态 1,过程 Tenants_InsertTenant,第 16 行关键字“with”附近的语法不正确。如果此语句是公用表表达式、xmlnamespaces 子句或更改跟踪上下文子句,则前面的语句必须以分号结束。

我意识到这应该很简单,但是当您的 SQL 新手和 SQL 管理器错误对我来说似乎很神秘时,最好寻求帮助:)

谢谢,贾斯汀

4

4 回答 4

11

显然 CREATE LOGIN 只接受文字。您可以尝试将其包装在 exec 中并将其构建为字符串:

EXEC('CREATE LOGIN' + quotename(@username) + ' WITH PASSWORD = ' + quotename(@password, ''''))

编辑:添加引号名称以防止 sql 注入攻击

于 2009-05-07T22:25:04.510 回答
6

可能的解决方案:

sp_addlogin @loginame = '测试',@passwd = '测试',@defdb = '测试'

于 2009-05-08T07:51:37.410 回答
1

试试这个:

declare @t nvarchar(4000)
set @t = N'CREATE LOGIN ''''' + @username + ''''' WITH PASSWORD = ''''' + @password
exec sys.sp_executesql @t
于 2009-05-07T22:28:38.870 回答
1

基于@codeulike 和@Galkin 的答案,我最终做到了:

DECLARE @t nvarchar(4000)
SET @t = N'CREATE LOGIN ' + QUOTENAME(@username) + ' WITH PASSWORD = ' + QUOTENAME(@password, '''') + ', default_database = ' + QUOTENAME(@DatabaseName)
EXEC(@t)

我正在运行 SQL Server 2019 并将 EXEC(--> 与 QUOTENAME() 内 <--) 组合在同一行上不起作用。

如果我了解使用引号名称构建字符串的microsoft sql 注入文档,那么执行可以保护您免受 SQL 注入。

于 2020-03-04T13:51:10.023 回答