【问题标题】:How do I bind an INTERVAL param with PDO?如何将 INTERVAL 参数与 PDO 绑定?
【发布时间】:2019-06-05 06:56:34
【问题描述】:

我有一个查询,我试图完全从绑定参数设置,但现在我不得不求助于从 GET 参数附加一个字符串(我真的不想这样做)。

这是我现在的解决方案:

$interval = !empty($_REQUEST['interval']) ? $_REQUEST['interval'] : '28 DAY';
$interval = str_replace('_', ' ', $interval);

$data = array(
    ':msisdn' => $_REQUEST['msisdn']
);

$sql = <<<SQL
SELECT
    COUNT(*) AS `countup`
FROM
    (
        SELECT
            utc.`id_user`
        FROM
            `user_to_cli` utc
        WHERE
            1=1
            AND utc.`cli` = :msisdn
            AND utc.`dts_start` > CURDATE() - INTERVAL $interval
    ) a
;
SQL;

这很好用,但是当我尝试将间隔更改为绑定参数时,如下所示:

$interval = !empty($_REQUEST['interval']) ? $_REQUEST['interval'] : '28 DAY';
$interval = str_replace('_', ' ', $interval);

$data = array(
    ':msisdn' => $_REQUEST['msisdn'],
    ':interval' => $interval
);

$sql = <<<SQL
SELECT
    COUNT(*) AS `countup`
FROM
    (
        SELECT
            *
        FROM
            `user_to_cli` utc
        WHERE
            1=1
            AND utc.`cli` = :msisdn
            AND utc.`dts_start` > CURDATE() - INTERVAL :interval
    ) a
;
SQL;

我收到以下错误:

Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') a'

【问题讨论】:

  • 28 DAY 更像是一个语法结构而不是一个值。绑定数字部分可能会起作用(每个 ->bindParam 键入,或每个 SQL 转换 INTERVAL (1*?) DAY)。
  • 如果我只绑定 28 而不是 28 DAY,这可以工作,但我希望能够按 HOUR、MONTH 等进行选择。
  • 我猜你将无法参数化 DAYMONTH YEAR 等。我真的会在那里使用自定义白名单过滤器。 (当然比 inlineCASE 更省力/可能甚至不可行。)

标签: php mysql pdo


【解决方案1】:

您的代码尝试使用绑定变量来替换 SQL 关键字和数字。 You Can't Do That™。

当我解决了这个问题后,我将时间间隔转换为秒,然后使用

 CURDATE() - INTERVAL :seconds SECONDS

顺便说一句,CURDATE() 今天给你午夜。如果您处理的是次日间隔,则可能需要 NOW()。

【讨论】:

  • 我认为这是最好的解决方案。我应该只转换为秒/天/什么,并始终使用相同的间隔测量。
猜你喜欢
  • 2016-12-26
  • 2017-01-29
  • 1970-01-01
  • 2011-05-31
  • 2016-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多