清理MySQL存储过程参数

清理MySQL存储过程参数,mysql,stored-procedures,sql-injection,Mysql,Stored Procedures,Sql Injection,我正在开发一个存储过程,它根据输入参数的值动态生成查询。sp使用mysql中的CONCAT()函数构建查询。其中一个参数允许用户输入搜索字符串作为varchar数据类型 mysql中是否有类似于php的mysql\u real\u escape\u string()的功能可以防止sql注入攻击 以下是此sp正在执行的操作的示例: //正在尝试发布代码。不断被拒绝。不告诉我为什么。 不要使用CONCAT()函数来生成查询 使用。准备好声明。 不要使用CONCAT()函数来生成查询 使用。准备好声

我正在开发一个存储过程,它根据输入参数的值动态生成查询。sp使用mysql中的CONCAT()函数构建查询。其中一个参数允许用户输入搜索字符串作为varchar数据类型

mysql中是否有类似于php的
mysql\u real\u escape\u string()
的功能可以防止sql注入攻击

以下是此sp正在执行的操作的示例:

//正在尝试发布代码。不断被拒绝。不告诉我为什么。

不要使用CONCAT()函数来生成查询

使用。准备好声明。 不要使用CONCAT()函数来生成查询

使用。准备好声明。 请回复您的评论:


我同意你的看法,但是,你如何根据输入在准备好的报表中添加特定部分。例如,如果参数_A和_B可用,则连接另外两个表并包含WHERE语句?然后知道准备好的语句正在为哪个版本的查询运行,以知道需要绑定哪些参数

有时您必须使用条件代码块:

CREATE PROCEDURE MyProc(IN _A INT, IN _B INT)
BEGIN
  IF _A IS NOT NULL AND _B IS NOT NULL
    PREPARE stmt1 FROM 'SELECT * FROM MyTable WHERE A = ? AND B = ?';
    SET @A = _A, @B = _B;
    EXECUTE stmt1 USING @A, @B;
    DEALLOCATE PREPARE stmt1;
  ELSEIF _A IS NOT NULL
    PREPARE stmt1 FROM 'SELECT * FROM MyTable WHERE A = ?';
    SET @A = _A;
    EXECUTE stmt1 USING @A;
    DEALLOCATE PREPARE stmt1;
  ELSEIF _B IS NOT NULL
    PREPARE stmt1 FROM 'SELECT * FROM MyTable WHERE B = ?';
    SET @B = _B;
    EXECUTE stmt1 USING @B;
    DEALLOCATE PREPARE stmt1;
  END
END
对于具有条件限制和偏移量的示例,您可以更简单地执行此操作。受
INT
数据类型约束的输入参数不存在SQL注入风险。然后,您可以使用COALESCE()将变量默认为具有一些合理值的变量

我同意@YourCommonSense的说法,即存储过程不是最好的解决方案。MySQL的存储过程实现很原始,很难使用。我看到许多关于堆栈溢出的问题,询问如何在MySQL的存储过程中执行某些任务,每次都让我感到畏缩

您最好使用几乎任何其他脚本语言,而不是使用MySQL存储过程。

关于您的评论:


我同意你的看法,但是,你如何根据输入在准备好的报表中添加特定部分。例如,如果参数_A和_B可用,则连接另外两个表并包含WHERE语句?然后知道准备好的语句正在为哪个版本的查询运行,以知道需要绑定哪些参数

有时您必须使用条件代码块:

CREATE PROCEDURE MyProc(IN _A INT, IN _B INT)
BEGIN
  IF _A IS NOT NULL AND _B IS NOT NULL
    PREPARE stmt1 FROM 'SELECT * FROM MyTable WHERE A = ? AND B = ?';
    SET @A = _A, @B = _B;
    EXECUTE stmt1 USING @A, @B;
    DEALLOCATE PREPARE stmt1;
  ELSEIF _A IS NOT NULL
    PREPARE stmt1 FROM 'SELECT * FROM MyTable WHERE A = ?';
    SET @A = _A;
    EXECUTE stmt1 USING @A;
    DEALLOCATE PREPARE stmt1;
  ELSEIF _B IS NOT NULL
    PREPARE stmt1 FROM 'SELECT * FROM MyTable WHERE B = ?';
    SET @B = _B;
    EXECUTE stmt1 USING @B;
    DEALLOCATE PREPARE stmt1;
  END
END
对于具有条件限制和偏移量的示例,您可以更简单地执行此操作。受
INT
数据类型约束的输入参数不存在SQL注入风险。然后,您可以使用COALESCE()将变量默认为具有一些合理值的变量

我同意@YourCommonSense的说法,即存储过程不是最好的解决方案。MySQL的存储过程实现很原始,很难使用。我看到许多关于堆栈溢出的问题,询问如何在MySQL的存储过程中执行某些任务,每次都让我感到畏缩


您最好使用几乎任何其他脚本语言,而不是使用MySQL存储过程。

将代码粘贴为明文,然后我们可以帮助您设置格式MySQL\u real\u escape\u string()不能防止sql注入攻击。@Alfabravo我也无法将其添加为纯文本。单击“提交”按钮时,我遇到一条消息,说明“提交编辑时出错”,无论其格式如何。请在“注释行”下方重试。。。确保它不是太大!:)@同样的反应。不过我还是上传了一张截图。你知道为什么不允许上传这段代码吗?将代码粘贴为明文,然后我们可以帮助你格式化MySQL\u real\u escape\u string()不能防止sql注入攻击。@Alfabravo我也无法将其添加为纯文本。单击“提交”按钮时,我遇到一条消息,说明“提交编辑时出错”,无论其格式如何。请在“注释行”下方重试。。。确保它不是太大!:)@同样的反应。不过我还是上传了一张截图。你知道为什么它不允许上传这个特定的代码块吗?一旦你完成了,别忘了,否则它可能会挂起,你可能最终会同意你的观点,但是你如何根据输入在准备好的语句中添加特定的部分呢。例如,如果参数_A和_B可用,则连接另外两个表并包含WHERE语句?然后知道准备好的语句运行的是哪个版本的查询,以知道需要绑定哪些参数?我不知道。首先,我决不会使用存储过程。但是你可以尝试实现一些东西,比如给定你的图片,我认为在搜索中使用占位符没有任何问题。一旦你完成了,不要忘了这样做,否则它可能会挂起,最终你可能会同意你的观点,但是你如何根据输入向准备好的语句中添加特定部分。例如,如果参数_A和_B可用,则连接另外两个表并包含WHERE语句?然后知道准备好的语句运行的是哪个版本的查询,以知道需要绑定哪些参数?我不知道。首先,我决不会使用存储过程。但是您可以尝试实现一些类似于给定图片的功能,我认为使用占位符进行搜索没有任何问题。
“您最好使用几乎任何其他脚本语言,而不是使用MySQL存储过程”
“您最好使用几乎任何其他脚本语言,而不是使用MySQL存储过程”
CREATE PROCEDURE MyProc(INT _quick_search VARCHAR(50),
  IN _limit INT, IN _offset INT)
BEGIN
  SET @LIMIT = COALESCE(_limit, 1);
  SET @OFFSET = COALESCE(_offset, 0);

  PREPARE stmt1 FROM 'SELECT ...blah blah... LIMIT ? OFFSET ?';
  EXECUTE stmt1 USING @LIMIT, @OFFSET;
  DEALLOCATE PREPARE stmt1;
END