Neste artigo veremos

  • Criação de banco de dados Firebird;
  • Exemplo de migração de dados.

Qual a finalidade?

  • Descobrir como recuperar os registros de um banco para outro com a estrutura das tabelas totalmente diferente;
  • =Exemplificar, de maneira prática, a solução para diferentes situações complicadas, independente do sistema gerenciador de banco de dados usado.

Quais situações utilizam esses recursos?

Quando se está implantando um novo sistema em um cliente e o mesmo precisa recuperar os dados já cadastrados em seu antigo sistema desenvolvido por terceiros a maior parte das vezes é criar uma aplicação para migração de dados, como fazer isso?

Resumo do DevMan

Como importar os dados de um banco para outro que possui a estrutura das tabelas totalmente diferente? Como inserir as dependências e manter a integridade dos dados? Uma aplicação em Delphi é a solução para a maioria dos problemas encontrados na hora de se importar os registros contidos em um banco de dados que será substituído. Este artigo traz um exercício prático para exemplificar a solução para situações como esta, a se aplicar independente do sistema gerenciador de banco de dados usado.

Nada é mais importante para o usuário de um sistema do que manter o cadastro de seus clientes e outros dados importantes quando se fala em substituir seu sistema. Passamos por esta situação quando desenvolvemos um sistema para um cliente que já possuía um outro sistema desenvolvido por terceiros. O problema na hora de importar os dados é que, como existem muitas maneiras de se modelar tabelas de um banco de dados, e como cada programador pensa de um jeito diferente, as tabelas do banco origem às vezes são bem diferentes do banco destino. Outra situação parecida é a que programadores mais experientes com certeza já passaram: ter que atualizar seu antigo sistema que armazenava dados em uma base de dados ultrapassada (Paradox por exemplo), para um banco de dados mais moderno. Nesse caso, o programador, com mais experiência do que quando criou o antigo sistema, encontra soluções mais elaboradas para estruturar o seu novo banco. A idéia desse artigo, para desenvolvedores iniciantes que certamente passarão por essa situação, é mostrar como criar uma aplicação em Delphi que irá acessar os dois bancos, percorrer registro por registro e inserir no banco destino fazendo todo controle de condições para manter a integridade dos dados.

Um exemplo de estruturas de tabelas diferentes seria:

  • Banco 1: Contém uma tabela para armazenar clientes, outra para fornecedores e outra para funcionários;
  • Banco 2: Contém uma tabela chamada Pessoa, onde são armazenados os vários tipos de cadastros com dados em comum, como por exemplo cliente, fornecedor e funcionário (têm em comum: nome, endereço, telefone, CPF, etc.). Para cada novo registro na tabela Pessoa, deve-se informar o valor verdadeiro ou falso para os campos Cliente, Fornecedor e Funcionario. Essa estrutura evita que uma pessoa que seja cliente e funcionário ao mesmo tempo seja cadastrada mais de uma vez.

No decorrer do artigo será colocada em prática a criação de dois bancos com características do exemplo citado acima. Vamos nos referenciar a eles como sendo respectivamente o banco origem (contém os dados já cadastrados) e o banco destino (receberá a importação dos dados). Ambos os bancos serão criados em Firebird. Na verdade, poderíamos exemplificar com SGBDs (Sistema Gerenciador de Banco de Dados) diferentes, mas o foco do artigo está na estrutura diferente das tabelas. Usando apenas o Firebird tornamos a prática do artigo mais dinâmica. Além do mais, todo o controle de importação será feito na aplicação, ou seja, não depende do SGBD.

Após a criação dos bancos, o próximo passo será a aplicação. Nesta, iremos primeiramente adicionar um formulário simples para inserir alguns cadastros no banco origem. Em seguida, outro formulário irá controlar todo o processo de importação dos dados, analisando as condições e inserindo os dados através de DataSet´s.

Criando a origem

Criaremos primeiramente um banco de dados simples para usar de exemplo para a origem dos dados que queremos importar. Este terá apenas as tabelas Cliente, Dependente, Fornecedor e Funcionario. Sugiro que o banco seja criado em Firebird 2.0 e com a ferramenta IBExpert para execução dos scripts, mas como já foi dito, o SGDB fica a critério de cada um. A Listagem 1 mostra o script para criação do banco de dados origem.

A Listagem 2 traz um script opcional onde, para cada tabela, é criado um genaretor (Gen_Cliente_Id, Gen_Dependente_Id, etc.) e um trigger (T_Cliente_Bi, T_Dependente_Bi, etc.). O objetivo é gerar automaticamente o código da chave primária de cada tabela. Os triggers sempre serão disparados antes da confirmação de uma inserção (Active Before Insert) e irão atribuir a chave primária para a tabela respectiva, retornando o valor do generator.

Listagem 1. Script de criação do banco de dados origem

CREATE DATABASE 'C:\SISTEMAS\BANCOS\ORIGEM.FDB'
  CREATE TABLE CLIENTE (
      CLI_CODIGO INTEGER NOT NULL,
      CLI_NOME VARCHAR(70) NOT NULL,
      CLI_PESSOA_FJ CHAR(1) NOT NULL,
      CLI_CPF_CNPJ VARCHAR(20) NOT NULL,
      CLI_ENDERECO1 VARCHAR(70),
      CLI_NUM_END1 VARCHAR(10),
      CLI_BAIRRO1 VARCHAR(40),
      CLI_CEP1 CHAR(10),
      CLI_CIDADE1 VARCHAR(40),
      CLI_UF1 CHAR(2),
      CLI_ENDERECO2 VARCHAR(70),
      CLI_NUM_END2 VARCHAR(10),
      CLI_BAIRRO2 VARCHAR(40),
      CLI_CEP2 CHAR(10),
      CLI_CIDADE2 VARCHAR(40),
      CLI_UF2 CHAR(2));
  ALTER TABLE CLIENTE ADD CONSTRAINT PK_CLIENTE PRIMARY KEY (CLI_CODIGO);
  CREATE GENERATOR GEN_CLIENTE_ID;
  CREATE TRIGGER T_CLIENTE_BI FOR CLIENTE ACTIVE BEFORE INSERT POSITION 0
  AS
  BEGIN
    IF (NEW.CLI_CODIGO IS NULL) THEN
      NEW.CLI_CODIGO = GEN_ID(GEN_CLIENTE_ID,1);
  END
  ;
  CREATE TABLE DEPENDENTE (
      DEP_CODIGO     INTEGER NOT NULL,
      CLI_CODIGO     INTEGER NOT NULL,
      DEP_NOME       VARCHAR(70) NOT NULL,
      DEP_DATA_NASCIMENTO DATE
  );
  ALTER TABLE DEPENDENTE ADD CONSTRAINT PK_DEPENDENTE PRIMARY KEY (DEP_CODIGO)
    USING INDEX PK_DEPENDENTE; 
  ALTER TABLE DEPENDENTE ADD CONSTRAINT FK_DEP_CLIENTE FOREIGN KEY (CLI_CODIGO)
    REFERENCES CLIENTE(CLI_CODIGO)USING INDEX FK_DEP_CLIENTE;
  CREATE GENERATOR GEN_DEPENDENTE_ID;
  CREATE TRIGGER T_DEPENDENTE_BI FOR DEPENDENTE ACTIVE BEFORE INSERT POSITION 0
  AS
  BEGIN
    IF (NEW.DEP_CODIGO IS NULL) THEN
      NEW.DEP_CODIGO = GEN_ID(GEN_DEPENDENTE_ID,1);
  END
  ;
  CREATE TABLE FORNECEDOR (
      FOR_CODIGO INTEGER NOT NULL,
      FOR_NOME VARCHAR(70) NOT NULL,
      FOR_PESSOA_FJ CHAR(1) NOT NULL,
      FOR_CPF VARCHAR(20) NOT NULL,
      FOR_ENDERECO VARCHAR(70),
      FOR_NUM_END VARCHAR(10),
      FOR_BAIRRO VARCHAR(40),
      FOR_CEP CHAR(10),
      FOR_CIDADE VARCHAR(40),
      FOR_UF CHAR(2)
 );
  ALTER TABLE FORNECEDOR ADD CONSTRAINT PK_FORNECEDOR PRIMARY KEY (FOR_CODIGO);
  CREATE GENERATOR GEN_FORNECEDOR_ID;
  CREATE TRIGGER T_FORNECEDOR_BI FOR FORNECEDOR ACTIVE BEFORE INSERT POSITION 0
  AS
  BEGIN
    IF (NEW.FOR_CODIGO IS NULL) THEN
      NEW.FOR_CODIGO = GEN_ID(GEN_FORNECEDOR_ID,1);
  END
  ;
  CREATE TABLE FUNCIONARIO (
      FUN_CODIGO INTEGER NOT NULL,
      FUN_NOME VARCHAR(70) NOT NULL,
      FUN_CPF VARCHAR(11) NOT NULL,
      FUN_ENDERECO VARCHAR(70),
      FUN_NUM_END VARCHAR(10),
      FUN_BAIRRO VARCHAR(40),
      FUN_CEP CHAR(10),
      FUN_CIDADE VARCHAR(40),
      FUN_UF CHAR(2),
      FUN_CARGO VARCHAR(40),
      FUN_SALARIO NUMERIC(12,2)
 );
  ALTER TABLE FUNCIONARIO ADD CONSTRAINT PK_FUNCIONRIO PRIMARY KEY (FUN_CODIGO);
  CREATE GENERATOR GEN_FUNCIONARIO_ID;
  CREATE TRIGGER T_FUNCIONARIO_BI FOR FUNCIONARIO ACTIVE BEFORE INSERT POSITION 0
  AS
  BEGIN
    IF (NEW.FUN_CODIGO IS NULL) THEN
      NEW.FUN_CODIGO = GEN_ID(GEN_FUNCIONARIO_ID,1);
  END
  ;

Listagem 2. Script opcional para criação de triggers no banco de dados origem

CREATE GENERATOR GEN_CLIENTE_ID;
  CREATE GENERATOR GEN_DEPENDENTE_ID;
  CREATE GENERATOR GEN_FORNECEDOR_ID;
  CREATE GENERATOR GEN_FUNCIONARIO_ID;
  CREATE TRIGGER T_CLIENTE_BI FOR CLIENTE
  ACTIVE BEFORE INSERT POSITION 0
  AS
  BEGIN
    IF (NEW.CLI_CODIGO IS NULL) THEN
      NEW.CLI_CODIGO = GEN_ID(GEN_CLIENTE_ID,1);
  END;
  CREATE TRIGGER T_DEPENDENTE_BI FOR DEPENDENTE
  ACTIVE BEFORE INSERT POSITION 0
  AS
  BEGIN
    IF (NEW.DEP_CODIGO IS NULL) THEN
      NEW.DEP_CODIGO = GEN_ID(GEN_DEPENDENTE_ID,1);
  END;
  CREATE TRIGGER T_FORNECEDOR_BI FOR FORNECEDOR
  ACTIVE BEFORE INSERT POSITION 0
  AS
  BEGIN
    IF (NEW.FOR_CODIGO IS NULL) THEN
      NEW.FOR_CODIGO = GEN_ID(GEN_FORNECEDOR_ID,1);
  END;
  CREATE TRIGGER T_FUNCIONARIO_BI FOR FUNCIONARIO
  ACTIVE BEFORE INSERT POSITION 0
  AS
  BEGIN
    IF (NEW.FUN_CODIGO IS NULL) THEN
      NEW.FUN_CODIGO = GEN_ID(GEN_FUNCIONARIO_ID,1);
  END; ... 

Quer ler esse conteúdo completo? Tenha acesso completo