我有以下动态查询,并希望将一个运算符作为参数传递,但我得到一个错误
@ageOperator附近的不正确语法
此外,我想防止任何SQL注入。我可以像下面这样进行连接,但是它会导致SQL注入。
@sWhere = ' WHERE AGE1 ' + @ageOperator + ''' + @age + '''提前谢谢你!
DECLARE @age INT,
@ageOperator VARCHAR(10),
@sSQL NVARCHAR(MAX),
@sWhere NVARCHAR(MAX)
SET @age = 21
SET @ageOperator = ' = '
SET @sWhere = ' WHERE AGE1 @ageOperator @age '
SET @sSQL = ' SELECT * FROM WEBPM_COPY.DBO.Test1111 ' + @sWhere
EXEC sp_executesql @sSQL, N'@age INT, @ageOperator char(10)', @age, @ageOperator;发布于 2018-11-01 15:49:15
如果要执行此代码,必须将运算符连接到@sWhere变量:
set @sWhere = ' WHERE AGE1 '+ @ageOperator +' @age ';但是,10个字符就足以编写'=1 or 1=1--' (10个字符),所以它并不是真正的sql安全。
更好的实现方法是接受一组有限的操作符,并将其白名单:
DECLARE @age INT,
@ageOperator VARCHAR(10),
@sSQL NVARCHAR(MAX),
@sWhere NVARCHAR(MAX);
SET @age = 21;
SET @ageOperator = ' = ';
IF @ageOperator NOT IN('=', '<=', '>=', '<>')
RAISERROR ('Invalid @ageOperator', -1, 1);
SET @sWhere = ' WHERE AGE1 '+ @ageOperator +' @age ';
SET @sSQL = ' SELECT * FROM WEBPM_COPY.DBO.Test1111 ' + @sWhere ;
EXEC sp_executesql @sSQL, N'@age INT, @ageOperator char(10)', @age, @ageOperator;发布于 2018-11-01 15:54:36
你不能把接线员变参数化。到一个executesql参数描述
每个参数定义由一个参数名和一个数据类型组成。
只能使用值数据作为参数。在回答您的问题时,我建议您实现自己的逻辑来检查操作员:
case @ageOperator when '=' then ... else <invalid case> end发布于 2018-11-01 15:56:54
如果您打印出您的@sSQL变量是什么,结果是SELECT * FROM WEBPM_COPY.DBO.Test1111 WHERE AGE1 @ageOperator @age,因此它实际上是将变量的名称作为字符串传递,而不是它的值。这就是您的错误消息的来源。
例如,将@sWhere的分配更改为
set @sWhere = ' WHERE AGE1 ' + @ageOperator + CAST(@age AS VARCHAR(3))导致@sSQL变成SELECT * FROM WEBPM_COPY.DBO.Test1111 WHERE AGE1 = 21,这是有效的语法。
我不确定这是否仍然可以防止SQL注入--我认为它应该是因为您不能用3个字符来处理'age',但是它解决了“@ageOperator附近的不正确语法”错误。
https://stackoverflow.com/questions/53104508
复制相似问题