You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL插入1948年timestamp字段出现数据截断错误的原因排查

MySQL 8.0插入早期年份Timestamp时出现数据截断错误

问题场景

在MySQL Server 8.0环境下,向tb_cliente表插入年份为1948的日期值时触发数据截断错误,但插入1999年的日期值可正常执行。

表结构

CREATE TABLE tb_cliente ( 
    id bigint unsigned NOT NULL AUTO_INCREMENT, 
    st_servidor tinyint(1) NOT NULL, 
    nm_nome varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, 
    nm_nome_social varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    cd_matricula varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, 
    cd_siape varchar(255) CHARACTER SET utf8mb4 
            COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    dt_nascimento timestamp NOT NULL, 
    sexo varchar(1) COLLATE utf8mb4_unicode_ci NOT NULL, 
    nacionalidade varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, 
    ano_chegada_no_pais varchar(255) 
        COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    naturalidade varchar(255) CHARACTER SET utf8mb4 
        COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    uf_nascimento varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, 
    estado_civil varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, 
    sn_conjuge_servidor tinyint(1) DEFAULT NULL, 
    nm_conjuge varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    nm_pai varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    nm_mae varchar(255) CHARACTER SET utf8mb4 
        COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    raca varchar(255) CHARACTER SET utf8mb4 
        COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    cor_dos_olhos varchar(255) CHARACTER SET utf8mb4 
        COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    cor_dos_cabelos varchar(255) CHARACTER SET utf8mb4 
        COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    sn_alergico tinyint(1) DEFAULT NULL, 
    grau_de_instrucao varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    dt_conclusao timestamp NULL DEFAULT NULL, 
    altura decimal(8,2) DEFAULT NULL, 
    tipo_sanguineo varchar(255) CHARACTER SET utf8mb4 
        COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    sn_doador_de_orgaos tinyint(1) DEFAULT NULL, 
    nome_anterior varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    endereco varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    nr_cep varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    nr_cpf varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, 
    telefone varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    telefone_celular varchar(255) 
        COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    email_institucional varchar(255) 
        COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    email_externo varchar(255) 
        COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    email_comunicados varchar(255) 
        COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    endereco_correspondencia varchar(255) 
        COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    nr_cep_correspondencia varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    created_at timestamp NULL DEFAULT NULL, 
    updated_at timestamp NULL DEFAULT NULL, 
    user_id bigint unsigned DEFAULT NULL, 
    PRIMARY KEY (id), 
    UNIQUE KEY tb_servidor_nr_cpf_unique (nr_cpf), 
    KEY tb_servidor_user_id_index (user_id), 
    CONSTRAINT tb_servidor_user_id_foreign FOREIGN KEY (user_id) 
        REFERENCES tb_users (id) ON DELETE CASCADE ON UPDATE CASCADE 
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

错误信息

SQL Error [1292] [22001]: Data truncation: Incorrect datetime value: '1948-07-19 00:00:00' for column 'dt_nascimento' at row 1

成功插入的示例语句

insert into tb_cliente (
            updated_at, created_at, st_servidor, 
            nm_nome, cd_matricula, dt_nascimento, 
            sexo, nacionalidade, uf_nascimento, 
            estado_civil, grau_de_instrucao, nr_cpf, 
            telefone, telefone_celular, email_institucional, email_externo) 
values ('2022-10-25 00:00:00', '2022-10-25 00:00:00', '1', 
        'User name 1', '000000', '1999-07-19 00:00:00','M', 
        '1', 'AC', 'CASADO','ENSINO' , '000000', '000000', '000000', 
        'USER@UOL.COM.BR', 'USER@UOL.COM.BR' )

原因分析

MySQL的timestamp类型有严格的取值范围限制:默认是**'1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC**。要插入的1948年日期早于这个范围的下限,因此触发数据截断错误;而1999年的日期在合法范围内,所以插入成功。

解决方法

方法一:修改字段类型为datetime(推荐)

datetime类型的取值范围是**'1000-01-01 00:00:00' 到 '9999-12-31 23:59:59'**,完全覆盖1948年的日期需求。执行以下SQL修改字段:

ALTER TABLE tb_cliente MODIFY COLUMN dt_nascimento datetime NOT NULL;
-- 如果dt_conclusao字段也需要存储早期日期,可一并修改
ALTER TABLE tb_cliente MODIFY COLUMN dt_conclusao datetime NULL DEFAULT NULL;

方法二:调整MySQL全局参数(不推荐)

若必须使用timestamp类型,可修改explicit_defaults_for_timestamp参数并调整时区配置,确保转换后的UTC时间在合法范围内。但该方法会影响整个数据库的timestamp行为,可能引发其他兼容性问题,不建议用于存储早于1970年的日期。


内容的提问来源于stack exchange,提问作者fabionvs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 08:45:30