【问题标题】:Join 2 strings as query in a procedure在过程中加入 2 个字符串作为查询
【发布时间】:2011-10-14 16:16:09
【问题描述】:

如何根据收到的参数构建查询?我想添加到查询的末尾。

我尝试了类似的方法,但没有成功:

DELIMITER $$
CREATE PROCEDURE `get_users`(IN sortstring TEXT)
BEGIN
PREPARE statement FROM
 "SELECT username, password FROM users ?";
SET @param = sortstring;
EXECUTE statement USING @param;
END$$

我会传递给 sortstring 类似的东西:

ORDER BY username DESC

我可以通过使用 concat 或其他东西来更简单吗?

【问题讨论】:

  • 得跑了,但是看这里:forums.mysql.com/read.php?60,41372,47813
  • @Dems 谢谢。你能发个帖子让我把它标记为正确答案。
  • 在使用这样的代码时,请确保您知道什么是“SQL 注入”。

标签: mysql sql stored-procedures


【解决方案1】:

您需要解构排序字符串并根据允许的术语白名单检查其所有部分。

请参阅以下伪代码。我还没有完全测试它,但可以说这是最重要的想法。

DELIMITER $$

CREATE PROCEDURE `get_users`(IN sortstring TEXT)
BEGIN
  //check sortstring against a whitelist of allowed sortstrings
  DECLARE sortpart VARCHAR(255);
  DECLARE done BOOLEAN DEFAULT false;
  DECLARE allok BOOLEAN DEFAULT true; 
  DECLARE i INTEGER DEFAULT 1;

  WHILE ((NOT done) AND allOK) DO
    SET sortpart = SUBSTRING_INDEX(sortstring,',',i);
    SET i = i + 1;
    SET done = (sortpart IS NULL);
    IF NOT DONE THEN
      SELECT 1 INTO allok WHERE EXISTS 
        (SELECT 1 FROM whitelist 
         WHERE allowed_sort_claused = sortpart AND tablename = 'users');
    END IF
  END WHILE;
  IF allOK THEN     
    PREPARE statement FROM 
      CONCAT('SELECT username, passhashwithsalt FROM users ',sortstring);
    EXECUTE statement;
    DEALLOCATE PREPARE statement;
  ELSE SELECT 'error' as username, 'error' as passhashwithsalt;
  END IF; 

END$$

见:How to prevent SQL injection with dynamic tablenames?

代码中的错误
您不能使用列名或 SQL 关键字作为参数。您只能将值用作参数。因此,您的查询将永远不会通过准备。
SELECT x FROM t1 ? 中的 ? 将被 SELECT x FROM t1 'ORDER BY field1, field2' 替换,这没有任何意义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-25
    • 1970-01-01
    • 2015-08-05
    相关资源
    最近更新 更多