【问题标题】:MySQL prepared statements with parameters not returning dataMySQL准备的带有参数的语句不返回数据
【发布时间】:2018-06-15 19:54:04
【问题描述】:

我一直在尝试使参数化的准备好的语句工作。第一个函数只显示带有列名的标题行,不显示任何daya。第二 函数提供所有请求的数据。不同之处在于第一个使用参数,第二个只使用连接字符串。第一个中的选择语句 函数用于调试目的,任何变量中都没有 NULL 字符串。

我想让参数化版本正常工作,我将不胜感激。

我已经查看了这些 stackoverflow 答案,Multiple Parametersmysql Prepare StatementInternals of prepared statementunable to create prepared statements(可能是我的问题的答案)。

-- -----------------------------------------------------
-- procedure getAllBookDataWhere2
-- -----------------------------------------------------

USE `booklibinventory`;
DROP procedure IF EXISTS `booklibinventory`.`getAllBookDataWhere2`;

DELIMITER $$
USE `booklibinventory`$$
CREATE PROCEDURE `getAllBookDataWhere2` 
(
    IN whereStr VARCHAR(256)
)
BEGIN

    DECLARE finalQuery VARCHAR(4096);
    DECLARE selectedFields, leftJoinTables, joinOnFields VARCHAR(1024);
    DECLARE whereClause, orderByClause VARCHAR(256);

    SET @selectedFields = allBooksSelectFields();
    SET @jointTables4Query = allBooksDataTables();
    -- orderBy may become a parameter in the future.
    SET @orderByClause = ' a.LastName, a.FirstName, s.SeriesName, v.VolumeNumber, t.TitleStr';
    SET @whereclause = whereStr;

    -- @selectedFields and @jointTables4Query are concatenated because they don't change,
    -- @whereClause and @orderByClause can change and therefore are parameters.

SELECT @orderByClause;
SELECT @whereClause;

    SET @finalQuery = CONCAT('SELECT ', @selectedFields);
    SET @finalQuery = CONCAT(@finalQuery, ' FROM bookinfo AS BKI ');
    SET @finalQuery = CONCAT(@finalQuery, @jointTables4Query);
    SET @finalQuery = CONCAT(@finalQuery, ' WHERE ?  ORDER BY ? ;');

SELECT @finalQuery;

    PREPARE stmt FROM @finalQuery;
    EXECUTE stmt USING @whereClause, @orderByClause;
    DEALLOCATE PREPARE stmt;

END$$

DELIMITER ;

-- -----------------------------------------------------
-- procedure getAllBookDataWhere
-- -----------------------------------------------------

USE `booklibinventory`;
DROP procedure IF EXISTS `booklibinventory`.`getAllBookDataWhere`;

DELIMITER $$
USE `booklibinventory`$$
CREATE PROCEDURE `getAllBookDataWhere` 
(
    IN whereStr VARCHAR(256)
)
BEGIN

    DECLARE finalQuery VARCHAR(4096);
    DECLARE selectedFields, leftJoinTables, joinOnFields VARCHAR(1024);
    DECLARE whereClause, orderByClause VARCHAR(256);

    SET @selectedFields = allBooksSelectFields();
    SET @jointTables4Query = allBooksDataTables();
    -- orderBy may become a parameter in the future.
    SET @orderByClause = ' ORDER BY a.LastName, a.FirstName, s.SeriesName, v.VolumeNumber, t.TitleStr;';
    SET @whereclause = CONCAT(' WHERE ', whereStr);

    -- @selectedFields and @jointTables4Query are concatenated because they don't change,
    -- @whereClause and @orderByClause can change and therefore are parameters.


    SET @finalQuery = CONCAT('SELECT ', @selectedFields);
    SET @finalQuery = CONCAT(@finalQuery, ' FROM bookinfo AS BKI ');
    SET @finalQuery = CONCAT(@finalQuery, @jointTables4Query);
    SET @finalQuery = CONCAT(@finalQuery, @whereClause);
    SET @finalQuery = CONCAT(@finalQuery, @orderByClause);

    PREPARE stmt FROM @finalQuery;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

END$$

DELIMITER ;

【问题讨论】:

    标签: mysql parameters prepared-statement


    【解决方案1】:

    参数用于值,而不是整个子句。您的 WHERE 和 ORDER BY 子句实际上是 WHERE 'somestring'ORDER BY 'somestring'(注意引号)。

    另外,如果我没记错的话,EXECUTEd 语句不会将结果集添加到过程返回的结果中。通常,执行最终需要将insert select 放入一个临时表中,过程可以在退出之前直接从中选择。

    编辑:由于您已经将查询连接在一起,您可以替换您的 ?-占位符 ... WHERE ', @whereClause, ' ORDER BY ', @orderByClause, ';');

    参数不能保护你不让原始 sql 被“用户”提供。

    【讨论】:

      猜你喜欢
      • 2020-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多