Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Aceita datas invalidas como "algo", "qualquer texto"

Testei muitas datas, e todas são aceitas e inseridas com um status http 201, fiz alguns console.log's e todos diziam que a invalid data, mas o "erro" permanecia null, e ao olhar no workbench as datas inseridas era sempre 0000-00-00 00:00:00, mudei o HH:MM:SS para minusculo, fiz vários testes, inclusive utilizei o código do curso e mesmo assim aceitava datas inválidas,

const moment = require('moment');
const conexao = require('../infrastructure/conexao');

class Atendimento{
    adiciona(atendimento, res){
        const dataCriacao = moment().format('YYYY-MM-DD hh:mm:ss');
        const data = moment(atendimento.data, 'DD/MM/YYYY').format('YYYY-MM-DD hh:mm:ss')

        const atendimentoDatado = {...atendimento, dataCriacao, data};
        const sql = 'INSERT INTO Atendimentos SET ?';
        conexao.query(sql, atendimentoDatado, (erro, result) => {
            if(erro) {
                res.status(400).json(erro)
            } else {
                res.status(201).json(result)
            }
        })
    }
}

module.exports = new Atendimento;

é como se ele visse o erro e substituísse por esse valor default, tentei colocar um valor default qualquer na criação da tabela como '2020-01-01 00:00:00', mas a data continua aparecendo como '0000-00-00 00:00:00, segue também o código da criação de tabela

class Tabelas{
    init(conexao){
        this.conexao = conexao;
        this.criarAtendimentos();
    };

    criarAtendimentos(){
        const sql = 
        `CREATE TABLE IF NOT EXISTS Atendimentos(
            id int NOT NULL AUTO_INCREMENT,
            cliente VARCHAR(50) NOT NULL,
            pet VARCHAR(20),
            servico VARCHAR(20) NOT NULL,
            data DATETIME NOT NULL,
            dataCriacao DATETIME NOT NULL,
            status VARCHAR(20) NOT NULL,
            observacoes TEXT,
            PRIMARY KEY(id)
        );`
        this.conexao.query(sql,(erro) => {
            if(erro){
                console.log(erro);
            } else {
                console.log('Tabela Atendimentos criada com sucesso');
            };
        })
    }
};
module.exports = new Tabelas;

testei com modificações e tudo, mas o erro persiste. queria saber se aconteceu com alguém ou se tem solução.

testei de outra forma com o código do github de hash <7413f9e299e798c4a0778875ba221d6ff850078f>

e coloquei o codigo assim para analisar a query do sql

const moment = require('moment')
const conexao = require('../infraestrutura/conexao')

class Atendimento {
    adiciona(atendimento, res) {
        const dataCriacao = moment().format('YYYY-MM-DD hh:mm:ss')
        const data = moment(atendimento.data, "DD-MM-YYYY").format('YYYY-MM-DD hh:mm:ss')
        const atendimentoDatado = {...atendimento, dataCriacao, data}

        const sql = 'INSERT INTO Atendimentos SET ?'
        //no postman coloquei:
        //cliente Guilherme
        //pet Buddy
        //servico Banho
        //data algo
        //status Agendado
        //observacoes Nenhuma

        var query = conexao.query(sql, atendimentoDatado, (erro, resultados, campos) => {
            console.log(query.sql)
            if(erro) {
                res.status(400).json(erro)
            } else {
                res.status(201).json(resultados)
            }
        })
    }
}

module.exports = new Atendimento

ao testar e ver o console da query.sql

a saída era: INSERT INTO Atendimentos SET cliente = 'Guilherme', pet = 'Buddy', servico = 'Banho', data = 'Invalid date', status = 'Agendado', observacoes = 'Nenhuma', dataCriacao = '2020-04-29 02:33:19'

queria saber pq mesmo a query colocando invalid date, fica com esse erro de aceitar a data e colocar 0000-00-00 00:00:00

1 resposta
solução!

Olá Guilherme, tudo bem com você?

Acredito que já deve ter encontrado a solução para esse problema, mas creio que possa servir para alunos que tenham as mesmas dúvidas, então peço perdão pela demora

A questão é que o MySQL muitas vezes vai evitar gerar erros, então quando um dado chega no banco de maneira incorreta, ele irá buscar fazer 2 coisas: substituir pelo valor padrão descrito pelo usuário

mysql> desc Atendimentos;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | int(11)     | NO   | PRI | NULL    | auto_increment |
| cliente     | varchar(50) | NO   |     | NULL    |                |
| pet         | varchar(20) | YES  |     | NULL    |                |
| servico     | varchar(20) | NO   |     | NULL    |                |
| data        | datetime    | NO   |     | NULL    |                |
| dataCriacao | datetime    | NO   |     | NULL    |                |
| status      | varchar(20) | NO   |     | NULL    |                |
| observacoes | text        | YES  |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+

Como não definimos nenhum valor padrão para a data o que ele faz é utilizar o próprio padrão do mysql que é criar uma data de "zeros", como podemos ver na documentação:

. If the date is totally wrong (outside the server's ability to store it), the special “zero” date value '0000-00-00' is stored in the column instead.

Traduzindo, se o servidor não consegue fazer uma conversão da data ele irá salvar com essa data especial, você pode checar isso fazendo inclusive uma inserção pelo bando de dados e no campo "data" colocar qualquer string aleatória que teremos o mesmo resultado

Pelo que a documentação diz as novas versões do Mysql utiliza o chamado strict mode por padrão, ou seja, dados inválidos são automaticamente rejeitados, entretanto caso o banco não esteja com esse comportamento podemos ativar com o SET sql_mode ='STRICT_TRANS_TABLES', dessa forma ao fazer uma inserção:

{
    "cliente": "Lucas",
    "pet": "Babalu",
    "servico": "Tosar",
    "Status": "Agendado",
    "observacoes": "Nenhuma",
    "data": "qualquer"
}

Teremos como erro:

  "sqlMessage": "Incorrect datetime value: 'Invalid date' for column 'data' at row 1",

Entretanto acredito que a melhor abordagem a se fazer é uma boa validação no servidor, como a instrutora fez no curso, do que deixar a cargo do banco de dados fazer essa validação , até porque já evitamos fazer contatos desnecessários com o banco, e, conseguímos ter uma noção do erro maior do que o retornado pelo mysql :)

Abraços e Bons Estudos!

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software