Sql server 使用sp_executesql proc创建SQL登录

Sql server 使用sp_executesql proc创建SQL登录,sql-server,dynamic-sql,Sql Server,Dynamic Sql,以下代码不起作用: declare @pUserName nvarchar(50) = N'[test2]' ; declare @pPassword nvarchar(50) = N'''123456'''; declare @QueryString as nvarchar(max); declare @ParmDefinition as nvarchar(max); SET @QueryString = N'CREATE LOGIN @dUserName WITH PASSWORD= @

以下代码不起作用:

declare @pUserName nvarchar(50) = N'[test2]' ;
declare @pPassword nvarchar(50) = N'''123456''';

declare @QueryString as nvarchar(max);
declare @ParmDefinition as nvarchar(max);

SET @QueryString = N'CREATE LOGIN @dUserName WITH PASSWORD= @dpassword , DEFAULT_DATABASE=[Yerknain] ,DEFAULT_LANGUAGE=[us_english], CHECK_EXPIRATION=ON, CHECK_POLICY=ON';
SET @ParmDefinition = N'@dUserName nvarchar(50) , @dpassword nvarchar(50)';  

EXECUTE sp_executesql @QueryString, @ParmDefinition,
                             @dUserName =  @pUserName, 
                             @dpassword = @pPassword;
它抛出了一个错误:

Msg 102,15级,状态1,第1行 “@dUserName”附近的语法不正确

但当我将其更改为以下内容时:

declare @pUserName nvarchar(50) = N'test2' ;
declare @pPassword nvarchar(50) = N'123456';

declare @QueryString as nvarchar(max);
declare @ParmDefinition as nvarchar(max);

SET @QueryString = N'CREATE LOGIN [@dUserName] WITH PASSWORD= ''@dpassword'' , DEFAULT_DATABASE=[Yerknain] ,DEFAULT_LANGUAGE=[us_english], CHECK_EXPIRATION=ON, CHECK_POLICY=ON';
SET @ParmDefinition = N'@dUserName nvarchar(50) , @dpassword nvarchar(50)';  

EXECUTE sp_executesql @QueryString, @ParmDefinition, 
                            @dUserName =  @pUserName, 
                            @dpassword = @pPassword;
它正在工作,但不是用test2注册新用户,而是用name@pUserName注册它


有没有办法用sp_executesql过程来解决这个问题?不仅仅是通过exec,我还需要检查所有内容?

用字符串连接来构建@QueryString。注意,这样做时,不需要将这些作为参数发送到sp_executesql


但是通过这种方式,参数将不会被检查,无论它们是精确的长度还是类型,它只会将其放在那里,而不检查是吗?那么有SQL注入的风险吗?或者从安全方面来说还可以?@AlphasSupremum 1通过将用户名放在矩形括号中,并在密码中用两个单引号替换任何“单引号”实例,可以保护您免受SQL注入攻击。2您不能使用参数创建登录名,这就是为什么我的答案会将用户名连接到字符串中。但是,我不确定密码是否可以作为参数传递,您应该尝试一下,看看这是否有效。无论如何,我写的是安全的,而不是SQL注入攻击。@AlphasSupremum我已经修改了我的答案以使用该函数,在这种情况下,该函数可以更好地防止SQL注入。一般来说,在名字周围加上长方形的引号是不好的。QUOTENAME函数总是做得最好。
SET @QueryString = N'CREATE LOGIN '+QUOTENAME(@dUserName)+' WITH PASSWORD= '''+REPLACE(@dpassword,'''','''''')+''' , DEFAULT_DATABASE=[Yerknain] ,DEFAULT_LANGUAGE=[us_english], CHECK_EXPIRATION=ON, CHECK_POLICY=ON';