【问题标题】:Incorrect datetime value: '2018' for column when passing valid date as string不正确的日期时间值:将有效日期作为字符串传递时列的“2018”
【发布时间】:2018-01-25 16:22:38
【问题描述】:

今天我遇到了一个非常奇怪的问题。显然传递的日期与传递给我的查询的 bind_param 不同。

数据库结构:

|id varchar(16) autoincrement|date_created datetime|date_updated datetime|

当前该表包含有效数据:

|1|2018-01-25 16:53:40|2018-01-25 16:53:40|

现在我正在尝试执行准备好的UPDATE 语句:

UPDATE `table1` SET `date_created` = ?, `date_updated` = ? WHERE `id` = ?

我正在绑定以下数据:

["date_created"]=> string(19) "2018-01-25 16:53:40"
["date_updated"]=> string(19) "2018-01-25 17:02:57"
["id"]=> int(1) 1

但由于任何原因我得到了错误

1292: string(67) "不正确的日期时间值:第 1 行的列 'date_created' 的 '2018'"

我不明白为什么bind_paramsexecute 应该将有效日期缩短为年份

编辑:PHP 代码,根据要求。它是一个自动生成查询并执行它的函数。我添加了var_dumps“应该执行”查询的部分

public function executeUpdateQuery(){
    // update existing record
    $where['id'] = 1;
    $array['date_created'] = self::getTimeStamp();
    $array['date_updated'] = self::getTimeStamp();
    if(!$this->updateRecord($where, $array)){
        print("<br>Error:<br>");
        var_dump($this->db->error);
    }
}

public static function getTimeStamp(){
    return date('Y-m-d H:i:s');
}

/**
 * @param array $array
 * @return string
 */
public static function getTypes(array $array = []) : string {
    $types = "";
    foreach ($array as $value){
        if(is_int($value))
            $types .= "i";
        elseif(is_string($value))
            $types .= "s";
        elseif(is_bool($value))
            $types .= "i";
        else
            $types .= "s";
    }
    return $types;
}

public function updateRecord(array $array = [], array $fields = []){

    if(empty($array) || empty($fields)) return FALSE;
    /** @var \mysqli_stmt $stmt */
    $query = "UPDATE `" . $this->tablename . "` SET `" . implode("` = ?, `", array_keys($fields)) . "` = ? WHERE `" . implode("` = ? AND `", array_keys($array)) . "` = ?;";
    $stmt = $this->db->prepare($query);

    $types = self::getTypes($fields);
    $types .= self::getTypes($array);
    if(!$stmt->bind_param($types, ...array_values($fields), ...array_values($array))) {
        return FALSE;
    }
    $result = $stmt->execute();
    $resultquery = $query;
    foreach ($fields as $field){
        $resultquery = $this->str_replace_first('?', (is_int($field)?$field:"'".$field."'"), $resultquery);
    }
    foreach ($array as $field){
        $resultquery = $this->str_replace_first('?', (is_int($field)?$field:"'".$field."'"), $resultquery);
    }
    var_dump($resultquery);
    print("<br>Fields:<br>");
    var_dump($fields);
    print("<br>Affected Rows:<br>");
    var_dump(mysqli_affected_rows($this->db));
    print("<br>Errors:<br>");
    var_dump(mysqli_errno($this->db));
    var_dump(mysqli_error($this->db));
    var_dump(mysqli_error_list($this->db));
    return $result;
}

public function str_replace_first($from, $to, $subject){
    $from = '/'.preg_quote($from, '/').'/';

    return preg_replace($from, $to, $subject, 1);
}

【问题讨论】:

  • 不仅显示数据,还显示 PHP 代码
  • @RaymondNijland 我会添加它,但会很困惑 - 因为我会自动生成我的查询

标签: php mysql datetime bindparam mysql-error-1292


【解决方案1】:

显然问题在于datetime 字段被绑定为整数而不是字符串,因为我混淆了这两个数组:

$types = self::getTypes($fields);
$types .= self::getTypes($array);

因此,字符串 "2018-01-25 16:53:40" 被转换为整数 2018

实际执行的bind_param看起来像:

bind_param(iss, a string, a string, an integer);

【讨论】:

    猜你喜欢
    • 2020-10-05
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 2023-03-15
    • 2018-06-24
    • 1970-01-01
    • 2013-06-28
    • 1970-01-01
    相关资源
    最近更新 更多