我有一个存储过程,我曾经直接在字段中写入,但我更改了它以允许用户将字段提供为TEXT:
CREATE DEFINER=`root`@`localhost` PROCEDURE `leaderboard_get_data`(numPerPage INTEGER,
pageNumber INTEGER, daysSince INTEGER, field TEXT)
BEGIN
DECLARE numBefore INTEGER DEFAULT (((pageNumber - 1) * numPerPage));
SET @dateSince = DATE_SUB(DATE(NOW()), INTERVAL daysSince DAY);
SELECT
@curRank := @curRank + 1 AS PlayerRank,
PlayerName, field
FROM players p, (SELECT @curRank := (((pageNumber - 1) * numPerPage))) r
WHERE @curRank BETWEEN (((pageNumber - 1) * numPerPage)) AND (((pageNumber - 1) * numPerPage) + 1) + (numPerPage - 1) - 1
AND PlayerLastGameCompletedDate IS NOT NULL AND (daysSince < 0 or DATE(PlayerLastGameCompletedDate) BETWEEN DATE(@dateSince) AND DATE(NOW()))
ORDER BY field DESC
LIMIT numBefore, numPerPage;
END
如您所见,字段为TEXT。现在,当我执行此存储的进程时,MySQL C ++ Connector会抛出sqlstate = 0,sqlerror = 0的异常。
我怀疑我可能没有正确传递字段,可能有一种特殊的方法可以传递它。
可能出现什么问题?
由于
答案 0 :(得分:1)
如果您要指定列,则必须使用动态sql(预准备语句)。
CREATE DEFINER=`root`@`localhost` PROCEDURE `leaderboard_get_data`(numPerPage INTEGER,
pageNumber INTEGER, daysSince INTEGER, field TEXT)
BEGIN
DECLARE numBefore INTEGER DEFAULT (((pageNumber - 1) * numPerPage));
SET @dateSince = DATE_SUB(DATE(NOW()), INTERVAL daysSince DAY);
SET @sql = CONCAT('SELECT
@curRank := @curRank + 1 AS PlayerRank,
PlayerName, ', field, '
FROM players p, (SELECT @curRank := (((pageNumber - 1) * numPerPage))) r
WHERE @curRank BETWEEN (((pageNumber - 1) * numPerPage)) AND (((pageNumber - 1) * numPerPage) + 1) + (numPerPage - 1) - 1
AND PlayerLastGameCompletedDate IS NOT NULL AND (daysSince < 0 or DATE(PlayerLastGameCompletedDate) BETWEEN DATE(@dateSince) AND DATE(NOW()))
ORDER BY ', field, ' DESC
LIMIT ?, ?;');
PREPARE stmt FROM @sql;
EXECUTE stmt USING numBefore, numPerPage;
DEALLOCATE PREPARE stmt;
END
答案 1 :(得分:0)
你做不到这么容易。现在你的SELECT
正在你的玩家表中寻找名为“PlayerName”和“field”的字段。作为一种解决方法,您可以尝试将查询构建为concat()
的字符串,并将其作为预准备语句运行。