【问题标题】:Error matching dates in PDOPDO 中的错误匹配日期
【发布时间】:2018-12-05 11:16:05
【问题描述】:

我正在尝试更新日期列与当前年份和月份匹配的数据库表上的记录。我不断收到此错误

日期时间值不正确:“created_at”列的“%2018-06%”

这就是我正在做的事情

$current_month = date("Y-m");
$points = 4;
$freelancer_id =4;
$update = "UPDATE monthly_limits SET points = :points WHERE freelancer_id = :freelancer_id AND 
created_at LIKE concat('%', :current_month, '%')";
$query = $this->db->prepare($update);
$query->bindParam("points", $points);
$query->bindParam("current_month", $current_month);
$query->bindParam("freelancer_id", $freelancer_id);
$query->execute();

请问我该如何解决?

【问题讨论】:

  • 你遇到了什么错误?
  • 你用的是什么数据库?
  • 您最好使用YEAR(created_at) = :year AND MONTH(created_at) = :month,并传入date('Y') 作为年份和date('m') 作为月份。
  • 不知道,但无论如何,在左侧使用通配符对索引不起作用。
  • 你用的是什么mysql版本?我从未见过where 中的日期/日期时间列出现该错误。如果您尝试设置日期/日期时间列,我可以设置它。

标签: php sql pdo


【解决方案1】:

这不是日期在 SQL 数据库中的工作方式。 like 语句用于字符串类型,而日期是一个美化的数字。鉴于参数的风格,我打赌你最好的选择是进行两次差异检查。一个月一次,一年一次。

你还没有指定你的 RDBMS,所以我会给出一个 MySQL 的答案。

UPDATE 
  monthly_limits SET points = :points 
WHERE 
  freelancer_id         = :freelancer_id 
  AND Year(created_at)  = :current_year
  AND Month(created_at) = :current_month

【讨论】:

    【解决方案2】:

    您不能将通配符与日期和 db 值一起用作日期。

    您最好获取要比较的日期片段并直接使用它们:

    $current_year = date("Y"); 
    $current_month = date("mm");
    $points = 4;
    $freelancer_id =4;
    //Use the SQL version you have to get the date parts this is general.
    $update = "UPDATE monthly_limits SET points = :points WHERE freelancer_id = :freelancer_id AND 
            MONTH(created_at) = :current_month AND YEAR(created_at) = :current_year";
            $query = $this->db->prepare($update);
            $query->bindParam("points", $points);
            //Separated these
            $query->bindParam("current_month", $current_month);
            $query->bindParam("current_month", $current_year);
            $query->bindParam("freelancer_id", $freelancer_id);
            $query->execute();
    

    【讨论】:

    • 为什么不能在日期/日期时间中使用通配符? sqlfiddle.com/#!9/0e255a/2
    • 您是否尝试过针对您拥有的实际数据库运行它?我只是测试 MSSql 和 MySql 两者都返回一个空集。此外,这将是非常低效的,因为数据库会将所有内容都转换为字符串,然后进行某种字符串比较,其中显示的数据对于目标更加清晰并且更普遍使用。
    • 同样,使用like 对 1000 条记录进行测试需要 42 秒才能返回任何内容。使用 year(date)month(date) 返回现有的耗时不到 1 秒的 1000 行。
    • 但是您实际上可能会遇到这个stackoverflow.com/questions/22806870/…
    【解决方案3】:

    为了利用索引,我建议您使用完整日期。只需将一个日期设置为月初,将另一个日期设置为月底,然后搜索该范围内的日期:

    $date_start = date('Y-m-1 00:00:00');
    $date_end = date('Y-m-t 23:59:59');
    
    $points = 4;
    $freelancer_id =4;
    $query = $this->db->prepare("UPDATE monthly_limits 
        SET points = :points 
        WHERE freelancer_id = :freelancer_id 
        AND created_at >= :date_start
        AND created_at <= :date_end"
    );
    $query->bindParam("points", $points);
    $query->bindParam("date_start", $date_start);
    $query->bindParam("date_end", $date_end);
    $query->bindParam("freelancer_id", $freelancer_id);
    $query->execute();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-01
      • 2018-02-25
      • 1970-01-01
      相关资源
      最近更新 更多