如何有效地转义T-SQL中的特殊字符?

时间:2015-10-19 22:32:35

标签: sql sql-server tsql escaping sql-injection

IF NOT EXISTS (select * from sys.server_principals where lower([name]) =lower('DOMAIN\t''acct'))
BEGIN
  CREATE LOGIN [DOMAIN\t'acct] FROM WINDOWS WITH DEFAULT_DATABASE=[master]
END

以上代码正常运行。我的问题是,有没有办法有效地使用占位符,以便我可以传入相同的帐户,并在我有特殊字符时在两个地方使用?

IF NOT EXISTS (select * from sys.server_principals where lower([name]) =lower('$(account)'))
BEGIN
  CREATE LOGIN [$(account)] FROM WINDOWS WITH DEFAULT_DATABASE=[master]
END

我只需用DOMAIN \ t' acct或DOMAIN \ t' acct替换$(帐号)?

替换前者仅适用于第一次更换,并说

CREATE LOGIN [DOMAIN\t''acct] FROM WINDOWS WITH DEFAULT_DATABASE=[master]
Windows NT user or group 'DOMAIN\t''acct' not found. Check the name again.

用于创建登录语句。

对于后者,我不能只用t'替换,因为它会被错误地转义。使用框执行此操作会引发此错误:

select * from sys.server_principals where lower([name]) = lower([DOMAIN\t'acct])
Invalid column name 'DOMAIN\t'acct'.

任何防止sql注入的附加指针都会有所帮助。我也在考虑DOMAIN \&tacct等帐户(输入验证为有效的Windows用户以及域格式(名称中包含\))。

2 个答案:

答案 0 :(得分:1)

为了防止sql注入,我认为最好使用参数化查询而不是使用占位符。

要使CREATE LOGIN语句与sql参数一起使用,您必须使用动态sql。函数QUOTENAME将帮助您正确地转义登录名。在这种情况下,您的SQL代码可能如下所示:

if not exists(select * from sys.server_principals where lower([name]) = lower(@loginName))
begin
    declare @sql nvarchar(max);
    set @sql =
        'CREATE LOGIN ' + quotename(@loginName) +
        ' FROM WINDOWS WITH DEFAULT_DATABASE = [master]';

    exec sp_executesql @sql;
end

其中@loginName是您应提供的参数。

答案 1 :(得分:0)

仅在select查询中使用SQL replace函数来替换'与''通过占位符