Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Problema com Update e Insert

Preciso de ajuda! Criei um projeto seguindo as orientações do curso, está tudo funcionando. Mas tenho um pequeno problema, meu Update e Insert precisam de métodos "toMap()" diferentes para funcionarem corretamente. Quando chamo insert com o método toMap(), ele grava o primeiro contato, mas os outros retornam o seguinte erro:

Exception has occurred.
SqfliteDatabaseException (DatabaseException(UNIQUE constraint failed: contatos.id (code 1555)) sql 'INSERT INTO contatos (id, nome, email, imagem) VALUES (?, ?, ?, NULL)' args [0, Dandara, dada@gmail.com]})

Então precisei criar um toMap1() para funcionar.

O projeto completo está em:

https://github.com/diegolg13/contatos1

trecho do arquivo database_helper.dart

//Incluir um objeto contato no banco de dados
Future<int> insertContato(Contato contato) async {

  Database db = await this.database;

  var resultado = await db.insert(contatoTable, contato.toMap1());

  return resultado;
}


  //Atualizar o objeto Contato e salva no banco de dados
  Future<int> updateContato(Contato contato) async {
     var db = await this.database;

    var resultado = 
      await db.update(contatoTable, contato.toMap(), 
      where: '$colId = ?', 
      whereArgs: [contato.id]);

   return resultado;
}

trecho do arquivo contato.dart


Map<String,dynamic> toMap() {
    var map = <String,dynamic> {
      'id':id,
      'nome': nome,
      'email': email,
      'imagem': imagem
    };
    return map;
  }

  Map<String,dynamic> toMap1() {
    var map = <String,dynamic> {
      //'id':id,                
      'nome': nome,
      'email': email,
      'imagem': imagem
    };
    return map;
  }

trecho do arquivo home_page.dart onde decido inserir ou atualizar o contato se ele for diferente de null.

 void _exibeContatoPage({Contato contato}) async {
      final contatoRecebido =  await Navigator.push(context,
        MaterialPageRoute(
          builder: (
            context)=> ContatoPage(contato: contato)
            ), 
        );

        if(contatoRecebido != null){
          if(contato != null )
          { 
             await db.updateContato(contatoRecebido);
          }else{

             await db.insertContato(contatoRecebido);
          }
          _exibeTodosContatos();
        }
    }
3 respostas
solução!

Você tem que retirar o id do comando INSERT, pois é um índice automaticamente gerenciado pelo SGBD .

Assim o comando dever ser mudado:

sql 'INSERT INTO contatos (id, nome, email, imagem) VALUES (?, ?, ?, NULL)' args [0, Dandara, dada@gmail.com]})

passa a ser: sql 'INSERT INTO contatos ( nome, email, imagem) VALUES (?, ?, NULL)' args [ Dandara, dada@gmail.com]})

No meu create talbe:

'CREATE TABLE $contatoTable($colId INTEGER PRIMARY KEY AUTOINCREMENT, '
        '$colNome TEXT, $colEmail TEXT, $colImagem TEXT)');

O AUTOINCREMENT é desnecessário? Já que estou declarando o id como primary key.

No projeto ByteBank do curso temos:

static const String tableSql = 'CREATE TABLE $_tableName('
      '$_id INTEGER PRIMARY KEY, '
      '$_name TEXT, '
      '$_accountNumber INTEGER)';
  static const String _tableName = 'contacts';
  static const String _id = 'id';
  static const String _name = 'name';
  static const String _accountNumber = 'account_number';

O autoincrement é essencial ao banco, apenas tire o id do código que faz inserção.