mySQL按占位符排序

时间:2014-06-24 22:34:28

标签: php mysql sql

我试图调用一个存储过程来返回一组按特定顺序排序的结果(order by),这是我的存储过程:

DELIMITER $$

CREATE DEFINER=`root`@`localhost` PROCEDURE `getReadReportsPagingFinal`(startIndex INTEGER, pageSize INTEGER, sortingCol VARCHAR(255), sortingDir VARCHAR(255))
BEGIN

    SET @Query = "SELECT * FROM reports 
    WHERE 'new'=0
    ORDER BY ?, ?
    LIMIT ?, ?";


    SET @a = sortingCol;
    SET @b = sortingDir;
    SET @c = startIndex;
    SET @d = pageSize;

    PREPARE stmt1 FROM @Query;
    EXECUTE stmt1 USING @a, @b, @c, @d;
    DEALLOCATE PREPARE stmt1;
END

我知道占位符不能用于列名:

  

对于大多数驱动程序,占位符不能用于任何元素   声明会阻止数据库服务器验证   语句并为其创建查询执行计划。

所以我试图将sortingCol和sortingDir连接到查询:

@Query = CONCAT(@Query, sortingCol);

给出了语法错误。

有更好的方法吗?目前,参数通过调用存储过程的PHP脚本传递。

1 个答案:

答案 0 :(得分:1)

您不能将列放在LIMIT子句之后的末尾。您排序的列必须在ORDER BY子句中。但是你没错,你不能在列名中使用参数。

SET @Query = CONCAT("SELECT * FROM reports 
  WHERE 'new'=0
  ORDER BY ", sortingCol, " ", sortingDir,
" LIMIT ?, ?");

小心地在这些字符串片段中放置SQL关键字周围的空格。您不希望最终得到ORDER BY column1 ASCLIMIT ? ?

另外请记住,在进行PREPARE之前,通过将过程参数插入到查询中,您将面临SQL注入的风险。如果有人欺骗您的应用程序传递sortedCol:1 UNION SELECT * FROM information_schema.columns --

,该怎么办?

在将这些字符串连接到SQL之前,您需要采取措施白名单这些字符串。当您处理动态列名或SQL关键字时,这是防止SQL注入漏洞的最佳防御。