Tutorial: CRUD de Banco de Dados

Este tutorial orienta voce na construcao de uma aplicacao completa de banco de dados com operacoes Create, Read, Update e Delete usando SQLite. Voce conectara a um banco de dados, exibira registros em uma grade TBrowse e os navegara com TDBNavigator.

Passo 1: Criar o Projeto

  1. Crie um novo projeto chamado ContactsDB via Arquivo → Novo Projeto.
  2. Abra main.prg no Editor de Codigo.
  3. Vamos construir um gerenciador de contatos com campos de nome, email e telefone.

Passo 2: Conectar ao SQLite

Arraste um componente TSQLite da aba de paleta Acesso a Dados para o formulario, ou crie no codigo. O componente SQLite do HarbourBuilder gerencia a conexao e execucao de consultas.

#include "hbbuilder.ch"

function Main()

   local oDB, oForm

   // Abrir (ou criar) o arquivo de banco de dados SQLite
   DEFINE SQLITE oDB FILE "contacts.db"

   if .not. oDB:lConnected
      MsgAlert( "Falha ao abrir banco de dados: " + oDB:cError )
      return nil
   endif

   CreateTable( oDB )
   BuildUI( oDB )

return nil
SQLite nao requer servidor

O SQLite armazena todo o banco de dados em um unico arquivo. Isso o torna perfeito para aplicacoes desktop — sem instalacao, sem configuracao, e funciona em todas as plataformas.

Passo 3: Criar a Tabela

Use Execute() para executar uma declaracao CREATE TABLE IF NOT EXISTS. E seguro chamar toda vez que a aplicacao inicia.

static function CreateTable( oDB )

   oDB:Execute( "CREATE TABLE IF NOT EXISTS contacts (" + ;
      "id INTEGER PRIMARY KEY AUTOINCREMENT," + ;
      "name TEXT NOT NULL," + ;
      "email TEXT," + ;
      "phone TEXT" + ;
      ")" )

return nil

Passo 4: Construir a Interface do Usuario

A interface consiste em uma grade TBrowse para exibir registros, campos de entrada para edicao, um TDBNavigator para navegacao de registros e botoes CRUD.

static function BuildUI( oDB )

   local oForm, oBrw, oNav
   local oGetName, oGetEmail, oGetPhone
   local oBtnAdd, oBtnUpdate, oBtnDelete
   local cName := "", cEmail := "", cPhone := ""

   DEFINE FORM oForm TITLE "Gerenciador de Contatos" ;
      SIZE 800, 600 FONT "Segoe UI", 10

   // --- Grade de dados ---
   @ 10, 10 BROWSE oBrw ;
      OF oForm SIZE 760, 300 ;
      HEADERS { "ID", "Nome", "Email", "Telefone" } ;
      WIDTHS  { 50, 200, 250, 150 }

   // --- Barra de navegacao ---
   @ 320, 10 DBNAVIGATOR oNav ;
      OF oForm SIZE 300, 32 ;
      BROWSE oBrw

   // --- Campos de entrada ---
   @ 370, 10 LABEL oLbl1 VALUE "Nome:"   OF oForm SIZE 60, 24
   @ 370, 80 GET oGetName VAR cName     OF oForm SIZE 250, 24

   @ 400, 10 LABEL oLbl2 VALUE "Email:"  OF oForm SIZE 60, 24
   @ 400, 80 GET oGetEmail VAR cEmail   OF oForm SIZE 250, 24

   @ 430, 10 LABEL oLbl3 VALUE "Telefone:"  OF oForm SIZE 60, 24
   @ 430, 80 GET oGetPhone VAR cPhone   OF oForm SIZE 250, 24

   // --- Botoes CRUD ---
   @ 480, 80 BUTTON oBtnAdd PROMPT "Adicionar" ;
      OF oForm SIZE 90, 32 ;
      ACTION DoInsert( oDB, oBrw, oGetName, oGetEmail, oGetPhone )

   @ 480, 180 BUTTON oBtnUpdate PROMPT "Atualizar" ;
      OF oForm SIZE 90, 32 ;
      ACTION DoUpdate( oDB, oBrw, oGetName, oGetEmail, oGetPhone )

   @ 480, 280 BUTTON oBtnDelete PROMPT "Excluir" ;
      OF oForm SIZE 90, 32 ;
      ACTION DoDelete( oDB, oBrw )

   // Carregar dados iniciais
   RefreshBrowse( oDB, oBrw )

   // Quando usuario clicar em uma linha, preencher campos de entrada
   oBrw:OnClick := { || OnRowSelect( oBrw, oGetName, oGetEmail, oGetPhone ) }

   ACTIVATE FORM oForm CENTERED

return nil

Passo 5: Implementar Operacoes CRUD

INSERT — Adicionando um Novo Registro

static function DoInsert( oDB, oBrw, oGetName, oGetEmail, oGetPhone )

   local cName  := oGetName:GetValue()
   local cEmail := oGetEmail:GetValue()
   local cPhone := oGetPhone:GetValue()

   if Empty( cName )
      MsgAlert( "Nome e obrigatorio." )
      return nil
   endif

   oDB:Execute( "INSERT INTO contacts (name, email, phone) VALUES (?, ?, ?)", ;
      { cName, cEmail, cPhone } )

   RefreshBrowse( oDB, oBrw )
   MsgInfo( "Contato adicionado." )

return nil

SELECT — Atualizando a Grade

static function RefreshBrowse( oDB, oBrw )

   local aRows := oDB:QueryToArray( "SELECT id, name, email, phone FROM contacts ORDER BY name" )

   oBrw:SetArray( aRows )
   oBrw:Refresh()

return nil

UPDATE — Modificando o Registro Selecionado

static function DoUpdate( oDB, oBrw, oGetName, oGetEmail, oGetPhone )

   local nId    := oBrw:GetValue( 1 )  // Coluna 1 = id
   local cName  := oGetName:GetValue()
   local cEmail := oGetEmail:GetValue()
   local cPhone := oGetPhone:GetValue()

   if nId == 0
      MsgAlert( "Selecione um contato primeiro." )
      return nil
   endif

   oDB:Execute( "UPDATE contacts SET name=?, email=?, phone=? WHERE id=?", ;
      { cName, cEmail, cPhone, nId } )

   RefreshBrowse( oDB, oBrw )
   MsgInfo( "Contato atualizado." )

return nil

DELETE — Removendo o Registro Selecionado

static function DoDelete( oDB, oBrw )

   local nId := oBrw:GetValue( 1 )

   if nId == 0
      MsgAlert( "Selecione um contato primeiro." )
      return nil
   endif

   if MsgYesNo( "Excluir este contato?" )
      oDB:Execute( "DELETE FROM contacts WHERE id=?", { nId } )
      RefreshBrowse( oDB, oBrw )
      MsgInfo( "Contato excluido." )
   endif

return nil

Selecao de Linha — Preenchendo Campos de Entrada

static function OnRowSelect( oBrw, oGetName, oGetEmail, oGetPhone )

   oGetName:SetValue(  oBrw:GetValue( 2 ) )
   oGetEmail:SetValue( oBrw:GetValue( 3 ) )
   oGetPhone:SetValue( oBrw:GetValue( 4 ) )

return nil

Passo 6: Usando TDBNavigator

O controle TDBNavigator fornece botoes de navegacao padrao (Primeiro, Anterior, Proximo, Ultimo) que funcionam diretamente com a grade TBrowse. Arraste da paleta Acesso a Dados e defina a propriedade oBrowse para sua instancia TBrowse.

Consultas parametrizadas previnem injecao SQL

Sempre use marcadores ? e passe valores como um array. Nunca concatene entrada do usuario diretamente em strings SQL. O componente SQLite do HarbourBuilder trata o escape automaticamente.

Arquitetura da Aplicacao

graph TD A["Camada de UI
TForm + TBrowse + TGet"] --> B["Manipuladores de Eventos
DoInsert / DoUpdate / DoDelete"] B --> C["Camada de Dados
Componente TSQLite"] C --> D["Arquivo SQLite
contacts.db"] D --> C C --> B B --> E["RefreshBrowse
QueryToArray + SetArray"] E --> A style A fill:#58a6ff,stroke:#388bfd,color:#0d1117 style B fill:#d2a8ff,stroke:#bc8cff,color:#0d1117 style C fill:#3fb950,stroke:#2ea043,color:#0d1117 style D fill:#f0883e,stroke:#d18616,color:#0d1117
Proximo passo

Pronto para servir dados via HTTP? Continue para o tutorial Servidor Web para construir uma aplicacao web junto com sua aplicacao desktop.

Nesta Página

Primeiros Passos Paleta de Componentes Recursos da IDE Tutoriais Referencia Plataformas Passo 1: Criar o Projeto Passo 2: Conectar ao SQLite Passo 3: Criar a Tabela Passo 4: Construir a Interface do Usuario Passo 5: Implementar Operacoes CRUD INSERT — Adicionando um Novo Registro SELECT — Atualizando a Grade UPDATE — Modificando o Registro Selecionado DELETE — Removendo o Registro Selecionado Selecao de Linha — Preenchendo Campos de Entrada Passo 6: Usando TDBNavigator Arquitetura da Aplicacao