-1

今天我遇到了一个非常奇怪的问题。显然,传递的日期与传递给我的查询的 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:字符串(67)“不正确的日期时间值:第 1 行的列 'date_created' 的 '2018'”

我不明白为什么bind_paramsexecute应该将有效日期减少到一年

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

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);
}
4

1 回答 1

0

显然问题是该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);
于 2018-01-25T17:30:36.000 回答