我有一个SELECT语句,我正在通过PHP和PDO构建,以提供已登录过去XX分钟的用户列表。当我硬编码SQL语句执行正常的时间间隔但是当我尝试替换从Web表单中选择的时间间隔时,我得到一个SQL错误。我不确定是什么问题。我正在使用PDO和PREPARE语句
try
{
$sql = 'SELECT DISTINCT PlayerName
FROM Player_Data pd LEFT JOIN character_data cd
ON pd.PlayerUID = cd.PlayerUID
WHERE cd.LastLogin > DATE_SUB(NOW(), :login_interval_value)';
$statement = $pdo->prepare($sql);
$statement->bindValue(':login_interval_value',$_POST['login_interval']);
$statement->execute();
$results = $statement->fetchAll();
}
catch (PDOException $e)
{
$error = 'Error getting player names: ' . $e->getMessage();
include 'error.html.php';
exit();
}
这是我得到的错误......
Error getting player names: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''INTERVAL 60 MINUTES')' at line 4
答案 0 :(得分:4)
两次更正。时间单位是单数(1)。另一个是你需要让login_interval的发布数据只是分钟数。这完全合法:
DATE_SUB(NOW(), INTERVAL '60' MINUTE)
这是不正确的,当你的帖子数据是整个区间表达时会发生什么:
DATE_SUB(NOW(), 'INTERVAL 60 MINUTE')
所以要么更改你的表单,所以$ _POST ['login_interval']只是分钟数或从中提取数字。假设您更改了表单,这就是您的代码更改为:
try
{
$sql = 'SELECT DISTINCT PlayerName
FROM Player_Data pd LEFT JOIN character_data cd
ON pd.PlayerUID = cd.PlayerUID
WHERE cd.LastLogin > DATE_SUB(NOW(), INTERVAL :login_interval_value MINUTE)';
$statement = $pdo->prepare($sql);
$statement->bindValue(':login_interval_value',$_POST['login_interval']);
$statement->execute();
$results = $statement->fetchAll();
}
1 - https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-add
答案 1 :(得分:1)
您不能使用INTERVAL 60 MINUTES
的占位符,它会引用它。
您只需要将值转换为整数。(相反,使用帖子编号。)
$sql = 'SELECT DISTINCT PlayerName
FROM Player_Data pd LEFT JOIN character_data cd
ON pd.PlayerUID = cd.PlayerUID
WHERE cd.LastLogin > DATE_SUB(NOW(), INTERVAL '.(int)$_POST['login_interval'].' MINUTES)';
$statement = $pdo->prepare($sql);
$statement->execute();
$results = $statement->fetchAll();