2

我有一个通过 PHP 和 PDO 构建的 SELECT 语句,以提供在过去 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
4

2 回答 2

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

于 2013-05-29T01:27:16.950 回答
1

您不能使用占位符 for 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();
于 2013-05-29T01:18:48.507 回答