MySQL 带参数的准备语句不返回数据

MySQL prepared statements with parameters not returning data

我一直在尝试使参数化准备语句起作用。第一个函数仅显示带有列名的 header 行,不显示任何日期。第二 函数提供所有请求的数据。区别在于第一个使用参数而第二个仅使用连接的字符串。第一个中的 select 语句 函数用于调试目的,任何变量中都没有 NULL 字符串。

我想让参数化版本正常工作,如果有任何帮助,我将不胜感激。

我已经查看了这些 Whosebug 答案,Multiple Parameters, mysql Prepare Statement, Internals of prepared statement, unable 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 ;

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

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

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

参数无法保护您不让 sql 被 "user" 提供。