提问人:Ramesh Sapkota 提问时间:12/11/2019 更新时间:12/11/2019 访问量:81
无法使用动态 no.用户定义的变量(防止 sql-injectiondatabase-mysql)
Unable to create the MYSQL EXECUTE command by using dynamic no. of user defined variables (prevent sql-injectiondatabase-mysql)
问:
我一直在尝试使用用户定义变量的动态数量来执行 prepare 语句,但我找不到任何解决我问题的示例。
我有一个mysql存储过程,它接受超过15个参数。根据输入参数的值,查询的条件将在过程中添加/删除。因此,用户定义的变量也应根据添加到过程的条件进行更改。那么,有没有办法使用用户定义变量的动态数量来执行过程?
这是我的示例存储过程,
DELIMITER $$
DROP PROCEDURE IF EXISTS `aaa`$$
CREATE PROCEDURE `aaa`(IN param1 VARCHAR(255),IN param2 VARCHAR(255), IN param3 VARCHAR(255)
,IN param4 VARCHAR(255),IN param5 VARCHAR(255),IN param6 VARCHAR(255),
IN param7 VARCHAR(255),IN param8 VARCHAR(255),IN param9 VARCHAR(255),
IN param10 VARCHAR(255)
)
BEGIN
SET @v1 = param1;
SET @v2 = param2;
SET @v3 = param3;
SET @v4 = param4;
SET @v5 = param5;
SET @v6 = param6;
SET @v7 = param7;
SET @v8 = param8;
SET @v9 = param9;
SET @v10 = param10;
BEGIN
SET @QUERY = CONCAT("SELECT * FROM test.customer where name= 'abcd' ");
IF param1 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field1 = ? ");
END IF;
IF param2 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field2 = ? ");
END IF;
IF param3 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field3 = ? ");
END IF;
IF param4 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field4 = ? ");
END IF;
IF param5 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field5 = ? ");
END IF;
IF param6 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field6 = ? ");
END IF;
IF param7 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field8 = ? ");
END IF;
IF param8 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field8 = ? ");
END IF;
IF param9 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field9 = ? ");
END IF;
IF param10 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field10 = ? ");
END IF;
PREPARE stmt FROM @QUERY;
EXECUTE stmt using @v1,@v2,.......; -- varies based on the condition satisfied. can we make this dynamic??
DEALLOCATE PREPARE stmt;
END;
END$$
DELIMITER ;
答:
1赞
Bill Karwin
12/11/2019
#1
这是一个解决方案:
SET @QUERY = CONCAT('SELECT * FROM test.customer where name= ''abcd'' ');
IF param1 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY,' AND field1 = ? ');
ELSE
SET @QUERY = CONCAT(@QUERY,' AND ? IS NULL');
END IF;
IF param2 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY,' AND field2 = ? ');
ELSE
SET @QUERY = CONCAT(@QUERY,' AND ? IS NULL');
END IF;
...same for the other params...
PREPARE stmt FROM @QUERY;
EXECUTE stmt using @v1, @v2, @v3, @v4, @v5, @v6, @v7, @v8, @v9, @v10;
DEALLOCATE PREPARE stmt;
此解决方案允许 EXECUTE 接受相同数量的参数。其中一些将针对列进行测试,否则将使用哪个为真进行测试,因为只有当我们已经知道它们是 NULL 时,我们才使用该谓词。IS NULL
注意:我也改成了 .我建议不要使用 for 字符串分隔符,因为含义可能会根据您的SQL_MODE而变化。"
'
"
评论
0赞
Ramesh Sapkota
12/11/2019
非常感谢。我认为可能有一种方法可以避免其他条件。无论如何,这对我有很大帮助。
评论