【问题标题】:How to compare the month parts of two dates?如何比较两个日期的月份部分?
【发布时间】:2017-05-29 18:41:29
【问题描述】:

我正在尝试查询当前月份,这是我的查询:

 $clients = $this->Clients;
    $query = $clients->find();

    if($this->Auth->user('role') !== 'admin'){
        $query->where(['user_id =' => $this->Auth->user('id')]);
        $query->where(['MONTH(dob) = ' => 'EXTRACT(month FROM (NOW()))']);

        $query->order(['dob' => 'ASC']);

    }

它返回 0 条记录(我的字段是日期类型),但是 phpmyadmin 中的这个查询有效:

SELECT * FROM `clients` WHERE MONTH(dob) = EXTRACT(month FROM (NOW()))

我做错了什么?

【问题讨论】:

    标签: sql cakephp cakephp-3.0 query-builder


    【解决方案1】:

    只需查看实际生成的查询(查看您的 DBMS 查询日志,或尝试DebugKit),它看起来会有所不同,因为key => value 条件集中的右侧值受参数绑定/铸造/引用/转义。在您的情况下,它将被视为字符串,因此条件最终将类似于:

    WHERE MONTH(dob) = 'EXTRACT(month FROM (NOW()))'
    

    这当然不会匹配任何东西。

    您可以将整个 SQL sn-p 作为单个数组值或表达式对象传递,这样它将按原样插入到查询中(不要以这种方式插入用户值,这会创建 SQL 注入漏洞!),但我建议改用可移植函数表达式。

    CakePHP 附带 EXTRACTNOW 的函数表达式,因此您可以简单地执行以下操作:

    use Cake\Database\Expression\IdentifierExpression;
    use Cake\Database\Expression\QueryExpression;
    use Cake\ORM\Query;
    
    // ...
    
    $query->where(function (QueryExpression $exp, Query $query) {
        return $exp->eq(
            $query->func()->extract('MONTH', new IdentifierExpression('dob')),
            $query->func()->extract('MONTH', $query->func()->now())
        );
    });
    

    看起来有点复杂,但值得,它可以跨 DBMS 移植并且兼容自动引用。生成的 SQL 将类似于

    WHERE EXTRACT(MONTH FROM (dob)) = (EXTRACT(MONTH FROM (NOW())))
    

    另见

    【讨论】:

    • 谢谢,这里有很多很棒的信息,但是当我尝试您的查询时,我收到了这个错误:“消息”:“在 null 上调用成员函数 func()”
    • 如果错误真的发生在上面的确切代码中,我会感到非常惊讶,因为传递给闭包的第二个参数的值是$this。如果它是null,则意味着调用该函数的对象本身不存在(尽管我已经在 PHP 中看到了更奇怪的怪癖)。无论如何,在没有看到所有代码、堆栈跟踪、知道确切的 CakePHP 版本的情况下,在 cmets 中我几乎无能为力。 @bstras21
    • 其实拼错是我的错。您的代码确实有效,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多