Construção de Aplicações de Acesso a Banco de Dados Parte II (Relação Mestre/Detalhe)

Documentos relacionados
Construção de Aplicações de Acesso a Banco de Dados Parte I (Cadastro Simples)

Manual. Portal de Seminovos

PLANO DE SAÚDE LANÇAMENTO COLETIVO

Lançamentos Protocolados

Manual. Portal de Seminovos

Laboratório Configuração do Backup e da Restauração de Dados no Windows 8

SIE - SISTEMA DE INFORMAÇÕES PARA O ENSINO USUÁRIOS AUXÍLIO TRANSPORTE

Tutorial para utilização do módulo de estágio

Lista de Preço Calculada Cálculo do Valor de Custo. Sumário

Habilitar ou desabilitar macros em arquivos do Office. Habilitar macros quando a Barra de Mensagens for exibida

Técni n c i as e L i L n i g n u g age g ns n p ara r Ba B nc n o d e D ados I ACCESS

Boletim Técnico Gestão por Quadrantes Produto Processo Subprocesso Data publicação Desenvolvimento/Procedimento 1 Cadastro

Banco de Dados. -Aprendendo conceitos -Usando o SQL Conf para: -Conectar no banco de dados -Criar, alterar, excluir e consultar estruturas de tabelas

RECURSOS HUMANOS. Pagamentos. Lançamentos de verbas

Tutorial: como funciona o SysBackup

Manual do Usuário. MedLink Dental

TRABALHO FINAL 20 Pontos

Manual do Usuário. MedLink Dental

Processo de Controle

Futura Loja Virtual

Laboratório Configuração do Backup e da Restauração de Dados no Windows 7 e no Vista

Universidade Federal do Pampa Núcleo de Tecnologia da Informação e Comunicação - NTIC 10/09/2013

MANUAL. Certificado de Origem Digital PERFIL PRODUTOR. Versão

SISTEMA ADM ERP - MANUAL DO USUÁRIO. Conceitos Básicos

Stored Procedures e Triggers

Proposta para geração de Cadernos

Conciliação de Movimento / Extrato bancário

Cordilheira Sistema Contábil 2.85a Conciliação Contábil

xchekplus Manual do Usuário

Triggers(Gatilhos) Tiago Alves de Oliveira

AUTOLAC VERSÃO FINALIZAÇÃO: 27 JUL PUBLICAÇÃO: 31 JUL. 2017

Primeiro Trabalho Prático Projeto de Software - CI /1 Prof. Andrey Pimentel

Manual de Utilização do PWAP Android

Linguagem de Programação II Professor: Luiz Claudio Ferreira de Souza Assunto: Linguagem Pascal (Ambiente Lazarus) com Banco de Dados

Tutorial Prestação de Contas. Escolas

Cadastro de Títulos Públicos. Manual do Usuário. Treinamento Fase 1 (TRN 01)

Contribuinte que não possui o evento R.1000 no sistema Escrita Fiscal, mas já realizou a entrega pelo E-cac, deverá:

TAXAS E TARIFAS BOVESPA

Título: Configuração para emissão das Certidões Negativas de Débito - CND.

Banco de Dados I Introdução SQL

NOVIDADES/MELHORIAS ERP SOLUTION. Versão

Executar uma macro clicando em um botão da Barra de Ferramentas de Acesso Rápido

Tutorial para inclusão de unidade de ensino

A U L A 1 0 C R I A N D O V I E W S V I E W S ( V I S Õ E S )

Linguagem de Programação II Professor: Luiz Claudio Ferreira de Souza Assunto: Linguagem Pascal (Ambiente Lazarus) com Banco de Dados

Manual de utilização Zeus Direto

A JL tem uma super novidade. para sua empresa!!!!

5 Busca Tratamento das Palavras-Chave de Entrada

RESUMO DE AULAS PC1 ETEC TAQUARITUBA 2 SEM 2011

Manual -Sistema de Cadastro. Dúvidas? (83)

Refinamentos sucessivos

Instituto Federal de Educação, Ciência e Tecnologia de São Paulo - IFSP

Manual de Utilização (Fluxo)

MANUAL DE UTILIZAÇÃO PERFIL CONTRIBUINTE

Sistema SIEC Manual Operacional

Manual do Gerência do Cliente Resultados de Exames

C A P I T U L O 10 F U N Ç Õ E S I N T E R N A S P H P P A R A B A N C O D E D A D O S

1 Versões do documento O que se entende por Referências do Fornecedor Configuração das funções organizacionais...

SAGUI : MÓDULO RESERVA DE SALAS. ~~~~~ Gestor do Módulo Reserva de Salas ~~~~~

Processo: Compras. Acesso. Motivação. Parâmetros. Nome do Processo: Cotação de compras. Pendências Versão 2009 Release 2 Autor Francisca

S U B G R U P O S D M L E D Q L : A L T E R A N D O E A P A G A N D O D A D O S E M U M A T A B E L A

MANUAL OPERACIONAL (abril/2018)

Inserção de Dados no banco de Dados através dos componentes Combobox, Radio e Checkbox

Pesquisa de Satisfação - MicrovixERP. Visão Geral sobre o tutorial Pesquisa de Satisfação

Manual de Utilização do Cadastro de Beneficiários Integrado - CBI

FastCube 2.0 Programmer Manual

Liberação de Atualização 4.8

CONFIGURAÇÕES DAS LISTAS

Cadastro de Futura Ponto - FP07.2

Alterações liberadas na semana 27/07 a 31/07

2015 GVDASA Sistemas Protocolo 2

Portal de Cotação da FCC S.A.

PORTAL DE TERCEIROS PRESTADORES DE SERVIÇOS

Versão 8.3A-01. Versão Final da Apostila de Novidades

Manual Busca XML Contador

PROCEDIMENTOS SAESP II - NOVO PROCESSO DE DIETA ESPECIAL CADASTRO DE DIETA ESPECIAL E CONSULTA DE DIETAS ESPECIAIS CADASTRADAS PERFIL ESCOLA

INSTITUTO DE PREVIDÊNCIA E ASSISTÊNCIA DOS SERVIDORES MUNICIPAIS DE GRAVATAÍ /RS

1 SOLUÇÕES & SERVIÇOS

MANUAL DE EMISSÃO DE MDF-e VERSÃO 3.0

2013 GVDASA Sistemas Protocolo 2

Manual de Utilização do Sistema de Controle de BM da Priner

Preparação. Linguagem de Manipulação de Dados (DML) Estudo Dirigido 10/12/2013

LEANDRO REIS BENTO SIS VENDA

TransactionCentre - Client.exe Estabelecimento - Funções Administrativas

PROCEDIMENTOS ARMAZENADOS (Stored Procedures)

MANUAL. Certificado de Origem Digital PERFIL EXPORTADOR. Versão

TOTVS Manual do Usuário Intellector Portal

Release Notes SUPRI Liberada em 01/03/2016 Página 1

COMO CRIAR PEDIDOS A PARTIR DA CESTA DE PRODUTOS

MANUAL DO USUÁRIO Cadastros Básicos

MYSQL - PRIMEIROS COMANDOS CRIAÇÃCO DO BD E DAS TABELAS, INSERÇÃO E CONSULTA DE REGISTROS. create database [if not exists] <nome>

Conciliação de Movimentos Contábeis

TUTORIAL ACERTO DE COMISSÕES

Orientações Básicas para Análise e Tramitação de Projetos de Pesquisa pela Plataforma Brasil pelos Comitês de Ética em Pesquisa

Addon 2ª via de Pagamentos v1.7

BANCO DE DADOS GERENCIAL 1 A U L A 2

MANUAL DE UTILIZAÇÃO DO SISTEMA LUX NF-E V

CONTEXTO DO MANUAL Esse manual apresenta o processo de Plano de Trabalho Docente no SIGA.

Manual de Instruções MEDTISS

Transcrição:

79 Universidade Federal de Santa Maria Anexo II Construção de Aplicações de Acesso a Banco de Dados Parte II (Relação Mestre/Detalhe) O objetivo deste material é demonstrar possíveis códigos (enxutos e seguros) para realizar operações de acesso/manutenção em uma tabela resultante de um relacionamento NxN (muitos para muitos) utilizando componentes DataWare (componentes que representam automaticamente informações contidas em uma origem de dados). Nas aplicações este tipo de relação (NxN) é normalmente denominado de relação Mestre/Detalhe. Neste tipo de relação os dados exibidos na tabela Detalhe são dependentes dos dados exibidos na tabela Mestre. Para exemplificar essa relação vamos utilizar uma tabela resultante da relação Receitas e Ingredientes (uma receita pode conter muitos ingredientes e um ingrediente pode estar contido em muitas receitas). O modelo de dados utilizado neste exemplo utiliza três tabelas relacionadas da seguinte forma: CREATE TABLE RECEITAS ( ID_RECEITA INTEGER NOT NULL, NOME VARCHAR(100) NOT NULL, ORIGEM VARCHAR(100), TIPO_RECEITA CHAR(1) NOT NULL, TEMPO_PREPARO DECIMAL(5,2), MODO_PREPARO BLOB SUB_TYPE 1, FOTO BLOB SUB_TYPE 0 ); CREATE TABLE INGREDIENTES_RECEITA ( ID_RECEITA INTEGER NOT NULL, ID_INGREDIENTE INTEGER NOT NULL, QUANTIDADE DECIMAL(5,2) NOT NULL ); CREATE TABLE INGREDIENTES ( ID_INGREDIENTE INTEGER NOT NULL, DESCRICAO VARCHAR(100) NOT NULL, UNIDADE CHAR(3) NOT NULL ); A relação mestre/detalhe pode se dar por qualquer uma das tabelas relacionadas. Por exemplo, no cadastro de receitas podem-se exibir todos os seus ingredientes (neste caso a tabela mestre é a tabela Receitas e a tabela detalhe é a tabela Ingredientes_Receita). Essa relação também seria válida no cadastro de Ingredientes, ou seja, exibir todas as receitas onde determinado ingrediente é utilizado (neste caso a tabela mestre é a tabela Ingredientes e a tabela detalhe é a tabela Ingredientes_Receita). Independente de quem seja a tabela mestre, a tabela detalhe sempre será aquela que representa o relacionamento NxN. Observe na figura abaixo uma relação de dependência entre Receitas e IngredientesReceita Caderno Didático Lazarus IDE Página 79

80 Universidade Federal de Santa Maria Em uma aplicação com uma relação mestre/detalhe, os códigos discutidos no Anexo I (Cadastro Simples) sofrerão algumas alterações (agora será necessário executar operações e controlar mais de uma tabela). Para fazer a demonstração será utilizada uma janela de manutenção semelhante à figura abaixo com o devido tratamento dos eventos que possam ocorrer objetivando um código simples que possa funcionar para qualquer tela de cadastro com características semelhantes. De forma a organizar o código, um componente ActionList será utilizado com a criação e implementação 3 novas ações (actincluirdetalhe, actsalvardetalhe, actexcluirdetalhe) além daquelas sete já discutidas anteriormente actnovo, actlocalizar, actsalvar, actcancelar, actexcluir, actsair, actlocalizarpordescricao). Edit DBEdit (ParentColor = true, ReadOnly = true) GroupBox para agrupar todas os campos da tabela detalhe e suas relações. DBGrid para listar as informações da tabela detalhe evitando a necessidade de mecanismos para pesquisa (o usuário clica sobre o registro que deseja fazer manutenção) Três novas ações para permitir a manutenção nas informações da tabela Detalhe. Relacionamento Mestre/Detalhe entre dois componentes SQLQuery O relacionamento de dependência (mestre/detalhe) entre duas consultas é realizado por meio de dois procedimentos: Inclusão de uma condição na SQLQuery da tabela Detalhe: a propriedade SQL da tabela detalhe deve ser alterada de forma a conter uma condição na cláusula WHERE que filtre os dados da tabela detalhe de acordo com o registro selecionado na tabela mestre. A condição de filtro da tabela detalhe deve-se utilizar de um campo obrigatoriamente existente na tabela mestre (geralmente o campo chave), precedido do sinal de ":" (dois pontos); Alterar a propriedade DataSource da SQLQuery Detalhe indicando o DataSource da SQLQuery Mestre. Caderno Didático Lazarus IDE Página 80

81 Universidade Federal de Santa Maria A figura a seguir ilustra as alterações necessárias para ativar uma relação mestre/detalhe entre dois componentes SQLQuery: Com essa relação configurada, quando a tabela MESTRE está ativa a tabela DETALHE se comporta exibindo somente os registros que fazem referência ao registro atual da tabela MESTRE. Em outras palavras, o comando SQL da SQLQueryDetalhe é alterado de forma a substituir o valor do parâmetro :ID_RECEITA pelo valor contido no campo de mesmo nome (ID_RECEITA) da SQLQueryMestre. Abertura e Fechamento de Consultas Os procedimentos AbrirConsultas() e FecharConsultas() desenvolvidos no Anexo I (Cadastro Simples) precisarão ser alterados para ativar e desativar os dados da tabela detalhe e eventualmente tabelas relacionadas a ela. procedure AbrirConsultas(); //Se a transação não está ativa então inicia ela if not SQLTransaction.Active then SQLTransaction.StartTransaction;... //Restante do código discutido no Anexo I //Se a tabela detalhe e suas tabelas relacionadas não estão ativas então devem ser ativadas if not TabelaRelacionadaComDetalhe.Active then TabelaRelacionadaComDetalhe.Open; if not TabelaDetalhe.Active then TabelaDetalhe.Open; //se a tabela não está ativa então a ative if not TabelaMestre.Active then TabelaMestre.Open; procedure FecharConsultas(); //se as tabelas relacionadas estão ativas então as mesmas devem ser fechadas... //Restante do código discutido no Anexo I //Se a tabela detalhe e suas tabelas relacionadas estão ativas então devem ser fechadas if TabelaDetalhe.Active then TabelaDetalhe.Close; if TabelaRelacionadaComDetalhe.Active then TabelaRelacionadaComDetalhe.Close; //se a tabela está ativa então ela deve ser encerrada if TabelaMestre.Active then TabelaMestre.Close; //se a transação estiver ativa a mesma deve ser encerrada if SQLTransaction.Active then SQLTransaction.EndTransaction; Caderno Didático Lazarus IDE Página 81

82 Universidade Federal de Santa Maria Mantendo as tabelas (mestre e detalhe) com o mesmo estado O código a seguir demonstra como sincronizar o estado da tabela mestre e da tabela detalhe. Sempre que a tabela mestre estiver ativa a tabela detalhe deve ser ativada e sempre que a tabela mestre estiver inativa então a tabela detalhe deve ser inativada. Essa alteração será feita no procedimento HabilitarDesabilitarControles que também será alterado para habilitar e/ou desabilitar o GroupBox onde estão os controles da tabela detalhe. procedure HabilitarDesabilitarControles;... //Código que habilita e desabilita os controles visuais //de acordo com o status da tabela mestre //sincronização da situação da tabela detalhe em função da situação da tabela mestre TabelaDetalhe.Active:=TabelaMestre.Active; //Se a tabela mestre estiver em status de inserção ou edição então os controles da //tabela detalhe devem ficar desabilitados caso contrario os controles devem ser //habilitados se a tabela detalhe estiver ativa ou desabilitados se estiver fechada if TabelaMestre.State = dsinsert then GroupBoxDadosTabelaDetalhe.Enabled := false else GroupBoxDadosTabelaDetalhe.Enabled := TabelaDetalhe.Active; //Se a tabela detalhe está ativa e não contém nenhum registro (está vazia) então //a ação de gravação da tabela detalhe deverá ficar desabilitada if TabelaDetalhe.Active and TabelaDetalhe.IsEmpty then actsalvardetalhe.enabled := false; Inclusão de um novo registro na tabela Datalhe (ação actincluirdetalhe) A inclusão de um registro na tabela detalhe ocorre normalmente através do método insert e deve atribuir ao campo que representa a relação entre as tabelas o valor da tabela mestre. Também é valido verificar se o status da tabela detalhe já não é de inclusão, neste o método insert nem precisa ser executado. Se existirem campos que precisarem ser inicializados ou então componentes que precisam receber o foco este é o momento apropriado para isso. //Se a tabela detalhe estiver ativa if TabelaDetalhe.Active then //Coloca a tabela detalhe em modo de inserção apenas se já não o estiver if TabelaDetalhe.State <> dsinsert then TabelaDetalhe.Insert; //Atribui ao campo que faz a relação entre a tabela mestre e a tabela detalhe //o valor do campo chave da tabela mestre TabelaDetalhe.FieldByName('CampoRelacaoMestreDetalhe').Value := TabelaMestre.FieldByName('CampoChave').value; //Aqui pode-se indicar componentes que receberão o foco e/ou componentes que //precisarão ser inicializados. DBEditDetalheQualquer.SetFocus; DBLkpCmbBxDetalheQualquer.ItemIndex := -1 //Após o usuário clicar no botão que faz a inserção na tabela detalhe então //a ação de salvamento deve ficar habilitada actsalvardetalhe.enabled:=true; Caderno Didático Lazarus IDE Página 82

83 Universidade Federal de Santa Maria Persistência (gravação) do registro atual da tabela detalhe (ação actsalvardetalhe) A gravação das informações da tabela detalhe vai exigir um pouco de atenção. O procedimento de gravação/persistência é simples: o comando Post grava os dados no DataSet, o comando ApplyUpdates envia os dados do DataSet para serem persistidos na base de dados e por último, a ação de Commit da transação vai efetivar os dados e encerrar a transação. Essa última situação é justamente onde se deve prestar mais atenção: quando a transação for encerrada, todos os DataSets ligados a ela serão automaticamente fechados. Isso significa, transpondo a situação para o exemplo dos ingredientes e receitas, que a cada vez que um ingrediente for incluído em uma receita o usuário teria que novamente localizar a receita para fazer uma nova inclusão ou alteração de dados. Para contornar essa situação, a cada vez que os dados da tabela detalhe forem persistidos haverá necessidade de ativar novamente as consultas e posicionar os registros. O código a seguir demonstra como isso pode ser feito: var //variáveis auxiliares para guardar informações do registro que será salvo Chave1, Chave2 : integer; //Chave1 = Chave da tabela mestre, e parte da chave // da tabela detalhe, Chave2 = chave complementar da tabela detalhe if TabelaDetalhe.State in [dsinsert, dsedit] then //Se o status da tabela detalhe for // inserção o edição //Inicia a validação dos campos do cadastro detalhe //(se forem muitos campos recomenda-se a criação de uma subrotina) if Length(Trim(DBEditQualquer.Text)) = 0 then DBEditQualquer.SetFocus; MessageDlg('Uma informação obrigatória não foi informada.', mterror, [mbok], 0); Abort; if DBLkpCmbBxQualquer.ItemIndex = -1 then DBLkpCmbBxQualquer.SetFocus; MessageDlg('Uma informação obrigatória não foi selecionada.', mterror, [mbok], 0); Abort; //Guarda as informações da chave da tabela Detalhe Chave1:= TabelaDetalhe.FieldByName('CAMPO_CHAVE_1_TABELA_DETALHE').asInteger; Chave2:= TabelaDetalhe.FieldByName('CAMPO_CHAVE_2_TABELA_DETALHE').asInteger; try //Inicia o processo de gravação TabelaDetalhe.Post; //Grava os dados no DataSet TabelaDetalhe.ApplyUpdates; //Envia os dados do DataSet para o banco de dados SQLTransaction.Commit; //Efetiva as alterações no BD e encerra a transação except //Se ocorrer um erro on E : Exception do //Mostra uma mensagem de aviso ao usuário MessageDlg('Erro de gravação', 'Não foi possível salvar. Erros: ' + #13 + E.Message, mterror, [mbok],0); SQLTransaction.Rollback; //Cancela a transação AbrirConsultas; //Ativa as consultas //Posiciona a tabela mestre no registro que ela estava antes do salvamento TabelaMestre.Locate('CampoChave', Chave1, []); //Posiciona a tabela detalhe no registro que ela estava antes do salvamento TabelaDetalhe.Locate('CampoChave1;CampoChave2', VarArrayOf([Chave1, Chave2]),[]); //uses variants HabilitarDesabilitarControles; //Atualiza a situação dos controles visuais Caderno Didático Lazarus IDE Página 83

84 Universidade Federal de Santa Maria Exclusão do registro atual na tabela Detalhe (ação actexcluirdetalhe) A exclusão de uma informação na tabela detalhe pressupõe que o usuário esteja posicionado sobre o registro ao qual deseja excluir. Assim como na ação de gravação, a ação de exclusão exigirá que a transação seja encerrada, de forma que será necessário prever uma forma de reposicionar o registro da tabela mestre var chavetbmestre: integer; //Variável auxiliar para guardar a chave da tabela mestre //Se a tabela detalhe está ativa e não estiver vazia (há algo para excluir) if (TabelaDetalhe.Active) and (not TabelaDetalhe.IsEmpty) then //Guarda em uma variável auxiliar o campo da tabela detalhe que faz relação com //a tabela mestre chavetbmestre := TabelaDetalhe.FieldByName('CampoRelacaoMestreDetalhe').asInteger; try //inicia o processo de exclusão TabelaDetalhe.Delete; //Delata o registro no DataSet TabelaDetalhe.ApplyUpdates; //Envia a exclusão para o BD SQLTransaction.Commit; //Efetiva a exclusão no BD except //Se ocorrer um erro on E : Exception do //Mostra uma mensagem de alerta para o usuário MessageDlg('Erro de exclusão', 'Não foi possível excluir o registro. Ocorreram os seguintes erros:' + #13 + E.Message, mterror, [mbok],0); //Desfaz as alterações da transação SQLTransaction.Rollback; AbrirConsultas; //Ativa as consultas //Posiciona a tabela mestre no registro que ela estava antes da exclusão TabelaMestre.Locate('CampoChave', chavetbmestre, []); HabilitarDesabilitarControles; //Atualiza a situação dos controles visuais Caderno Didático Lazarus IDE Página 84