SQL Modelagem de dados com
Transcrição
SQL Modelagem de dados com
ANUNCIO Índice 06 12 22 34 42 48 SQL News Novas tecnologias, atualizações, lançamentos de produtos,eventos e livros. 08 Guia Rápido da SQL 18 Modelagem de dados com ErWin 26 Conctando Front-Ends 39 MySQL 44 Replicação de dados Explorando os princupais recursos do comando SELECT. Otimização de comandos SQL Conceitos e diretrizes para aumento da performance na execução de comandos SQL. Uma introdução aos recursos e utilização desta ferramenta. Introdução a UML Definição, implementação e utilizção de um modelo usando UML Exemplos práticos para o acesso a banco de dados com diversas ferramentas. Emacs SQL Utilizando o Emacs para acesso e manutenção de bancos de dados. Instalação, overview dos recursos e utlilização do MySQL no linux. PostgreSQL Uma análise dos recursos do postgre e vantagens de sua distribuição nacional. Teoria e prática envolvendo replicação de dados no SQL Server. JDataStore Conhecendo o banco de dados e uma entrevista com Sergio Cardoso. SQL Magazine - 3 EDITORIAL Coordenador Editorial Gladstone Matos [email protected] Editor Geral Gustavo Viegas [email protected] Equipe Editorial Cristina Viegas Edgar Silva Fábio Faldini Gisele Nichols Pedro Henrique dos Santos Acessora de Imprensa Kaline Dolabela [email protected] Contribuíram nesta edição Clementino Leal, Cleison Santos, Everson Ramos, Edgar Silva, Fábio Faldini, Gustavo Viegas, Gisele Nichols, Gladstone Matos, Paulo Ribeiro, Pedro Henrique Editor de Arte Vinicius O. Andrade [email protected] Capa Mauro Lassance [email protected] Gerente Geral Rosângela Matos [email protected] Publicidade Julio César Lopes [email protected] Jornalista Resposável Sérgio Moraes C. Brandão MTb: 15183-68-148 Impressão Ediouro Gráfica e Editora S/A Atendimento ao Leitor [email protected] Assinaturas [email protected] Colaboração de Artigos [email protected] Na Web www.sqlmagazine.com.br Distribuição Fernando Chinaglia Dist. S/A Rua Teodoro da Silva, 907 Grajaú - RJ - CEP: 206563-900 4 - Magazine SQL Atualmente, na medida em que as tecnologias de banco de dados e ferramentas para desenvolvimento de aplicações vem evoluindo, temos um abismo cada vez maior entre o profissional de informática e as áreas de conhecimento fora de sua especialização. Questiono: Até onde deve ir o conhecimento do profissional de tecnologia da informação? Será que a especialização total é o melhor caminho? Seja técnico, desenvolvedor ou analista, a questão é quanto de sua área ele precisa saber para implementar, analisar, projetar e interagir num processo de desenvolvimento e manutenção de uma aplicação? Será que podemos afirmar que um desenvolvedor deve ter somente conhecimentos profundos de uma determinada ferramenta de desenvolvimento e, no caso de uma aplicação que acesse um banco de dados, não ter a mínima noção deste banco? Ou ainda: um DBA que tem a responsabilidade de instalar, configurar, dimensionar, criar os objetos de um modelo, garantir uma boa performance, entre outras, não faria suas tarefas de modo mais consciente sabendo um pouco sobre como os dados serão acessados e manipulados? Podemos citar ainda aqueles que participam das definições de um projeto, lá no estágio embrionário do sistema. Para estes, o conhecimento do banco de dados, das tecnologias e ferramentas utilizadas para desenvolvimento, afetariam na definição do projeto a ponto de facilitar sua implementação e futura manutenção? Como disse, o abismo que separa o conhecimento entre cada profissional de informática tem se mostrado crescente, e isso, de certa forma, não é bom. A SQL Magazine chega até você com o objetivo de trazer informações sobre o “mundo” dos bancos de dados, tecnologias e ferramentas de desenvolvimento. Temos uma árdua tarefa diante dos leitores: diminuir o abismo citado, através da publicação de artigos de “base”, fomentando o conhecimento daqueles que ainda não lidam com o assunto, artigos técnicos, para os que já utilizam algum tipo de SGBD e artigos avançados, voltados para DBA´s. Além de novidades, previews, cursos e dicas. Espero que você encontre na SQL Magazine informações para o seu crescimento profissional, tomada de decisão, auxílio na solução de problemas, base para definição de projetos independente do seu papel nos mesmos e acima de tudo: uma fonte de consultas e mais consultas. Boa leitura. Gustavo Viegas Editor [email protected] ANUNCIO SQL Magazine - 5 Usando UML Com .NET Através do Rational XDE ( eXtended Development Environment ) Professional v2002 você pode ter na IDE do Visual Studio o ambiente nescessário para analisar, implementar e documentar suas soluções baseadas no .Net FrameWork utilizando UML. Esta integração é extremamente útil para implementação de sistemas complexo utilizando C#. O XDE suporta os principais diagramas UML, possibilita a utilização de vários Design Patterns além de facilitar a implementação de Design Patterns próprios. Consulte www.rational.com <http://www. rational.com> para um overview do produto. Application Server da Oracle oferece business intelligence incorporado SQL News Integrado ao servidor de aplicação, o Oracle9i Application Server proporciona todo o middleware necessário para uma eficiente comunicação de dados em e-business. Com um único produto é possível executar diversas aplicações (Java, portal, integração de aplicativos, wireless e outras). Foram efetuadas customizações que otimizam o processo de configuração de backup e recovery, gerenciamento automático de backups e logs arquivados, backups e restaurações reiniciáveis e restauração/recuperação de teste. O SQL e o PL/SQL receberam outras melhorias no Oracle9iAS. Foi adicionada depuração no lado servidor para múltiplas linguagens, permitindo que os ambientes de desenvolvimento integrado (IDEs) depurem tanto Java quanto PL/SQL dentro da mesma estrutura. Mais informações em www.oracle.com.br. Cresce a competição entre os bancos de dados da IBM, Microsoft, e Oracle Enquanto a Microsoft fala de futuras implementações no SQL Server, a Big Blue disponibiliza a versão DB2 8.1 UDB. Nesta última versão, a IBM está tentando tornar o seu banco de dados mais fácil de ser utilizado, distribuído, e administrado. Implementações que aumentam a performance na execução de queryes e capacidades autônomas estão entre as novidades do DB2 8.1. A Microsoft anunciou a versão 64-bit do SQL Server (Beta) e espera conquistar maior confiança dos usuários de banco de dados. A Oracle, por sua vez, utilizou a OracleWorld User Conference em San Francisco para mostrar detalhes do seu novo banco de dados, chamado até então de 10i e previsto para lançamento em meados de 2003. Apesar do nome final do produto não estar definido, a Oracle falou oficialmente que a nova versão terá seu foco no gerenciamento, aumento da capacidade, e novo suporte para XML e Web services. Computador que se conserta sozinho A IBM está desenvolvendo sistemas que se consertam sozinhos e necessitam de menos intervenção humana. Para isso, criou a divisão Autonomic Computing, cuja meta é fazer com que os computadores sejam autônomos de maneira semelhante ao comportamento do sistema nervoso humano, que permite adaptar-se às mudanças à sua volta, a defender-se de ataques externos e a recuperar-se de falhas internas. As capacidades autônomas estarão incluídas inclusive no banco de dados DB2. A idéia é permitir que os computadores dêem conselhos sobre seu melhor rendimento e, então, permitir que esses sistemas executem os conselhos sem o aval dos técnicos. Oracle9i nas eleições Mais de 185 milhões de votos foram processados no primeiro e segundo turnos das eleições pelo Tribunal Superior Eleitoral. Em menos de 24 horas, os brasileiros já sabiam o resultado dos 91 milhões de votos apurados na primeira fase. Para realizar tal feito, o TSE utilizou o banco de dados Oracle9i. O sistema, desenvolvido em parceria do TSE com a Oracle, é o mais avançado no segmento. Os dados de todos os Tribunais Regionais Eleitorais, correspondentes aos votos para deputados estaduais e federais, senadores e governadores, são totalizados e somados aos do TSE, que é responsável pela centralização e contagem dos votos para presidente da República. Esse processo permitiu a divulgação imediata dos resultados nos telões de apuração e na Internet. Backups seguros e contínuos A Storageteck, fornecedora de soluções de armazenamento de dados, está colocando no mercado as fitotecas robotizadas L20, L40 e L80, que permitem que os backups sejam feitos continuamente, 24 horas por dia. O produto foi desenvolvido para pequenas e médias empresas cujas plataformas rodam em ambientes NT, Novell, Linux ou Unix. Focados no mercado entry level, as bibliotecas de backup destinam-se a redes com necessidades de armazenamento a partir de 400 GB. Na prática, os produtos da Série L são disponíveis nas versões 2, 4 ou 8 drives, com capacidades de 110 GB a 220 GB cada. IBM DB2 UDB 8.1 para Linux (Beta) A IBM se orgulha do seu compromentimento com o Linux. Desde o seu portal Linux até a campanha ‘Paz, Amor, e Linux’ que foi “grafitada” nas ruas de cidades americanas no ano passado, a companhia tem deixado claro que pretende ser vista na linha de frente do desenvolvimento para este sistema. A versão 8.1 (Beta) do DB2 UDB esta disponível para download no site da “Big Blue” (www.ibm. com/db2/) e a IBM recomenda no mínimo 128Mb de memória e de 250Mb a 350Mb disponíveis em disco para instalação e utilização de um banco de dados de tamanho médio. Uma novidade está no db2setup utility, um utilitário com aparência e operação semelhante a de muitos programas para Windows. Informações adicionais e uma análise do produto estão disponíveis no endereço http://www.newarchitectmag.com/documents/s=7733/na1202m/index.html. Microsoft SQL Server comemora seu 10 º Aniversário A Microsoft Corp. anunciou no dia 20 de novembro o 10º aniversário do Microsoft(R) SQL Server (TM) na Associação de Profissionais de SQL Server (PASS) em Seattle, num grande evento exclusivamente dedicado ao banco. No keynote de abertura, Gordon Mangione, vice presidente corporativo do SQL Server na Microsoft, falou do passado e das futuras implementações no SQL Server como motivos para os muitos clientes e parceiros continuarem a desenvolver utilizando a plataforma Microsoft SQL Server. Com base nas inovações do produto, Mangione anunciou a disponibilização do SQL Server 2000 (64-bit) Beta 2 e do Microsoft SQL Server 2000 Service Pack 3 (SP3) Beta 1. Ele encorajou aos desenvolvedores a utilizarem ambas as versões Beta disponíveis e reforçou o objetivo da Microsoft de desenvolver um conjunto de ferramentas que garantam um alto nível de performance, gerenciamento e escalabilidade. ANUNCIO Oracle 9i - O Manual do DBA Autor: Kevin Loney Editora Campus - 992 páginas. R$ 159 Pertencente à série Oracle Press, cujos livros são guias oficiais da Oracle produzidos por especialistas da própria empresa, este livro oferece uma cobertura completa dos recursos mais recentes e as maneiras de incorporar esses recursos no gerenciamento de um banco de dados Oracle. Com este livro, o leitor aprenderá a implementar as soluções administrativas de especialistas, a manter os seus importantes sistemas da Internet e de comércio eletrônico flexíveis, seguros e disponíveis - tudo com informações exclusivas autorizadas pela Oracle. Este guia abrange todos os pontos importantes sobre Oracle 9i, fornecendo exemplos e técnicas reais. Alguns tópicos: SQL Magazine - 7 Guia rápido da SQL por Gladstone Matos A linguagem SQL é sucinta e ao mesmo tempo poderosa. Através de um idioma de fácil entendimento, a SQL permitiu a padronização na forma de comunicar os aplicativos front-ends com os diversos bancos de dados disponíveis. Neste artigo veremos os principais parâmetros do comando SELECT, a principal forma de recuperar dados através da SQL. COMANDO SELECT A SQL foi criada com o objetivo de padronizar os comandos de manipulação de dados em SGBD’s. Hoje em dia, apesar da linguagem possuir uma quantidade consideráveldeextensõeseimplementações proprietárias, pode-se afirmar que a meta foi alcançada. A maior parte do código SQL escrito nas aplicações se encontra no formato “puro”, conhecido como ANSI. O sucesso da SQL trouxe uma produtividade interessante para a manipulação de banco de dados. Conhecendo bem a linguagem é possível acessar os recursos básicos de qualquer banco relacional, como Oracle, SQL Server ou MySQL, sem praticamente nenhuma mudança. Veremos neste artigo um pequeno guia de referência para os parâmetros do comando SELECT, um dos mais importantes da linguagem SQL. SELECT Simples O comando SELECT permite recuperar os dados de um objeto do banco, como uma tabela, uma view e, em alguns casos, uma stored procedure (alguns bancos de dados permitem a criação de procedimentos que retornam valor). A sintaxe mais básica do comando é: SELECT <LISTA_DE_CAMPOS> FROM <NOME_DA_TABELA> Exemplo: SELECT CODIGO, NOME FROM CLIENTES; SELECT * FROM CLIENTES; O caracter “*” representa todos os campos. Apesar de prática, esta máscara não é muito utilizada, pois, para o SGBD, é mais rápido receber o comando com todos os campos explicitados. O uso do * obriga o servidor a consultar quais são os campos antes de efetuar a busca dos dados, criando mais um “passo” no processo. COMANDO WHERE A cláusula Where permite ao comando SQL passar condições de filtragem, Veja o exemplo: SELECT CODIGO, NOME FROM CLIENTES WHERE CODIGO = 10; SELECT CODIGO, NOME FROM CLIENTES WHERE UF = ‘RJ’ SELECT CODIGO, NOME FROM CLIENTES WHERE CODIGO >= 100 AND CODIGO <=500; SELECT CODIGO, NOME FROM CLIENTES WHERE UF=’MG’ OR UF = ‘SP’ Guia Rápido da SQL Os parênteses, corretamente utilizados, dão mais poder a consulta: A inclusão da palavra DESC garante a ordenação invertida: SELECT CODIGO, NOME FROM CLIENTES WHERE UF = ‘RJ’ OR (UF=’SP’ AND ATIVO=’N’); SELECT CODIGO, NOME FROM CLIENTES ORDER BY NOME DESC Neste comando, todos os clientes do Rio de Janeiro e apenas os clientes inativos de São Paulo seriam capturados. SELECT CODIGO, NOME FROM CLIENTES ORDER BY UF DESC, NOME SELECT CODIGO, NOME FROM CLIENTES WHERE (ENDERECO IS NULL) OR (CIDADE IS NULL) Aqui todos os clientes que não possuem endereco ou cidade cadastrados serão selecionados. FILTRO DE TEXTO SELECT CODIGO, NOME FROM FUNCIONARIO WHERE DEPARTAMENTO=’VENDAS’; SELECT CODIGO FROM CLIENTES WHERE NOME > “K”; Para busca parcial de strings, o SELECT fornece o operador LIKE: SELECT CODIGO, NOME FROM CLIENTES WHERE NOME LIKE “MARIA*”; Neste comando, todos os clientes cujo nome iniciam com Maria serão retornados. Se quisermos retornar os nomes que contenham “MARIA” também no meio, podemos alterar para: SELECT CODIGO, NOME FROM CLIENTES WHERE NOME LIKE “*MARIA*” O uso da máscara no início e no fim da string fornece maior poder de busca, mas causa considerável perda de performance. Este recurso deve ser utilizado com critério. Nota: Em alguns bancos de dados a máscara de fitro não é representada pelo caracter “*”. Consulte a referência do banco utilizado para verificar o caracter correto. Por padrão, a SQL diferencia caixa baixa de caixa alta. Para eliminar essa diferença, utilize a função UPPER: SELECT CODIGO, NOME FROM CLIENTES WHERE UPPER(NOME) LIKE “MARIA*SILVA*” ORDENAÇÃO A ordenação pode ser definida com o comando ORDER BY. Assim como no comando WHERE, o campo de ordenação não precisa estar listado como campo de visualização: SELECT CODIGO, NOME FROM CLIENTES ORDER BY NOME SELECT CODIGO, NOME FROM CLIENTES ORDER BY UF, NOME JUNÇÃO DE TABELAS O SELECT permite juntar duas ou mais tabelas no mesmo resultado. Isso pode ser feito de várias formas: SELECT CLIENTES.CODIGO, CLIENTES.NOME, PEDIDOS.DATA, PEDIDOS.VALOR FROM CLIENTES, PEDIDOS WHERE CLIENTES.CODIGO = PEDIDOS.CODCLIENTE Nesta linha as tabelas relacionadas CLIENTES e PEDIDOS são unificada através do campo chave, em uma operação de igualdade. Repare que o nome dos campos passam a ser prefixados pelo nome das tabelas, resolvendo duplicidades. Uma versão resumida desta comando pode ser: SELECT A.CODIGO, A.NOME, B.DATA, B.VALOR FROM CLIENTES A, PEDIDOS B WHERE A.CODIGO = B.CODCLIENTE O uso de aliases no código SQL torna a manutenção mais simples. No comando abaixo temos várias tabelas unificadas em uma mesma cláusula: SELECT A.CODIGO, A.NOME, B.DATA, B.VALOR, C.QTD, D.DESCRICAO FROM CLIENTES A, PEDIDOS B, ITENS C, PRODUTOS D WHERE A.CODIGO = B.CODCLIENTE AND B.CODIGO = C.CODPEDIDO AND C.CODPRODUTO = D.CODIGO Neste comando unificamos as tabelas relacionadas CLIENTES, PEDIDOS, ITENS e PRODUTOS. Veja mais alguns exemplos: SELECT A.CODIGO, A.NOME, B.DATA, B.VALOR FROM CLIENTES A, PEDIDOS B WHERE A.CODIGO = B.CODCLIENTE AND A.UF= ‘RJ’ SELECT A.CODIGO, A.NOME, B.DATA, B.VALOR FROM CLIENTES A, PEDIDOS B WHERE A.CODIGO = B.CODCLIENTE AND UF = ‘RJ’ OR (UF=’SP’ AND ATIVO=’N’); SELECT A.CODIGO, A.NOME, B.DATA, B.VALOR FROM CLIENTES A, PEDIDOS B WHERE A.CODIGO = B.CODCLIENTE ORDER BY A.UF, A.NOME Observe que a junção através da igualdade de campos traz como resultado somente os registros que possuem referência nas duas tabelas. Observe o comando abaixo: SELECT A.CODIGO, A.DESCRICAO, B.DESCRICAO FROM PRODUTOS A , COMPONENTES B WHERE A.CODIGO = B.CODPRODUTO Os produtos que não possuem componentes não são selecionados. Caso seja necessário criar uma listagem incluindo também os registros que não possuem correspondência, deve-se utilizar o comando JOIN. COMANDO JOIN A junção de tabelas no comando SELECT também pode ser feita com o comando JOIN. Este comando deve ser utilizado com a palavra reservada INNER ou com a palavra OUTER: INNER - Semelhante ao uso do operador “=” na junção de tabelas. Aqui, os registros sem correspondências não são incluídos. Esta cláusula é opcional e pode ser omitida no comando JOIN. OUTER – Os registros que não se relacionam também são exibidos. Neste caso, é possível definir qual tabela será incluída na seleção, mesmo não tendo correspondência. Para exemplificar, temos as tabelas abaixo: Produtos Código Descrição Categoria 1 Martelo 1 2 Chave de Fenda 1 3 Alicate 2 4 Desmagnetizador 2 5 Parafuso <null> Componentes Código Cod.Produto Descrição 1 3 Adaptador CF Qtd 1 2 4 CaboMod A1 2 2 4 CaboMod A2 1 Categoria Código Descrição 1 Ferramenta A1 2 Ferramenta B1 3 Ferramenta C1 4 Ferramenta D1 Observe os exemplos e o resultado produzido: SELECT A.CODIGO, A.DESCRICAO, B.DESCRICAO, B.QTD FROM PRODUTOS A INNER JOIN COMPONENTES B ON (A.CODIGO = B.CODPRODUTO) SQL Magazine - 9 Resultado 1 Cód Descrição FUNÇÕES DE AGRUPAMENTO Resultado 4 Descrição Qtd Cód Descrição Descrição Qtd 1 Alicate Adaptador CF 1 3 Alicate Adaptador CF 1 2 Desmagnetizador CaboMod A1 2 4 Desmagnetizador CaboMod A1 2 3 Desmagnetizador CaboMod A2 1 4 Desmagnetizador CaboMod A2 1 Este comando pode ser escrito na versão resumida abaixo: SELECT A.CODIGO, A.DESCRICAO, B.DESCRICAO FROM PRODUTOS A JOIN COMPONENTES B ON (A.CODIGO = B.CODPRODUTO) Como mostrado no resultado, os produtos que não possuem componentes não são incluídos na seleção. SELECT A.CODIGO, A.DESCRICAO, B.DESCRICAO , B.QTD FROM PRODUTOS A LEFT OUTER JOIN COMPONENTES B ON (A.CODIGO = B.CODPRODUTO) FULL OUTER JOIN Podemos ainda combinar o uso de INNER e OUTER através do comando FULL OUTER JOIN. Neste caso, todos os registros das duas tabelas envolvidas serão exibidos, tendo ou não relacionamento. Observe: SELECT A.CODIGO, A.DESCRICAO, B.DESCRICAO FROM PRODUTOS A FULL OUTER JOIN CATEGORIA B ON ( A.CATEGORIA = B.CODIGO ) ORDER BY A.DESCRICAO Produtos Resultado 2 Qtd Código 1 Martelo 1 1 Martelo Ferramenta A1 2 Chave de Fenda 2 2 Chave de Fenda Ferramenta A1 3 Alicate Adaptador CF 1 3 Alicate Ferramenta B1 4 Desmagnetizador CaboMod A1 4 Desmagnetizador Ferramenta B1 4 Desmagnetizador CaboMod B2 5 Parafuso 5 Parafuso Cód Descrição Descrição Categoria Ferramenta C1 Neste comando todos os produtos serão incluídos na seleção, independente de possuirem um componente. Observe que a palavra LEFT se refere a primeira tabela no relacionamento. O mesmo comando poderia ser descrito na forma: SELECT A.CODIGO, A.DESCRICAO, B.DESCRICAO FROM COMPONENTES A RIGHT OUTER JOIN PRODUTOS B ON ( A.CODIGO = B.CODPRODUTO ) A ordem das tabelas foi invertida, mas o resultado é o mesmo. Observe mais alguns exemplos: SELECT A.CODIGO, A.DESCRICAO, B.DESCRICAO , B.QTD FROM PRODUTOS A JOIN COMPONENTES B ON ( A.CODIGO = B.CODPRODUTO ) WHERE A.CATEGORIA=1 Resultado 3 Cód Descrição Descrição Qtd <vazio> <vazio> <vazio> <vazio> SELECT A.CODIGO, A.DESCRICAO, B.DESCRICAO FROM PRODUTOS A JOIN COMPONENTES B ON (A.CODIGO = B.CODPRODUTO ) WHERE A.CATEGORIA=1 OR A.CATEGORIA=2 ORDER BY A.CATEGORIA, A.DESCRICAO 10 - Magazine Descrição SQL São cinco as funções básicas de agrupamento: AVG: Retorna a média do campo especificado: SELECT AVG(VALOR) FROM PEDIDOS; MIN/MAX/SUM: Respectivamente, retorna o menor valor, o maior e o somatório de um grupo de registros: SELECT MIN(VALOR) FROM PEDIDOS; SELECT MAX(VALOR) FROM PEDIDOS; SELECT AVG(VALOR) FROM PEDIDOS; COUNT: Retorna a quantidade de itens da seleção: SELECT COUNT(CODIGO) FROM CLIENTES; AGRUPAMENTO Um poderoso recurso do comando SELECT é o parâmetro GROUP BY. Através dele podemos retornar informações agrupadas de um conjunto de registros, estabelecendo uma condição de agrupamento. É um recurso muito utilizado na confecção de relatórios. Para exemplificar, temos as tabelas CLIENTES e PEDIDOS: Clientes Ferramenta D1 UNION Existe ainda uma Segunda forma de juntar tabelas com o comando SELECT. Através do parâmetro UNION, é possível “colar” o conteúdo de duas tabelas. Veja o exemplo: SELECT CODIGO, NOME FROM CLIENTES UNION SELECT CODIGO, NOME FROM FUNCIONARIOS O resultado deste comando é a listagem de todos os clientes e a listagem dos funcionários, dentro do mesmo result set. Repare que no comando JOIN a união é horizontal e no UNION a união é vertical. Por default, os registros duplicados são eliminados na cláusula UNION. No exemplo anterior, se tivéssemos um cliente com mesmo nome e código de um funcionário, apenas o registro da primeira tabela seria exibido. Para incluir todos os registros, independente de duplicidade, utilize a palavra ALL: SELECT CODIGO, NOME FROM CLIENTES UNION ALL SELECT CODIGO, NOME FROM FUNCIONARIOS Código Nome 1 Gustavo Viegas 2 Vinicius Andrade 3 Rosangela Mattos Pedidos Código CodCliente Data Valor 1 1 01/10/2002 500 2 1 02/10/2002 100 3 2 01/10/2002 600 4 3 05/01/2002 100 5 3 10/10/2002 300 6 3 11/10/2002 80 SELECT CODCLIENTE, MAX(VALOR) FROM PEDIDOS GROUP BY CODCLIENTE O comando acima retorna o maior valor de pedido de cada cliente. Observe o resultado: Resultado 6 CodCliente MAX (Valor) 1 500 2 600 3 300 Guia Rápido da SQL SELECT CODCLIENTE, COUNT(*) FROM PEDIDOS GROUP BY CODCLIENTE Aqui vemos quantos pedidos foram feitos por cada cliente. Veja o resultado: Resultado 7 CodCliente COUNT(*) 1 2 2 1 3 3 Somente os clientes com 2 ou mais pedidos serão selecionados. Repare que o HAVING é utilizado, geralmente, com alguma função de agrupamento. Para filtros normais, pode-se utilizar o comando WHERE. Observe o exemplo abaixo: SELECT CODCLIENTE, COUNT(*) FROM PEDIDOS WHERE DATA > ‘06/10/2002’ GROUP BY CODCLIENTE HAVING COUNT(*) >= 2 Resultado 9 HAVING Através do comando HAVING podemos filtrar a cláusula GROUP BY. Observe o comando abaixo: SELECT CODCLIENTE, COUNT(*) FROM PEDIDOS GROUP BY CODCLIENTE HAVING COUNT(*) >= 2 CodCliente COUNT(*) 3 2 Repare que o cliente número 3 apresentou apenas dois pedidos, visto que o primeiro não possui data maior que 6/10. Conclusão O uso correto do comando SELECT fornece uma poderosa interface de filtro. Utilizando sempre a sintaxe padrão, o desenvolvedor conta com maior independência de plataforma, pois o SQL ANSI é compreendido pelos principais bancos de dados. Existem ainda funções especiais e funções de conversão, que serão abordados em futuras edições da SQL Magazine. Para maior eficiência no uso do SELECT, é desejável também o bom planejamentos dos índices do banco. Para maiores informações a respeito do uso de índices, leia a matéria de Everson Ramos, publicada nesta edição. Espero que este artigo introdutório sirva de consulta em seus projetos! webSITES ClubeDelphi www.clubedelphi.net/guias/index.asp Resultado 8 CodCliente COUNT(*) 1 2 3 3 NOTA A formatação no uso de campos do tipo DATE pode sofrer alterações de acordo com o banco utilizado. Consulte o manual de referência do mesmo para maiores detalhes. SQLAutor Gladstone Matos é coordenador das revistas ClubeDelphi, Java Magazine e SQL Magazine.. Pode ser contactado através do email: [email protected] ANUNCIO SQL Magazine - 11 Otimização de comandos SQL por Everson Volaco M esmo um aplicativo bem projetado poderá experimentar problemas de desempenho se a frase SQL que usa for mal construída. Falhas no projeto do aplicativo e na construção do SQL causam a maioria dos problemas de desempenho em bancos de dados projetados adequadamente. Veremos neste artigo como melhorar o comando SQL, para garantir maior performance em sua execução, tendo como base o ORACLE. A forma como o banco de dados se or-Index Search: Procura de um índice soganiza para responder a requisição de um bre a coluna definida no critério de seleção, aplicativo é diretamente influenciada pela identificando a localização dos registros maneira como a frase SQL é construída. qualificados. Existem vários pontos a serem observados O ORACLE possui seu próprio mecanesta construção. nismo de otimiO caminho mais chamado “A simples criação de índices nem zação, curto é o uso de ínotimizador, para sempre é o melhor caminho para executar dices para auxiliar a copesquisa mas, é immandos SQL e otimização de comandos SQL” portante observar, dinamicamente a simples criação de determinar que um índice nem sempre é o melhor cami- caminho de acesso seguir, dependendo nho para otimização de comandos SQL. das informações disponíveis. O melhor caminho de acesso é, geralmente, o uso Alguns conceitos importantes de índices, mas isso nem sempre é verdaAntes de partir para como e quais as me- deiro. Por exemplo, se existir uma forma lhores formas de se aplicar e se escrever de identificar diretamente um registro comandos SQL é importante relembrar- pelo seu endereço físico, a resposta será mais rápida. (neste caso estamos falando mos alguns conceitos importantes. Existem dois métodos básicos utilizados do rowid, endereço físico do registro em pelos SGDB´s para localizar dados, tam- uma tabela ORACLE). Ex.: bém conhecidos como caminhos de acesso. São eles: SELECT rowid INTO :emp_rowid FROM EMP -Full Table Scan: Leitura seqüencial, bloWHERE emp.empno = 5353 FOR UPDATE OF emp.ename; co por bloco, de toda a tabela. Neste méUPDATE emp SET emp.ename = “OTIMIZADOR” todo, são verificados registro a registro os WHERE rowid = :emp_rowid; critérios de seleção. Otimização de Comandos SQL Excluindo registros duplicados: DELETE FROM emp e WHERE e.rowid > (SELECT MIN(x.rowid) FROM emp x WHERE x.empno = e.empno); Algumas informações para auxiliar o acesso do otimizador: Verificar nas colunas dentro da cláusula WHERE: - Que colunas são índices; - Que colunas estão definidas como NOT NULL; - Que índices podem ser usados. É possível ajudar o otimizador a procurar o melhor caminho de acesso através da criação de índices e clusters, o que será considerado a partir de agora. Regras de Utilização de Índices Um índice será usado se : - o índice existir; - a coluna índice for referenciada na cláusula WHERE; Um índice pode ser usado para testes de: - Igualdade: SELECT e.empno, e.ename FROM emp e WHERE e.job = ‘CLERK’; - Intervalo ilimitado: SELECT e.empno, e.ename FROM emp e WHERE e.job > ‘CLERK’; - Intervalo limitado: SELECT e.empno, e.ename FROM emp e WHERE e.job BETWEEN ‘CLERK’ AND ‘JONES’; A criação de índices deve ser feita com critério. A atualização (inserts, updates e deletes) em tabelas de dados gera uma ação equivalente nos índices, sendo que o tempo de atualização dos índices é superior ao de atualização da tabelas, pois além da colocação do registro em seqüência dentro do índice é necessário a atualização dos ramos das árvores do índice. Considerando os detalhes acima, índices devem ser criados somente quando necessário, pois a sua simples existência não implica em melhoria de performance, podendo muitas vezes ser a origem de perda de performance. Condições de não utilização de Índices 1) Funções ou Operadores Aritméticos Se a coluna índice for modificada por uma função ou por operadores aritméticos (+,-,*,/), o índice não será utilizado. Um índice sobre SAL ou ENAME não será utilizado nos seguintes casos: SELECT e.ename, e.empno FROM emp e WHERE e.sal*12 = 2400; SELECT e.ename, e.empno FROM emp e WHERE SUBSTR(e.ename,1,3) = ‘JON’ Nos casos acima, as seguintes modificações permitem o uso de índice: SELECT e.ename, e.empno FROM emp e WHERE e.sal = 2400/12 SELECT e.ename, e.empno FROM emp e WHERE e.ename LIKE ‘JON%’ 2) Conversão de Dados A conversão de dados pode inibir a utilização do índice da coluna em questão se usado inadvertidamente. Na seguinte sentença, um índice sobre a coluna HIREDATE não será usado: SELECT e.ename, e.empno FROM emp e WHERE TO_CHAR(e.hiredate, ‘month dd,yyyy’) = ‘january 23,1982’ Esta mesma sentença SQL, modificada, usará o índice como segue: SELECT e.ename, e.empno FROM emp e WHERE e.hiredate = to_date(‘january 23,1982’ , ’mounth dd,yyyy’) Se na cláusula WHERE os predicativos utilizam dados de tipos diferentes, o ORACLE automaticamente converte um deles sem a preocupação sobre a melhor escolha para a utilização dos índices. A conversão por default é escolhida, pelo caso mais comum (Ex.: O valor de uma coluna, onde o tipo é number, rowid ou date, comparado com uma constante de tipo char). Em qualquer caso é muito recomendado o controle da conversão dos dados de maneira explícita. leitura seqüencial (Full Table Scan): SELECT e.ename, empno FROM emp e WHERE e.comm > = 100 A velocidade de execução dependerá dos dados da tabela. Se a maioria dos registros contiver valores não nulos, a cláusula “comm is not null” será mais rápida. Os índices concatenados não terão referência para os registros onde todas as colunas que o compõem tiverem valores nulos. 4) Caso de predicados com a condição “NOT EQUAL” Os índices sobre colunas referenciadas pela condição not equal não serão usadas. O otimizador considera que o número de registros que irão satisfazer a condição será maior do que os registros que não a satisfazem. O índice sobre DEPTNO não será usado na seguinte sentença SQL: SELECT e.ename, e.empno FROM emp e WHERE e.deptno !=10 No comando abaixo, o índice sobre deptno será utilizado: SELECT e.ename, e.empno FROM emp e WHERE not e.deptno > 20 O ORACLE executará a sentença SQL como e.deptno <= 20 5) Casos de sentenças SQL com cláusula “ORDER BY” A cláusula ORDER BY aumenta consideravelmente a necessidade de recursos para execução de uma sentença SQL. Em geral, tabelas temporárias serão necessárias para operação de sort. É possível evitar a utilização de tabelas 3) Caso de colunas com valores NULL temporárias se um índice sobre a coluna Os índices não contêm referência para alvo do order by existir. As seguintes convalores do tipo null. Isto quer dizer que os dições devem ser cumpridas: valores null podem ser - A coluna order by recuperados somente deve ser definida com através de uma leitura “Se a maioria dos registros not null; seqüencial completa da contiver valores não nulos, a - A coluna order by tabela (Full Table Scan). deve ser uma simples cláusula ‘comm is not null’ será No comando abaicoluna índice ou as xo o índice sobre a mais rápida.” primeiras coluna COMM não colunas de índice será utilizado: concatenado; - A cláusula order by deve conter soSELECT e.ename, e.empno FROM emp e mente colunas e não expressões; WHERE e.comm is null - Não deve haver qualquer cláusula Neste código o otimizador considera group by, distinct ou for update; que a maioria dos registros dentro da ta- Não deve haver nenhum outro acesbela são valores not null e irá escolher a SQL Magazine - 13 so alternativo que seja prioritário sobre o índice da coluna order by; A seguinte sentença SQL será executada via índice em DNAME se os requisitos mencionados acima forem respeitados: SELECT d.dname FROM dept d order by d.dname; SELECT d.dname, d.deptno FROM dept d WHERE d.loc = ‘dallas’ order by d.dname; SELECT d.dname, d.loc FROM dept d WHERE d.dname != ‘accouting’ order by d.dname; Na sentença abaixo, se um índice sobre a coluna LOC existir, tornar-se-á prioritário e o índice sobre dname não será usado: SELECT d.dname, d.deptno FROM dept d WHERE d.loc = ‘dallas’ order by d.dname; únicos serão favorecidos sobre os índices não únicos. - Vários índices não únicos : os registros identificados pelo caminho de acesso do índice condutor (o primeiro nome na sentença SQL) serão unidos com aquele identificado por outro índice. A meta é identificar os registros pertencentes a todos os índices. Se o otimizador não tiver clara escolha concernente a qual índice usar, então irá arbitrariamente escolher o primeiro mencionado dentro da sentença SQL como índice condutor (Driving Index). 8) Caso de sentença SQL com interseção de vários predicados de igualdade dentro da cláusula WHERE com índice não único. O índice não único será sorteado pela coluna rowid a fim de minimizar o número de comparações necessárias. Se nós temos índice não único sobre JOB e DEPTNO: 6) Casos de sentenças SQL contendo funções MAX ou `MIN Um índice será usado para executar uma sentença SQL com MAX ou MIN se as seguintes condições forem satisfeitas: SELECT e.ename FROM emp e WHERE e.job = - MAX ou MIN devem ser apenas ex‘manager’ and e.deptno = 20; pressões da lista de seleção; - A lista de seleção não deve ter quala. Procura a primeira ou próxima quer outro operador de concatenação ou referência do índice sobre job (driving adição a não ser somenindex) conte MAX ou MIN; “É possível ajudar o otimizador tendo ‘manager’. - A lista de seleção não deve conter qual- a procurar o melhor caminho b. Procura a priquer outra coluna a não de acesso através da criação de meira ou a próxiser uma simples ocor- índices e clusters” ma referência do rência da coluna como índice deptno conagrupamento de MAX tendo valor 20. ou MIN; - A sentença SQL não pode ser um Compara as duas rowid. JOIN; - Se as duas forem iguais, registro en- A cláusula WHERE e group by não contrado. Vai a próxima referência de podem ser utilizadas; “a.” e compara com a próxima refe- A coluna alvo do MAX ou MAX deve rência de “b.”. ser indexada ou fazer parte das primeiras - Se forem diferentes guarda a referêncolunas de um índice concatenado. cia de “a.” e passa a próxima referência de “b.”. A seguinte sentença SQL utilizará um - c. Continua a procura até que não índice sobre a coluna SAL: existam mais referências sobre o índice de job (driving index). SELECT (max(e.sal)*2) + 10000 FROM emp e; 7) Sentenças SQL recuperam informações sobre uma simples tabela Uma sentença SQL pode ter vários índices únicos e/ou não únicos à disposição do otimizador. A escolha do índice a ser usado depende da presença de: - Índices únicos e não únicos: os índices 14 - Magazine SQL 9) Caso de sentença SQL com interseção de um predicado de igualdade com um predicado sem limite, dentro da cláusula WHERE com índice não único. Somente o índice sobre a igualdade será usado. No exemplo que segue, se índices não únicos existirem sobre as colunas JOB e DEPTNO, o índice sobre JOB será utilizado, os registros correspondentes serão recuperados e verificada a validade do segundo predicado. SELECT e.ename FROM emp e WHERE e.job = ‘manager’ and e.deptno > 10 10) Caso de índice Concatenado Índices concatenados são índices formados por várias colunas representados como se fosse simplesmente uma única coluna. a) Interseção de vários predicados de igualdade. Se um índice concatenado existir sobre DEPTNO e JOB, somente uma referência será necessária para localizar a rowid correspondente : SELECT e.ename FROM emp e WHERE e.job = ‘manager’ and e.deptno = 10 b) Interseção de predicados sem limite com predicados de igualdade. Se um índice concatenado existir sobre DEPTNO e JOB, será utilizado para executar a seguinte sentença SQL : SELECT e.ename FROM emp e WHERE e.job = ‘manager’ and e.deptno > 10 c) Interseção de predicado sem limite. Se um índice concatenado existir sobre DEPTNO e JOB, será utilizado para executar a seguinte sentença SQL: SELECT e.ename FROM emp e WHERE e.job > ‘manager’ and e.deptno > 10 d) Utilização parcial ou total dos índices concatenados. O otimizador pode somente usar a ou as primeira(s) parte(s) do índice concatenado. No seguinte caso, um índice concatenado foi criado sobre as colunas EMPNO, ENAME e DEPTNO: A seguinte sentença SQL usa plenamente o índice concatenado: SELECT * FROM emp e WHERE e.empno = 7369 AND e.ename = ‘smith’ and e.depnto = 20 SELECT * FROM emp e WHERE e.ename = ‘smith’ AND e.empno = 7369 AND e.deptno = 20 As seguintes sentenças SQL utilizam parcialmente o índice concatenado: Otimização de Comandos SQL Uso parcial do índice usando somente EMPNO e ENAME: SELECT * FROM emp e WHERE e.empno = 7369 and e.ename = ‘smith’ Uso parcial do índice usando somente EMPNO e ENAME : SELECT*FROM emp e WHERE e.empno = 7369 and e.deptno = 20 As seguintes sentenças SQL não usam o índice : SELECT * FROM emp e WHERE e.ename = ‘smith’ and e.deptno = 20 SELECT * FROM emp e WHERE e.ename = ‘smith’ SELECT * FROM emp e WHERE e.deptno = 20 11) Casos de Índice único e não único na mesma sentença SQL. O otimizador favorecerá a utilização do índice único. No seguinte caso o índice não único existe em SAL e um índice único em EMPNO : SELECT e.ename FROM emp e WHERE e.sal = 3000 and e.empno = 7902 O índice único será usado para procurar a rowid correspondente ao empno = 7902. Nos registros recuperados serão verificados o valor de sal. 12) Caso de vários índices na mesma sentença SQL. Se vários índices únicos estão disponíveis, o otimizador irá escolher o primeiro mencionado na sentença SQL. Por exemplo, se índices únicos existirem sobre ENAME e EMPNO, e um índice não único existir sobre SAL, a seguinte sentença SQL será executada sobre o índice ENAME SELECT e.deptno FROM emp e WHERE e.sal = 3000 and e.ename = ‘scott’ and e.empno = 7602 Otimização da cláusula OR (União de predicados) O caminho de acesso é determinado como se a cláusula OR e suas ramificações estivessem ausentes. O caminho é determinado considerando cada ramificação da cláusula OR separadamente. Exemplo A Índice existente sobre SAL e JOB. SELECT e.ename FROM emp e WHERE e.deptno = 10 AND (e.sal = 3000 or e.job = ‘clerk’) Neste caso, o caminho de acesso identificado por “2” é melhor que o identificado por “1”, então a cláusula OR é otimizada para utilização dos índices. Análise 1)Para DEPTNO = 10 - Pesquisa seqüencial na tabela; 2) Para SAL = 3000 - Índice não único sobre SAL; Para JOB = ‘clerk’ - Índice não único sobre JOB; Exemplo B Somente índice sobre SAL utilizando a mesma sentença do exemplo Análise 1)Para DEPTNO = 10 - Pesquisa seqüencial na tabela; 2) Para SAL = 3000 - Índice não único sobre SAL; Para JOB = ‘clerk’ - Pesquisa sequencial na tabela. Os dois caminhos de acesso identificado por “2” não são melhores que o identificado por “1”, então os índices não serão utilizados e ocorrerá uma pesquisa seqüencial na tabela. O otimizador na Cláusula OR exige a presença dos índices utilizáveis dentro de cada coluna referenciada dentro da cláusula OR. Verificando o “Caminho de Acesso” do otimizador Podemos verificar o caminho de acesso utilizado pelo SGDB para executar uma determinada frase SQL. Chamaremos esse caminho de “Acesso de Plano de Execução”. No plano de execução são verificados todos os procedimentos feitos pelo SGDB, como utilização ou não de índices, clusters, rowid, além da verificação da quantidade de passos realizados pelo banco para execução do comando. Este procedimento é muito útil, pois pode ser utilizado como recurso para verificarmos se as alterações efetuadas em um comando realmente otimizam a execução do mesmo. A verificação do plano de execução é feita no Oracle através do comando EXPLAIN PLAN. A sintaxe do comando é a seguinte: EXPLAIN PLAN SET STATEMENT_ID = ‘COMAND_ID’ INTO OUTPUT FOR COMANDOSQL; Onde: - COMAND_ID é um String identifica- dor para posterior visualização do plano de execução. - OUTPUT é tabela onde o plano de execução é gerado. O usuário que executar o EXPLAIN PLAN deve ter direitos de INSERT sobre a mesma. O comando para criação desta tabela émostrado da listagem1. O Script para criação desta tabela chama-se “UTLXPLAN.SQL” e é instalado juntamente com oracle e a sua localização depende da versão do banco. - COMANDOSQL é o comando a ser analisado. Para verificação do plano de execução gerado pelo EXPLAIN PLAN devemos consultar a tabela informada no comando. Este procedimento pode ser efetuado de várias maneiras, uma delas é a que segue: SELECT SUBSTR(LPAD(‘ ‘,2*(LEVEL-1))|| operation,1,50) operation, options, object_name, position FROM OUTPUT START WITH id = 0 AND statement_id = ‘COMAND_ID’ CONNECT BY PRIOR id = parent_id AND statement_id = ‘COMAND_ID’; Onde, - COMAND_ID é um String identificador do plano de execução informado no EXPLAIN PLAN Listagem 1. create table NOME_DA_TABELA ( statement_id varchar2(30), timestamp date, remarks varchar2(80), operation varchar2(30), options varchar2(30), object_node varchar2(128), object_owner varchar2(30), object_name varchar2(30), object_instance numeric, object_type varchar2(30), optimizer varchar2(255), search_columns number, id numeric, parent_id numeric, position numeric, cost numeric, cardinality numeric, bytes numeric, other_tag varchar2(255), partition_start varchar2(255), partition_stop varchar2(255), partition_id numeric, other long, distribution varchar2(30)); SQL Magazine - 15 - OUTPUT é tabela onde o plano de execução é gerado. Vamos exemplificar a execução do EXPLAIN PLAIN validando a seguinte informação: “Um índice é utilizado se ele existir e se a coluna que faz parte deste índice estiver contida na clausula WHERE do comando SQL. Este mesmo índice não é utilizado se existirem funções de conversão de dados envolvendo esta coluna.” Em outras palavras: a execução do comando “SELECT * FROM EMP WHERE EMPNO = 50” utilizará o índice da chave primária, que contém a coluna EMPNO, e a execução do comando “SELECT * FROM EMP WHERE TO_CHAR(EMPNO) = ‘50’”, não utilizará o índice. Utilizaremos o comando do quadro em destaque acima para criação da tabela que receberá o plano de execução, com o nome de PLAN_TABLE. Em seguida executaremos o EXPLAIN PLAN para verificação da utilização do índice com o seguinte comando: SELECT SUBSTR(LPAD(‘ ‘,2*(LEVEL-1)) || operation,1,50) operation, options, object_name, position FROM PLAN_TABLE START WITH id = 0 AND statement_id = ‘SQLMagazine Com Indice’ CONNECT BY PRIOR id = parent_id AND statement_id = ‘SQLMagazine Com Indice’; O resultado com o plano de execução é mostrado na Tabela 2. Analisando este resultado comprovamos que o índice referente a chave primária foi utilizado. Vamos verificar agora o mesmo comando alterado: EXPLAIN PLAN SET STATEMENT_ID = ‘SQLMagazine Sem Indice’ INTO PLAN_TABLE FOR SELECT * FROM EMP WHERE TO_CHAR(EMPNO) = ‘50’; A verificação do plano de execução é feita de seguinte forma: EXPLAIN PLAN SET STATEMENT_ID = ‘SQLMagazine Com Indice’ INTO PLAN_TABLE FOR SELECT * FROM EMP WHERE EMPNO = 50; SELECT SUBSTR(LPAD(‘ ‘,2*(LEVEL-1)) || operation,1,50) operation, options, object_name, position FROM PLAN_TABLE START WITH id = 0 AND statement_id = ‘SQLMagazine Sem Indice’ CONNECT BY PRIOR id = parent_id AND statement_id = ‘SQLMagazine Sem Indice’; A verificação do plano de execução é feita de seguinte forma: Este resultado mostra que a utilização do índice foi anulada pela função aplicada ANUNCIO 16 - Magazine SQL OPERATION OPTONS OBJECT_NAME select statement table access by index rowid index unique scan emp pk_emp OPERATION OPTONS OBJECT_NAME select statement table access full emp a coluna. Conclusão Os cuidados a serem tomados com o acesso a dados da aplicação são parte importante de um projeto. A forma como as consultas são escritas e como o banco de dados está projetado influencia diretamente na performance do produto. Esses fatores não devem andar separados. Na maioria dos casos é necessária a perfeita integração entre a consulta escrita e o estado do banco de dados. Muitas vezes uma simples “arrumação” na consulta, trocando algumas cláusulas ou mudando um pouco a “lógica” das condicionais, garante um ganho na velocidade de execução e resposta da mesma. Não esqueça nunca de analisar se o índice a ser criado é realmente necessário, para não adicionar um mais um processo para o seu banco. Boa sorte e bons projetos! Otimização de Comandos SQL ANUNCIO SQL Magazine - 17 Modelagem de dados com SQL C por Cleison Santos oloca-se como de fundamental importância tanto a análise como a modelagem de dados para o processo de desenvolvimento de aplicações. Esses procedimentos garantem um maior controle das diversas etapas do projeto desde a denição das regras do negócio até a implementação e manutenção da aplicação como um todo. Existem no mercado, atualmente, diversas ferramentas para modelagem de dados, dentre as quais pode ser destacado o software ErWin. O ErWin pode ser usado de uma forma simples e prática possibilitando uma melhor visualização, controle e documentação do que se tem no banco de dados. Através dos diversos recursos disponíveis (Figura 1) podemos “desenhar” o nosso banco de dados definindo as entidades de que compõe o modelo com seus respectivos atributos e relacionamentos, definir características dessas entidades tornandoas reais em um modelo físico ou em vários modelos físicos se for necessário o acesso a SGDB´s distintos. Podemos ainda criar, de forma automática, o modelo implementado num banco de dados ou gerar scripts Figura 1. Tela inicial do ErWin para atualização de alterações efetuadas no modelo, “sincronizar” dois bancos de forma a garantir uma estrutura idêntica em ambos, e vários outros recursos. Na parte superior direita, observa-se uma barra de ferramentas com os principais objetos do ErWin, como mostrado na Figura 2, a seguir: Alguns conceitos importantes 1) Entidades - Entidade é o local onde ficam armazenadas as informações. Por exemplo, a Entidade ‘CLIENTES’ pode guardar informações referentes aos clientes, e assim sucessivamente. 2) Subtipos - Podem ser definidos como um espelho de uma ou mais entidades. Por exemplo, pode-se criar um subtipo chamado CLIENTES_RJ que contenha somente os clientes que moram no Rio de Janeiro, podendo ter ou não todos os Modelagem de Dados com ErWin Entidades Figura 2. Barra de ferramenta do ErWin Criar subtipos de entidades existentes Inserir textos no modelo, como comentário de entidades, relacionamentos e outros Relacionamento de cardinalidade um para muitos Relacionamento de cardinalidade muitos para muitos Relacionamento de cardinalidade um para um Auxilio para mudar os atributos de posição ou de entidades atributos da Entidade CLIENTES. 3) Atributos - Os atributos podem ser definidos como identificadores de cada informação contida na entidade. O Código do Cliente, por exemplo, é um atributo da Entidade CLIENTES. 4) Relacionamentos - Relacionamentos são definidos como a ligação entre duas ou mais entidades. 5) Cardinalidade - É o que caracteriza o relacionamento.Por exemplo: um pai pode ter mais de um filho, porém um filho só pode ter apenas um pai. Isso quer dizer que a cardinalidade define o comportamento do relacionamento, definindo-o como um para muitos, muitos para um ou até muitos para muitos. Os tipos de modelo • Modelo Lógico: É o modelo de abstração do sistema. Neste, detalhes como qual banco de dados será usado, o tipo de campo, o tipo de hardware, entre outros aspectos não são relevantes. Aqui, somente as necessidades do processo são definidas, dando uma visão “global” do sistema. No Erwin, podemos ter uma visão da regra de negócio, ou seja, podemos planejar uma estrutura lógica para o banco de dados, onde são definidas as Figura 3. Criação da Entidade Clientes validações, as restrições da regra de negócio, a análise das entidades e dos atributos definidos para a aplicação como um todo. •Modelo Físico: É onde os detalhes são definidos. Serve como um espelho de tudo o que está no banco de dados, permitindo controlar características de tabelas e colunas (conhecidos no modelo lógico como Entidades e Atributos) de forma particular para o SGDB utilizado além de possibilitar a definição de Procedures, Triggers e outros processos. Criando o modelo lógico O tipo de modelo que está sendo visualizado encontra-se na Combo situada logo acima da barra de ferramentas, mostrada na Figura 1. O modelo utilizado inicialmente será o modelo lógico, pois começando por este fica mais fácil definir o outro. Isso porque, como já foi visto, no modelo lógico tem-se um melhor controle da aplicação, sendo possível definir as validações necessárias, tanto para a regra de negócio como para a implementação de banco de dados no modelo físico. Posteriormente, podem ser criados modelos físicos para acessar a diferentes bancos de dados a Figura 4. Editor de Atributos partir do mesmo modelo lógico. Será criado um modelo simples, onde definiremos algumas entidades com seus respectivos atributos e relacionamentos mostrando como utilizar alguns dos muitos recursos disponíveis no ErWin para modelagem de dados. O modelo será feito com base em um sistema comercial com as tabelas CLIENTES, VENDEDORES, PRODUTOS, FORNECEDORES, PEDIDOS E ITENS_PEDIDOS. Criando as Entidades Como já visto, as entidades podem ser criadas através do primeiro objeto da barra de ferramentas, clicando nesta, arrastando para o modelo e trocando o seu nome, como mostrado na Figura 3. Criando os Atributos Para criar os atributos, basta apenas dar um duplo clique na entidade. É possível criar novos atributos, renomear ou excluir um atributo já existente, como mostrado na figura 4. Pode-se, também, ao lado direito da tela, definir várias características do atributo como chave primária na opção Primary Key ou Requerido na opção Required. Figura 5. Editor de Relacionamentos entre entidades SQL Magazine - 19 Figura 6. Modelo lógico com entidades, atributos e relacionamentos. Figura 8. Modelo Físico com Tabelas, Colunas e Relacionamentos Criando o modelo físico Figura 7. Editor de Coluna Criando os Relacionamentos Após criar todo o modelo lógico é necessária a definição dos atributos do modelo físico. Para alternar entre os modelo físico e lógico basta selecionar na Combo situada logo acima da barra de ferramentas, mostrada na Figura 1. No modelo físico iremos definir características das entidades e atributos criados no modelo lógico de acordo com o SGDB utilizado. Neste modelo temos uma visão real das tabelas, colunas, procedures, triggers e outros objetos do nosso banco. A figura 7 mostra o Editor de Coluna do modelo físico. Conforme o observado no modelo físico, não existem mais Entidades e Atributos, e sim Tabelas e Colunas, nomes comuns ao banco de dados. O editor de coluna permite alterar o tipo e tamanho de cada campo, assim como definir se ele pode ou não receber valores nulos. Ainda pode-se utilizar a aba Comment para comentar cada campo, assim como cada tabela. Para definir um tipo de relacionamento, basta escolher um dos três objetos já mostrados da barra de ferramentas, clicar na tabela pai e depois na tabela filho. Automaticamente, o relacionamento escolhido é visualizado. A figura 5 mostra o editor de Relacionamento e suas funcionalidades. Ao dar um duplo clique sobre o relacionamento esta tela é automaticamente aberta. Nela definimos a cardinalidade do relacionamento, assim como a nulidade dos campos que estão sendo relacionados. A figura 6 mostra o modelo totalmente criado, com suas entidades, atributos e respectivos relacionamentos. Criando o banco de dados a partir do Modelo Físico criado Figura 9. Target Server – Configuração do Banco de Dados Terminada a implementação é necessário criar os objetos definidos no ErWin em um banco de dados. Para isso, é preciso fazer o modelo apontar para o SGDB a ser utilizado acessando-se o menu: Server\Target Server. Além da seleção do SGDB e da versão do mesmo é possível definir opções referentes ao tipo de dados e a nulidade default para as colunas definidas no modelo bem como máscara para nomenclatura automática de índices e tabelas. Vide Figura 9. Após as configurações do Target Server, basta acessar o menu Tasks\Forward Engineer/Schema Generation para criar o banco de dados. Vide Figura 10. Utiliza- 20 - Magazine SQL remos um banco criado no Oracle. Como se pode ver a tela é bem intuitiva. Na pasta Summary indicamos os objetos do nosso modelo ( tabelas, colunas, índices, triggers, etc.. ) que serão criados no banco. Ao clicar no botão Generate, o banco é criado, automaticamente, com todas as tabelas, campos e relacionamentos demonstrados no modelo físico. A Figura 11 mostra os scripts com todos objetos gerados no banco de dados a partir do modelo implementado. Criando um modelo a partir de um banco existente Em muitos casos, o banco de dados já está totalmente implementado, sendo necessária a criação do modelo a partir deste. Este processo chama-se Engenharia Reversa, e é acessado pelo menu Tasks\Reverse Engineer. A primeira tela a ser exibida é a ErWin Template Selection, onde escolhe-se a opção Blank Diagram para criar o modelo do zero. Ao clicar em Next, depara-se com a tela Select Taget Server, onde é informado o tipo de banco de dados a ser utilizado e a sua versão. Clicando-se mais uma vez no botão Next, surge a tela Set Options onde são definidos procedimentos necessários à realização da engenharia reversa. Vide figura 12. Figura 10. Tela de geração de banco de dados Modelagem de Dados com ErWin Figura 14. Modelo criado apartir de um banco de dados existente usando a Engenharia Reversa Deste modo, as opções da engenharia reversa podem ser definidas como Dados de Tabelas, Colunas, TableSpace, Procedure, Triggers e outros. Na opção Table/Views Owned By, foi selecionada a opção Current User para importar somente os objetos criados pelo usuário conectado, poderíamos importar objetos de todos os usuários do banco ou de um usuário diferente do atualmente conectado desde que o mesmo tenha privilégios no banco suficientes para isso. Ainda há possibilidade de se escolher formas de indexação e outras coisas mais. Clicando-se no botão Next, visualiza-se a tela de conexão, conforme mostrado na Figura 13. Esta é a tela que permite fazer a conexão do modelo com o banco de dados definido em Taget Server, mostrado na Figura 9. Esta tela também é apresentada quando o banco é criado a partir do modelo. Nela são informados o Nome de Usuário, a Senha e a Connect String que repesenta a instância onde será efetuada a conexão, neste caso, com o Oracle. Foi criada uma Connection String, chamada “Comercio” no TNSNAMES do Oracle apontando para o banco de dados. Feito tudo isso, é só clicar no botão Connect que o modelo é criado automaticamente, conforme mostrado na Figura 14. Foi possível, a partir de um banco existente, criar um modelo semelhante ao já implementado, conforme já mostrado. Figura 13. Tela de Conexão com o Oracle. Figura 15. Modelo Físico para acessar o Sql server. No processo de Engenharia Reversa no ErWin, os modelos lógico e físico são criados automaticamente. Criando vários modelos físicos a partir de um único modelo lógico Ainda se pode, a partir de um modelo lógico, criar modelos físicos para acessar bancos de dados diferentes do Oracle. Será criado um modelo físico que acesse um banco de dados Sql Server a partir do mesmo modelo lógico criado para o Oracle. Para isso basta acessar o Target Server, mostrado na figura 9, mudar o banco para o Sql Server, escolhendo a versão, definindo os padrões (como já mostrado) e efetuar os procedimentos mostrados nas figuras 10 e 11. A Figura 15 aponta como fica o modelo físico para acessar o banco de dados Sql Server. Observa-se que alguns tipos de campos mudaram, como os campos de valores monetários, que passaram de Number (7,2) para Money, e os de data, que passaram de Date para Date/Time. Com isso, concluise que, a partir de um modelo lógico criado, pode-se criar modelos físicos para acessar diversos bancos de dados, e este se adapta à situação de cada um automaticamente. É importante ressaltar que o modelo lógico continua o mesmo. Conclusão Estes são apenas alguns dos muitos recursos que o ErWin oferece para modelagem de dados. É possível criar Procedures, Triggers, Views, alterar o banco de dados, alterar o modelo a partir de alguma alteração feita no banco, criar o dicionário de dados, etc. A implementação de um modelo antes do início do desenvolvimento de um sistema garante uma Figura 11. Script com o código de criação das tabelas definidas no modelo. Figura 12. Tela de opções da Engenharia visão ampla e unificada do mesmo, facilitando em muito a definição da regras de negócio, a implementação, manutenção e análise dos procedimentos, garantindo inclusive a continuidade do trabalho no caso de alterações na equipe de desenvolvimento com pouco ou nenhum retrabalho uma vez que o modelo disponibiliza de forma clara e objetiva uma documentação de toda infra-estrutura do sistema. SQLAutor Cleilson Santos é Analista de Sistemas, trabalha no Projeto SEP (Sistema de Engenharia de Poço) e SIRR (Sistema de Reserva e Reservatório) na Petrobrás. Pode ser contatado pelo e-mail [email protected] SQL Magazine - 21 Introdução à UML N por Gustavo Viegas o nal dos anos 80 e início dos anos 90, tínhamos muitos conitos de denições e nomenclaturas na área de modelagem. A escolha para utilização de um determinado padrão era denido mais pelo “gosto” pessoal do que por fatores técnicos oferecidos. Então, os três mais respeitados nomes nesse campo, cada qual com seu conceito e implementação de modelo, Ivar Jacobson (OOSE – Object Oriented Software Engineering), Grady Booch (The Booch Method) and James Rumbaugh (OMT –Object Modeling Technique) decidiram por m aos debates e trabalhar juntos na denição de um modelo único que veio a ser a UML. A UML permite que você “desenhe” uma “planta” do seu sistema. A comparação ideal é a de um construtor que vai realizar um projeto sem antes ter toda a planta que defina estrutura a ser construída. A experiência do construtor garante, até certo ponto, o sucesso do projeto. Mas, com certeza, uma vez feito o planejamento, o “cálculo estrutural”, o desenho da planta, a garantia de sucesso antes, durante e depois da efetivação da construção é incomparavelmente maior. O mesmo acontece com um projeto de software. A experiência do desenvolvedor ou analista, não pode substituir a necessidade de um projeto que defina uma “planta” da solução como um todo. Esta “planta” garante, em todas as fases do projeto, seja na definição, desenvolvimento, homologação, distribuição, utilização e manutenção do mesmo, uma maior clareza e objetividade para execução de cada ação, e, com certeza, quanto maior a solução, maior a necessidade de um projeto definido adequadamente. Desta forma, a UML é uma linguagem padrão para visualização, especificação, construção e documentação de um aplicativo ou projeto de software, e objetiva aumentar a produtividade, otimizar as etapas que envolvem o desenvolvimento de um sistema, aumentando assim a qualidade do produto a ser implementado. Ela independe da ferramenta em que o aplicativo será desenvolvido. A idéia e prover uma visão lógica de todo o processo de forma a facilitar a implementação física do mesmo. A UML disponibiliza, através de conceitos, objetos, símbolos e diagramas, uma forma simples, mas objetiva e funcional, de documentação e entendimento de um sistema. Você pode utilizar os diagramas e arquivos que compõe um modelo UML para o desenvolvimento, apresentação, treinamento e manutenção durante todo o ciclo de vida da sua aplicação. Ela é mais completa que outras metodologias empregadas para a modelagem de dados pois, tem em seu conjunto todos os recursos necessários para suprir as necessidade de todas as etapas que compõe um projeto, desde a definição, implementação, criação do modelo de banco de dados, distribuição, enfim, proporcionando sem qualquer outra ferramenta ou metodologia adicional, um total controle IIntrodução à UML do projeto. A UML implementa uma modelagem com uma visão orientada a objetos. Através dela podemos definir as classes que compõe a nossa solução, seu atributos, métodos e como elas interagem entre si. Apesar da UML ter como base a orientação a objetos, não significa que a ferramenta e a linguagem utilizada para a implementação do modelo seja também orientada a objetos, embora seja recomendável. Este artigo não irá explorar os conceitos de orientação a objetos, e sim a implementação de um modelo UML simples, para início da documentação de um sistema, utilizando dois diagramas implementados pela UML que são o “Diagrama de Casos e Uso” e o “Diagrama de Classes”. Os diagramas têm como objetivo representar, através de um conjunto de elementos, como o sistema irá funcionar e como cada peça do sistema ira trabalhar e interagir com as outras. Outra vantagem vem da facilidade de leitura dos diagramas que compõe a UML, além da facilidade de confeccioná-los, pois existem inúmeras ferramentas para modelagem de dados orientados a objetos (ferramentas Case), dentre elas o Rational Rose, o Model Maker, e o Poseidom UML. Além dos diagramas citados a UML disponibiliza outros diagramas, dentre os quais podemos citar o Diagrama de Objetos, Diagrama de Seqüência, Diagrama de Colaboração, Diagrama de Estado, Diagrama de Atividade e Diagrama de Componentes. nharia Reversa, que é gerar o modelo a partir das classes implementadas. O Poseidon tem sua versão free e pode ser baixado em www.gentleware.com. O modelo aqui proposto começa a ser implementado a partir de um problema real que é a necessidade de um cliente. O problema proposto é o seguinte: “Desenvolver um sistema para um caixa eletrônico onde é permitido a um cliente realizar quatro tipos de operações: a de consulta de saldo, solicitação de extrato, depósito e saque. Esse mesmo caixa eletrônico deve ser abastecido de dinheiro e ter os depósitos recolhidos por um funcionário do banco” Para definição do modelo do nosso sistema, iremos implementar primeiro um Diagrama de Casos de Uso ou Use Cases. Os objetivos principais de um diagrama de Casos de Uso são: • Descrever os requisitos funcionais do sistema de maneira uniforme para usuários e desenvolvedores; • Descrever de forma clara e consistente as responsabilidades a serem cumpridas pelo sistema, formando a base para a fase de projeto; • Oferecer as possíveis situações do mundo real para a fase de testes do sistema. Os elementos básicos de um diagrama de caso de uso são: ator, caso de uso, interação e sistema, todos ilustrados na figura 1. Um ator é uma entidade externa ao sistema que de alguma forma participa de um caso de uso. Um ator pode ser um ser humano, máquinas, dispositivos, ou outros sistemas. Atores típicos são cliente, usuário, gerente, computador, impressora, etc. Os atores representam um papel e iniciam um caso de uso que após executado, retorna um valor para o ator. Um caso de uso especifica um serviço que será executado ao usuário e é composto por um ou mais cenários. Um cenário é uma narrativa de uma parte do comportamento global do sistema. Para o problema proposto, o Diagrama de Casos de Uso pode ser implementado como mostrado na figura 2. No Diagrama de Casos de Uso implementado o sistema é o Caixa Eletrônico, os atores representam o Cliente e o Funcionário do banco. O Cliente interage com os Casos de Uso consulta de saldo, solicitação de extrato, depósito e saque e o Funcionário interage com os Casos de Uso Abastece de dinheiro e Recolher envelopes de depósitos. Para melhor entendimento do Diagrama de Casos de Uso é necessária a descrição textual do fluxo do Caso de Uso (principal e alternativo) e do Cenário ou dos Cenários que compõe cada Caso de Uso. Iremos descrever o Use Case Solicitação de Extrato bem como o Cenário que o compõe. Após a descrição textual de todos os Casos de Uso e respectivos Cenário, nossa documentação envolvendo o Diagrama de Casos de Uso está completa. O segundo diagrama a ser utilizado para solução do problema proposto é o Diagrama de Classes. Este diagrama, contém as classes que caracterizam os objetos do nosso sistema. As classes são extraídas a partir da análise do Diagrama de Casos de Uso e representam os componentes de interação do nosso sistema e Entendendo UML a partir de um exemplo prático Utilizaremos o Poseidon UML para implementar o modelo do exemplo. O Poseidon UML é uma ferramenta case que suporta os principais diagramas UML e é desenvolvido em Java. Tem algumas facilidades no que se refere a interação com o Java podendo, a partir de um modelo gerar o código Java das classes definidas no mesmo e também suporta a Enge- Figura2 SQL Magazine - 23 Caso de Uso “Solicitação de Extrato” 1) Descrição textual do fluxo principal do Use Case Solicitação de Extrato Este Caso de Uso inicia-se quando o Cliente escolhe a opção Extrato após passar o cartão no caixa eletrônico e ter a sua conta validada. Após a validação da conta o sistema pede ao cliente para escolher dentre as opções de saldo: Extrato Rápido - O subfluxo A1 (Imprimir Extrato Rápido) é executado. Extrato no Período - O subfluxo A2 (Imprimir Extrato no Período) é executado. Sair - O Caso de Uso é encerrado, o sistema volta a tela principal e solicita que o cliente passe o cartão. 2) Descrição textual dos Subfluxos alternativos associados a este use case A1 - Imprimir Extrato Rápido O sistema solicita que o cliente entre com a senha para autorizar a impressão do extrato (o subfluxo B1 - Solicitar e Validar de senha alfabética - é executado). Caso a senha seja validada a conta do cliente é consultada e o extrato é impresso (o subfluxo B2 – Imprimir Extrato - É executado). O sistema volta a tela principal e solicita que o cliente passe o cartão. A2 - Imprimir Extrato no período O Sistema solicita que o cliente informe a data inicial e final pra impressão do extrato. Em seguida O sistema solicita que o cliente entre com a senha para autorizar a impressão do extrato (o subfluxo B1 - Solicitar e Validar de senha alfabética - é executado). Caso a senha seja validada a conta do cliente é consultada de acordo com o período e o extrato é impresso (o subfluxo B2 – Imprimir Extrato - É executado). O sistema volta a tela principal e solicita que o cliente passe o cartão. B1- Solicitar e Validar de senha alfabética O sistema solicita que a senha do cartão seja digitada. Consulta a conta do cliente validando a senha digitada. Caso a senha não seja válida o sistema informa na tela e pede mais uma tentativa. O sistema verifica a quantidade de erros de validação de senha ocorridos no dia e informa que após 3 tentativas erradas o cartão do cliente será bloqueado e informa o número de tentativas que o cliente ainda dispõe. O Cliente pode sair da operação e voltar para a tela inicial, ou tentar novamente. Caso a senha seja válida, a operação prossegue. Caso contrário, após três tentativas o cartão do cliente é bloqueado. B2- Imprimir Extrato O sistema verifica se a impressora do caixa eletrônico está ativa e se a mesma possui papel. Caso apresente um dos problemas citados, o sistema mostra uma mensagem solicitando que o cliente realiza a operação em outro caixa eletrônico e volta para a tela inicial e avisa do erro sempre que uma operação que envolva impressão for solicitada. Caso contrário, o conteúdo solicitado para impressão é impresso. 3) Cenário Primário José dirige-se ao caixa eletrônico e passa o cartão na máquina. O Sistema, após validar a conta exibe as opções disponíveis. José seleciona a opção de Solicitação de Extrato. Em seguida José seleciona a opção de Extrato no Período. Informa a data inicial e final. O Sistema solicita a senha a José. Após José digitar a senha e confirmar a operação, o Sistema valida a senha, consulta a conta de José e imprime o extrato de movimentação da conta no período selecionado. 4) Cenário Secundário O Sistema, ao verificar os requisitos para impressão, retornou que a impressora estava sem papel. José, após ser informado do problema pelo sistema, dirigi-se a outro caixa eletrônico e inicia novamente a operação. Figura3 como eles se relacionam. Vamos implementar um Diagrama de Classe, a partir do Diagrama de Casos e Uso implementado, com a definição das classes Cliente, ContaBancaria e Lançamentos da Conta. ( Vide Figura 4 ) Uma classe é representada por um retângulo sólido com três partes: a primeira para o nome da classe; outra para os atributos da classe ( que podem ser vistos como características da classe); e a terceira para a declaração das operações definidas para a classe. A Figura 3 mostra a notação UML para classes. Através da classe Cliente implementada no diagrama da figura 4, nós definimos as características do nosso cliente (neste caso um Identificador e um Nome que representam os atributos da classe), seu relacionamento com a classe ContaBancaria que é de 1 para muitos ( isto representa a cardinalidade do relacionamento ) e definimos uma operação realizada pela classe que é ObterContaBancaria(). A mesma análise deve ser feita para a classe ContaBancaria e LancamentoConta. Com esse diagrama, já podemos identificar elementos que existirão em nosso sistema, suas carcterísticas e operações. Essas definições estão contidas nas classes. Essas classes tornam-se reais em nosso sistema a quando são manipuladas por ele e, a partir daí, são conhecidas como objetos, pois suas características passam a “ter um valor” e elas começam a interagir com outros objetos das classes relacionadas. Conclusão A UML se mostra como parte essencial no “ciclo de vida” de uma aplicação. Foi mostrado, utilizando apenas dois diagramas, toda a funcionalidade operacional de um sistema bem como a definição de elementos internos referentes ao desenvolvimento do mesmo. Esses dois diagramas fazem parte da documentação do sistema, e podem ser utilizados para uma apresentação da solução para o requisitante antes da implementação da mesma, visualização dos processos que o sistema irá disponibilizar, definição de elementos inerentes ao desenvolvimento como estrutura de telas, procedimentos operacionais, referência para criação de objetos de persistência em um banco de dados, etc. Existem outros elementos a explorar, outros diagramas, outros tipos de relacionamentos e documentação, mas este foi um passo inicial para conhecer todos os recursos que a UML disponibiliza e aumentar a qualidade do desenvolvimento de nossas aplicações. SQLAutor Figura4 24 - Magazine Gustavo Viegas é editor da revista SQL Magazine . Pode ser contactado pelo email: [email protected] SQL IIntrodução à UML ANUNCIO SQL Magazine - 25 Como conectar Front-Ends Delphi, VB.Net e Java por Pedro Henrique Paulo Correia Gustavo Viegas A tualmente não podemos negar que deparamos diariamente com diversas formas de armazenamento e manipulação de dados. Isto independe do lugar que estamos ou do que fazemos. Se vamos a um mercado, temos computadores que registram as vendas, máquinas de consulta de preços de produtos, terminais para saques eletrônicos, máquinas de cartão de crédito, entre outros. É comum encontrarmos em diversas áreas da nossa vida a presença de máquinas e aplicativos que, de alguma forma, lidam com dados armazenados, dinamizando e facilitando seu acesso. É comum encontrar aplicações que interagem com algum tipo de informação ou conjunto de informações. Independente da linguagem que foram desenvolvidas, elas visam garantir aos seus usuários segurança, clareza e objetividade na recuperação e manutenção do seu conteúdo. Mas antes de falarmos dos sistemas que fazem o usuário interagir diretamente com os dados, visualizando-os e manipulando-os de forma coerente e usual, é importante termos conhecimento prévio de que as informações manipuladas por eles, em sua maioria, estão armazenadas em um Sistema Gerenciador de Banco de Dados, ou simplesmente SGBD. Este SGBD deve garantir que os dados estejam armazenados de forma organizada, permitindo atualizações, inclusões e exclusões e garantindo toda segurança e consistência. Por definição temos que SGDB é “um software (ou conjunto de Softwares) responsável pelo gerenciamento (armazenamento e recuperação) dos dados no banco de dados”. Um SGBD pode gerenciar um ou mais bancos de dados. Mas como definir um banco de dados? Se nós temos um arquivo contendo a tabela de preços dos produtos de uma indústria, nós temos um banco de dados? Conceitualmente, uma banco de dados tem de representar uma coleção de dados organizados de forma coerente e com um significado real. Uma tabela de preços, por si só, não tem um significado real sem que existam outras tabelas que interajam com ela. Se nós temos uma tabela de preços, uma tabela de clientes, uma tabela de pedidos e uma tabela de produtos, já podemos montar um quadro que traduz um processo de atendimento a clientes, venda e controle de estoque, ou seja, uma situação real armazenada num banco de dados. A forma mais comum de interação entre usuário e banco de dados ocorre através de sistemas específicos, que por sua vez acessam o volume de informações geralmente através da linguagem SQL (Strutured Query Language), padrão entre os SGBD´s. A ferramenta de desenvolvi- Conectando Front-Ends com Delphi, VB.Net e Java Figura1. Uma nova aplicação no Delphi mento utilizada para a implementação desses sistemas é tão importante quanto o SGBD que gerencia as informações a serem acessadas por eles. Iremos analisar três grandes ambientes para desenvolvimento: Delphi, VB .Net e Java. Por que o Delphi? O Borland Delphi é uma grande opção para o desenvolvimento de sistemas em que é necessário utilizar servidores de Banco de Dados SQL. Inicialmente, é importante frisar que o Delphi possui um suporte bem amplo aos Servidores SQL encontrados hoje no mercado, através da implementação de diversos drivers e engines. Alguns são da própria Borland, como o DbExpress e a obsoleta BDE. Outros são de terceiros, como o ADO (ActiveX Data Objects) da Microsoft. Um driver geralmente é uma dll, um conjunto de funções utilizadas para acesso e manipulação de dados em um banco. Um engine é um aplicativo que faz a interface ou tradução das mensagens enviadas Figura3. Configuração do SQL Connection Figura2. Componentes SQL Connectiom pela aplicação para o driver, de forma que seja transparente para a aplicação o tipo de driver que está sendo utilizado para acesso ao banco. Uma das grandes novidades do novo Delphi é o suporte através da dbExpress ao servidor Microsoft SQL-Server 2000. Neste artigo usaremos o DbExpress e o ADO como engines de acesso e o banco de dados será o Northwind do Microsoft SQL-Server 2000. O ADO, sendo desenvolvido pela Microsoft, se caracteriza como uma ótima opção para conexão ao MSSQL Server, além de facilitar a distribuição da aplicação, uma vez que é suportado nativamente por diversas versões do sistema operacional Microsoft Windows (Win 98 SE, Win ME/2000 Professional, Win XP Home/Professional). Exemplificaremos o mesmo acesso utilizando o DBExpress. Iremos verificar que as diferenças de programação de um Engine de acesso para outro no Delphi são poucas. O que muda mais é o deploy (distribuição) e a performance. Exemplo em Borland Delphi 7 Primeiro iremos exemplificar a conexão utilizando DbExpress. Passo 1 – Iniciando uma nova aplicação. Clique menu File / New / Application como mostra a figura 1 Passo 2 – Configurando a conexão Adicione ao formulário form1 o componente SQLConnection, localizado na paleta de componentes DbExpress. Em seguida, clique com o botão inverso do NOTA Para obter mais informações sobre o ADO, acesse o Microsoft Universal Data Access no endereço: http://www.microsoft.com/data. Lá é possível baixar a versão mais recente do MDAC (conjunto de componentes que, entre outros recursos, inclui o ADO). Figura4. SQLConnection configurado SQL Magazine - 27 Figura5. Configurando o SQLQuery mouse no componente e selecione Edit Connection Properties, como mostra a figura 2. Será exibida uma caixa de diálogo para configuração das propriedades de conexão com o banco de dados. Vamos utilizar a conexão denominada MSSQLConnection (poderíamos adicionar uma nova conexão clicando no botão “+”, selecionando o driver MSSQL e dando um nome para a mesma) e configurar em Connection Settings os demais parâmetros: HostName – Nome ou IP da máquina servidora Database - Nome do banco de dados no SQL Server User_Name- Nome do usuário Password - Senha Para testar a conexão clique no botão “Test Connection” (último da barra de ferramentas com um ícone de engrenagem). A figura 3 mostra a janela preenchida. A conexão é aberta através da pro- Figura7. Componente ADOConnection 28 - Magazine SQL Figura6. Projeto com DBExpress finalizado priedade Connected do componente SQLConnection (as propriedades são acessadas através do Object Inspector). Podemos alterar esse valor em tempo de design ou tempo de execução. Altere a propriedade LoginPrompt para false para desabilitar a caixa de diálogo de login do banco. Neste caso, o usuário e senha já estão sendo passados diretamente pelo aplicativo. Observe as alterações na figura 4. Passo 3 – Acessando os dados Acessaremos a tabela Employees no banco tomado como exemplo. Para isso, insira um componente TSQLQuery, localizado também na paleta DBExpress. Devemos conectar o SQLQuery ao objeto SQLConnection. Selecione a propriedade SQLConnection do SQLQuery e aponte para SQLConnection1. Em seguida definimos o código da consulta SQL através da propriedade XXXX. Para executar a consulta em tempo de proje- to basta alterar a propriedade Active do componente para true. Vide figura 5. Passo 4 – Manipulando os dados e executando a aplicação Para permitir que o usuário manipule os dados selecionados, utilizaremos um componente DbGrid. Este componente está localizado na paleta Data Controls. Uma vez adicionado ao formulário é necessário que esse componente acesse os dados retornados pelo SQLQuery configurado no passo 3. Para isso, utilizaremos três outros componentes: ClientDataSet, DataSetProvider e DataSource que estão localizados na palheta Data Access. Esses componentes devem ser adicionados ao formulário e configurados da seguinte forma: DataSetProvider - A propriedade DataSet aponta para o SQLQuery configurado no passo 3. ClientDataSet – A propriedade ProviderName aponto para o objeto DataSetProvider. DataSource – A propriedade DataSet aponta para o ClientDataSet configurado no passo anterior. Por fim, para que os dados sejam exibidos no grid adicionado ao formulário, devemos apontar a propriedade DataSource do grid para o objeto DataSource1, alterarando a propriedade Active do ClientDataSet para true. Dessa forma os dados serão exibidos no grid, estando prontos para serem manipulados conforme mostra a figura 6. O ClientDataSet e o DataSetProvider fazem parte de uma implementação da Borland denominada DataSnap (antigo MIDAS) que disponibiliza para o desenvolvedor o que chamamos de “DataSet Desconectado”. A partir de um DataSet Conectando Front-Ends com Delphi, VB.Net e Java Figura8. Configurando ADOConnection qualquer, que no exemplo foi o SQLQuery, o DataSetProvider monta um conjunto de dados e envia para o ClientDataSet. Feito isso, o SQLQuery, que é o DataSet de origem, não é mais utilizado, bem como a conexão com o banco, e os dados podem ser manipulados sem sobrecarga da rede e conseqüente degradação da performance da aplicação. Após o término da manipulação dos dados, é necessário a execução do método ApplyUpdates do ClientDataSet, para que sejam aplicados no banco. No exemplo, o evento “OnClick” do botão “Aplica Alterações” deve ser implementado com o seguinte código: procedure TForm1.BitBtn1Click(Sender: TObject); begin ClientDataSet1.ApplyUpdates(0); end; O parâmetro do método indica o número de erros que serão desconsiderados antes de ser gerada uma exceção na aplicação. Neste caso o parâmetro indica que não podem ocorrer erros no processamento. Figura9. Escolhendo o Provider Para cancelar as alterações efetuadas é necessário a execução do método CancelUpdates. Neste caso, o evento “OnClick” do botão “Cancela Alterações” deve ser implementado com o seguinte código: procedure TForm1.BitBtn2Click(Sender: TObject); begin ClientDataSet1.CancelUpdates; end; Outra grande vantagem do Client DataSet e do DataSetProvider é a facilidade que eles disponibilizam para que, se for necessário, seja efetuada uma troca do engine de acesso ao banco. O mesmo programa feito com DBExpress será utilizado para exemplificar o acesso a dados utilizando ADO. ACESSO AO SQL SERVER COM ADO Passo 1 – Trocando o componente de conexão com o banco de dados. Em primero lugar os componentes SQLConnection e SQLQuery devem ser Figura10. Montando o ConnectionString excluídos do formulário para que possamos adicionar os componentes AdoConnection e AdoQuery localizados na paleta ADO. No ADO o componente responsável pela conexão é o AdoConnection. Após adicioná-lo no formulário devemos configurá-lo através do acesso ao menu Edit ConnectionString, conforme mostra a figura 7. A tela exibida por esta opção permite que utilizemos um Data Link File ou uma Connection String (figura 8). Utilizaremos esta última de forma a mostrar todo o processo de configuração da conexão. A vantagem de usar Data Link File é que os parâmetros ficam armazenados em um arquivo externo, possibilitando alterações sem a necessidade de “recompilação” do aplicativo. Para montar a Connection String acessaremos o assistente através do botão build da caixa de diálogo exibida (figura 8). Em primeiro lugar devemos configurar o Provider que irá gerenciar a conexão com o banco de dados. Escolheremos o “Microsoft OLE DB Provider for SQL Server” (figura 9). Após esta seleção devemos informar na pasta Connection os parâmetros para que a conexão seja efetuada. Indique o nome do servidor de banco de dados em “1. Select or enter a server name”, os dados para login em “2. Enter the informatino to log on to the server” e o banco de dados a ser acessado em “3. Select the database on the serever”. É importante que a opção “Allow saving password” esteja marcada para evitar erros na conexão uma vez que os parâmetros de login (usuário e senha) já estão definidos. Encerradas as configurações podemos testar a conexão através do botão “Test Connection” e em seguida encerrar o assistente através do botão ok (vide figura 10). Passo 2 – Adicionando o componente para acesso aos dados No ADO o componente a ser utilizado para substituir o SQLQuery é o ADOQuery que está na paleta ADO. Uma vez adicionado ao formulário, altere a propriedade Connection apotando-a para o objeto AdoConnection1. Altere a propriedade SQL de forma análoga ao passo 3 do exemplo com DbExpress. Feito isso, basta alterar a propriedade DataSet do DataSetProvider apontando para o ADOQuery configurado anteriormente. Altere a propriedade Active do SQL Magazine - 29 Figura12. Caixa de Diálogo de escolha do projeto no VisualStudio.NET ClientDataSet para true e pronto! (Vide figura 11). Exemplo em Microsoft VisualStudio. Net (utilizando VB.Net) Por que o VisualBasic.Net? Inicie o VisualStudio.Net e clique no menu File|New|Project. Na caixa de diálogo, clique em Visual Basic Projects e escolha Windows Applications na caixa Templates. Digite o nome do projeto e clique em OK. Após estes passos o VisualStudio.Net irá preparar o ambiente para o desenvolvimento de um projeto Visual Basic. No ADO.Net, assim como nas versões anteriores do ADO, existe o objeto Connection que permite a conexão com o Banco de Dados. Esse objeto, atualmente, não é um objeto único para qualquer tipo de conexão como antes. Agora ele é implementado em diversas classes que utilizam a interface IdbConnection em comum. Usaremos o SQLConnection, um componente Connection implemen- O Visual Basic agora faz parte de um novo conjunto de ferramentas para desenvolvimento de aplicações: a estratégia .Net. O .Net é uma nova plataforma da Microsoft, multi-linguagem, totalmente formulada para lidar com XML e Web Services e voltada para aplicações multidispositivos. Nesta plataforma, o ADO também ganhou uma nova implementação chamada ADO.Net e é este engine que iremos focalizar. O novo ADO.Net foi desenvolvido para ser uma versão bem diferente das anteriores, focando a completa compreensão do XML, o uso de DataSets desconectados e uma implementação mais leve para a Web. Figura11. Projeto com ADO finalizado 30 - Magazine SQL Figura13. SQLConnection Wizard tado para se conectar ao MSSQL-Server versão 7x e superiores, para acessar o banco Northwind que acompanha o MSSQL-Server 2000. Na ToolBox no lado esquerdo da aplicação clique na guia “Data” e insira no formulário um componente SQLConnection. Na caixa Properties clique na propriedade ConnectionString e selecione “New Connection...” (Figura4). Será exibida a janela padrão de configuração de ConnectionString do ADO. O exemplo no Delphi 7 utiliza a mesma janela e explica como configurar a ConnectionString para acessar o banco Northwind em detalhes. Configurado o componente de conexão é necessário informar de onde serão requisitados os dados. Esta requisição é feita por um objeto Command. Porém, assim como o objeto Connection, o Command possui diversas versões que variam de Provider para Provider. Por exemplo, para acessar o SQL-Server, o ADO.Net possui um Provider específico que, para ser utilizado, precisa de um SQLConnection pertencente ao namespace System.Data.SqlClient (implementação que aproveita recursos específicos do MS-SQL) e para se executar uma consulta no Banco deve-se utilizar um objeto SQLCommand, ou mesmo um SQLDataAdapter, também do mesmo namespace (ou seja, também especifico para o MS-SQL). O que implica que é necessário importar este namespace com o comando “Imports”. Na guia Data da ToolBox clique no componente SQLDataAdapter e insira-o no formulário. Automaticamente o Visual Studio irá apresentar o “Data Adapter Configuration Wizard”, que permite configu- Conectando Front-Ends com Delphi, VB.Net e Java rar de forma simples o SQLDataAdapter. Este componente tem como função facilitar o gerenciamento das requisições com o Servidor em relação ao DataSet (conjunto de registros), armazenando consultas SQL através das propriedades: DeleteCommand, InsertCommand, SelectCommand e UpdateCommand que permitem ao desenvolvedor especificar comandos SQL para controlar de forma otimizada e padronizada pelo ADO.Net os conjuntos de registros armazenados no Servidor. Utilizando o Wizard é possível configurar uma consulta simples e entender como se utiliza o SQLDataAdapter no VisualStudio.Net. Na primeira tela clique no botão “Next”, onde será exibido o passo: “Choose Your Data Connection”. Esta tela permite configurar que conexão irá requisitar os dados. Na caixa Combo pode-se especificar a conexão que já foi criada pelo componente SQLConnection inserido anteriormente. Após clique no botão “Next”. Em “Choose a Query Type” especificamos como os dados serão requisitados. Abaixo, segue uma pequena descrição de cada opção: - Use SQL statements: Permite especificar uma Query SQL que faça o retorno dos dados. O próprio Wizard irá gerar os comandos Delete, Update e Insert baseados nesta Query. - Create New Stored Procedures: Permite criar novos procedimentos armazenados a partir de uma Query SQL para os comandos Insert, Update e Delete. - Use Existing Stored Procedures: Permite especificar quais serão os procedimentos armazenados que farão os comandos: Select, Insert, Update e Delete do conjunto de registros específicos para cada situação. Será utilizada a opção “Use SQL statements” e a configuração da Query com o comando SQL abaixo: SELECT orderid, customerid, orderdate, shippeddate, shipname, shipregion, shipcountry FROM Orders Conforme visto no exemplo acima, será requisitado ao banco de dados apenas alguns campos da tabela de pedidos. Este comando SELECT será inserido na propriedade SelectCommand do SQLDataAdapter. Clique em “Next”. Serão gerados no Wizard os comandos SQL de acordo com o SELECT para configurar o componente automaticamente. Para finalizar, clique no botão “Finish”. Pronto! Foi criado um componente SQLDataAdapter que permite fazer consultas e, ainda dentro do padrão ADO. Net, modificar os dados selecionado, através da SQL gerada pelo Wizard. Os controles Data-Aware do .Net para exibir dados necessitam que estes sejam recebidos de um DataSet. Para gerar um DataSet, clique com o botão direito na figura do SQLDataAdapter no Form Designer e selecione “Generate DataSet”. Será visualizada uma caixa de diálogo onde, pressionando-se o botão “OK”, irá aparecer o componente DataSet. Em seguida insira um controle DataGrid. Linke a propriedade DataSource ao DataSet recém-gerado e DataMember a tabela Orders, visualizando os dados no grid da mesma forma que no Delphi. Por que o Java? O Java tem demonstrado seu poder com relação ao mundo multi-plataforma. Cada vez mais conhecido no Brasil, muito se tem produzido com Java. Um ponto forte do Java é o fato de grandes empresas estarem investindo nele, como as gigantes Oracle e IBM. Uma das formas de conexão de uma aplicação Java com um banco de dados é através da API JDBC. O JDBC, Java Database Connectivity, é uma API Java para conexão com SGDB´s diversos e execução de expressões SQL. Sendo mais específico, JDBC é um conjunto de classes e interfaces que permitem acesso a bases de dados relacionais de maneira uniforme, numa solução similar ao ODBC. Existem inúmeras implementações de drivers de bancos de dados compatíveis com JDBC que se enquadram em quatro categorias de soluções, definidas pela JavaSoft: Tipo 1 – Ponte JDBC / ODBC A ponte JDBC / ODBC foi desenvolvida em conjunto pela JavaSoft e a Intersolv, de modo a aproveitar a grande quantidade de drivers ODBC que já existem instalados nas máquinas. Aplicação Java faz uma chamada ao JDBC que por sua vez faz essa chamada ao ODBC e este à API de acesso nativa do banco. Tipo 2 – Driver Java Parcial + API Nativa Nesta solução o driver ODBC é eliminado e o driver JDBC converte as chamadas JDBC em chamadas diretas à API nativa do banco. Assim como os drivers do Tipo 1 é necessária a instalação de “aplicações cliente” do banco de dados na máquina onde está sendo executado o aplicativo. Tipo 3 – Driver 100% Java + Protocolo de Rede (arquitetura em 3 camadas) Nesta configuração o driver JDBC converte as chamadas JDBC em um protocolo de rede independente (independente do banco de dados). Estas chamadas são convertidas, então, em chamadas à API nativa do banco por um servidor intermediário (middleware). Essa arquitetura na verdade consiste de três camadas. Tipo 4 – Driver 100% Java: Nesta solução o driver converte as chamadas JDBC diretamente para o protocolo de rede utilizado pelo banco de dados. Escritos somente em Java, estes drivers não necessitam de ODBC nem de API nativa, gerando um enorme ganho de desempenho e permitindo o desenvolvimento de aplicações 100% Java. Exemplo em Java Utilizaremos para acessar o mesmo banco de dados dos exemplos em Delphi e VB .Net (NorthWind do SQL Server) um Driver JDBC do tipo 4 denominado Microsoft SQL Server 2000 JDBC Driver, que pode ser baixado no em http:// msdn.microsoft.com/downloads/default.asp?URL=/downloads/sample. asp?url=/MSDN-FILES/027/001/779/ msdncompositedoc.xml. Para exemplificar a conexão em Java, utilizaremos um “console application” onde será mostrado além da conexão a execução de um comando SELECT e o display dos dados retornados na tela. As classes utilizadas e os procedimentos serão explicados em seguida. Vale a pena ressaltar que este exemplo mostra uma das formas de acesso e manipulação de dados em Java (listagem1.). NOTA Nesta parte do Wizard pode-se utilizar o Query Builder do VisualStudio.Net, uma ferramenta muito interessante para desenvolver consultas SQL. SQL Magazine - 31 Listagem1 import java.sql.*; public class Principal { public static void main (String[] args) { Connection conn = null; try { DriverManager.registerDriver ( new com.microsoft.jdbc.sqlserver.SQLServerDriver()); conn = DriverManager.getConnection (“jdbc:microsoft:sqlserver:” + “//servidor:1433;DatabaseName=NorthWind;Selectmethod=cursor”, “usuario”, “senha”); } catch (SQLException e) { System.out.println (‘\n’ + “Erro na conexão com o banco.”); e.printStackTrace(); System.exit(1); } try { PreparedStatement pstmt = conn.prepareStatement(“SELECT * FROM EMPLOYESS”); ResultSet rs = pstmt.executeQuery(); while ( rs.next() ) { System.out.println(rs.getInt(“EmployeeID”) + “ - “ + rs.getString(“LastName”) + “,” + rs.getString(“FirstName”) ); } } pstmt.close(); conn.close(); } catch (SQLException e) { System.out.println (‘\n’ + “Erro ao recuperar dados no banco.”); e.printStackTrace(); System.exit(1); } } Inicialmente é declarado um objeto que irá representar a conexão com o banco de dados, neste exemplo chamado de conn, do tipo Connection. Voltaremos a falar nele adiante. Em seguida é executada a seguinte chamada: DriverManager.registerDriver( new com.microsoft.jdbc.sqlserver. SQLServerDriver()); O DriverManager é uma classe que gerencia os drivers registrados no JDBC. Este registro é feito através da chamada ao método estático registerDriver. A partir desse momento, a instância do driver passado como parâmetro passa a ser mantida pelo DriverManager e o driver 32 - Magazine SQL fica disponível para utilização pela aplicação Java. A próxima linha abre uma conexão com o banco de dados, que é atribuída para o objeto conn para ser manipulada pela aplicação. conn = DriverManager.getConnection (“jdbc:microsoft:sqlserver:” + “//servidor:1433;DatabaseName=NorthWind; Selectmethod=cursor”, “usuario”, “senha”); O método estático getConnection tem como parâmetro um String de Conexão, um String que representa o nome do usuário e um último que representa a senha do mesmo. O DriverManager verifica se o driver passado na primeira parte de String de Conexão está registrado no JDBC (como descrito anteriormente). Caso o driver esteja registrado é solicitada a conexão de acordo com os parâmetros passados na segunda parte do String de Conexão (onde temos o nome do servidor, a porta do listner, o nome do banco a ser acessado e o tipo de seleção) além do usuário e senha. Caso a conexão seja efetuada com sucesso, o objeto conn passa a “apontar” para a mesma. As linhas que seguem enviam o comando SQL para o Servidor de Banco de dados para que o mesmo seja compilado no servidor e fique pronto para execução. Este procedimento é executado através do método prepareStatement do objeto conn (instanciado pelo método getConnection visto anteriormente). Este método, se executado com sucesso, retorna um PreparedStatement que é a instância do comando “preparado” no Servidor e, no nosso exemplo, é manipulado pelo objeto pstmt. PreparedStatement pstmt = conn. prepareStatement(“SELECT * FROM EMPLOYESS”); Para acessarmos os dados do comando SQL preparado anteriormente é preciso que tenhamos um objeto do tipo ResultSet que é instânciado a partir do método ExecuteQuery() do PreparedStatement, como mostrado a seguir. ResultSet rs = pstmt.executeQuery(); Os procedimentos seguintes executam um “loop” nos dados resultantes do comando SQL contidos no ResultSet rs listando na tela os valores das colunas EmployeeID, LastName e FirstName. while ( rs.next() ) { System.out.println(rs.getInt(“EmployeeID”) + “ - “ + rs.getString(“LastName”) + “,” + rs.getString(“FirstName”) ); } Por fim, fechamos o PreparedStatement pstmt e o Connection Conn liberando com isso recursos do banco de dados e finalizando a aplicação se forma adequada. É interessante notar que todos os procedimentos referentes a conexão, a execução de comandos e manipulação de dados estão contidas num bloco protegido (try...catch) pois todos os métodos utilizados propagam SQLException, que representa uma exceção referente ao acesso ou manipulação de um banco de dados, Conectando Front-Ends com Delphi, VB.Net e Java devendo ser tratada pela aplicação. Conclusão Nosso objetivo foi mostrar os procedimentos a serem efetuados em cada uma das ferramentas analisadas para conexão e manipulação de dados de um banco no SQL Server, deixando alguns conceitos de forma a facilitar ao analista a definição sobre qual ferramenta usar para cada solução a ser implementada. De fato, não será somente a escolha da ferramenta de desenvolvimento que irá definir a melhor forma de implementar um projeto com sucesso. O analista que tiver um domínio completo do problema proposto pelo cliente (além de conhecimento e experiência em cada ferramenta) terá mais facilidade de escolher qual tecnologia se tornará mais eficiente para resolver o problema em questão. ANUNCIO SQL Magazine - 33 Acesso e manutenção de bancos com Emacs por Fabio Faldini O emacs é o editor de texto ocial do projeto GNU, integrandose, portanto, com todas as suas ferramentas. Pode ser usado como uma IDE, onde é possível editar, compilar, depurar e rodar aplicativos sem nunca precisar sair dele . Oferece recursos de edição de texto avançados como identação automática, highlight, auto-completar, pular para linha de erro automaticamente, além de estar integrado com email, news, web, gerenciadores de banco de dados, ftp, telnet e muito mais. “Perdi tudo” - grita furioso o usuário ao ver aquela mensagem de erro no console do SQLplus, depois de queimar horas escrevendo aquele comando SQL. “Porque não usei um editor de textos antes !?” Marca o texto com o mouse, Ctrl c... Ctrl v... e nada ! Tenta uma, duas, três vezes e nada... “O que está acontecendo?” Ctrl F9... mais uma vez, Ctrl F9 ... não vai ... não compila ... “O que houve?” Tenta selecionar o texto e não vai. Clica o botão esquerdo do mouse sobre aquelas linhas e nada! Essa é a reação de um analista MS-Visual Studio/Windows que começa trabalhar em ambientes heterogêneos, na frente Windows, atrás Unix, nos lados Mac, Visual Age daqui, Borland dali, Oracle, DB2, enfim... As mãos já estão acostumadas com o Visual Studio. Só de pensar em compilar, o fura-bolo esquerdo vai em direção do Ctrl e o direito em direção do F9. É assim mesmo, após anos usando os mesmos atalhos, acaba virando reflexo. O emacs veio resolver esses problemas e muito mais. Desenvolvido por Richard Stallman, o fundador do projeto GNU, foi originalmente escrito em Teco (uma linguagem de macros). Hoje em dia o emacs está na versão 21.2, podendo ser baixado no site www.emacs.org e compilado na maioria dos sistemas operacionais do mercado. O emacs é um ambiente de trabalho totalmente customizável e escalável. O usuário pode excluir, modificar e acrescentar funcionalidades e teclas de atalho tranqüilamente além da facilidade da Internet oferecer uma infinidade de componentes para serem instalados na IDE do emacs. Cada linguagem tem suas peculiaridades: highlight, compilador, interpretador, depurador... enfim, o tratamento de um fonte em C não é o mesmo tratamento dado à um fonte em Java, e menos ainda à um fonte em Lisp ou em Prolog. Como o emacs suporta tantas linguagens separadamente? Major-mode O emacs é como um esqueleto composto por vários componentes, entre eles componentes especializados para as linguagens de programação. Um conjunto de componentes especializados constitui um major-mode Acesso e manutenção de bando de dados com Emacs (modo de edição de texto). Quando um buffer (conteúdo de uma janela) é aberto, o emacs associa automaticamente a ele um major-mode para tratá-lo e controlar todos os sinais passados para o determinado buffer. O nome do major-mode usado aparece na mode-line (linha em cor inversa, situada na parte inferior da tela). Alem disso, a mode-line apresenta outras informações úteis como o tipo de texto e se o mesmo foi alterado. Vide Figura 1. Nas primeira versão do Emacs, já era notável a presença e a seleção automática dos major-modes. Quando aberto um fonte em ada (.a), logo entrava no adamode. Para um fonte em lisp (.l), entrava no lisp-mode, um fonte em prolog (.pl), entrava no prolog-mode. Para rodar os fontes em lisp no lisp-mode basta teclar o enter do keypad e logo aparecia o resultado na echo area, a linha que se encontra abaixo da mode-line. Para tratamento de código SQL, o emacs-21.2 oferece dois major-modes: o SQL-mode e o SQLi mode (modo SQL interativo). O SQL-mode controla a edição de código em SQL e o SQLi-mode interage diretamente com o gerenciador de banco de dados - mysql, oracle, postgres, informix, sybase, db2, interbase e SQLserver. SQL-Mode A forma mais simples de entrar diretamente no SQL-mode é abrir um arquivo com extensão .sql. O atalho para a abertura de um arquivo é: C-x f ( M-x find-file ) *NomeDoArquivo* RET. Se o arquivo não existir, será criado um novo arquivo vazio. Caso o arquivo não tenha extensão .sql, ou o sql-mode não for carregado, podemos carregá-lo manualmente: M-x sql-mode RET Para carregar automaticamente o SQLmode, ao abrir um arquivo com extensão .sql, basta acrescentar a linha seguinte no arquivo de configuração .emacs que fica no diretório do usuário ( ~user/.emacs ): (add-to-list ‘auto-mode-alist ‘(“\\.sql\\’” . sqlmode)) Agora a Query pode ser escrita no sql- Figura1. mode. É interessante a verificação do highlight no código escrito. Provavelmente, o código não aparecerá em highlight, já que por default, o highlight não está habilitado. Para habilitar o highlight no buffer corrente, basta digitar: M-x font-lock-mode RET Para habilitar o font-lock-mode em todos os buffers basta digitar: M-x global-font-lock-mode RET Para habilitar o font-lock-mode ao abrir qualquer arquivo, basta acrescentar as linhas abaixo no arquivo .emacs (custom-set-variables ‘(global-font-lock-mode t nil (font-lock))) SQLi-mode Após as configurações iniciais, para executarmos a Query digitada, é preciso entrar no SQLi-mode escolhendo uma das opções abaixo: M-x sql-mysql ( para usar com o MySQL ) M-x sql-informix ( para usar com o informix ) M-x sql-ingres ( para usar com o ingres ) M-x sql-postgres ( para usar com o postgres ) M-x sql-oracle ( para usar com o oracle ) M-x sql-sybase ( para usar com o sybase ) M-x sql-db2 ( para usar com o db2 ) M-x sql-interbase ( para usar com o interbase) M-x sql-ms ( para usar com SQLserver ) Por exemplo, para entrar no MySQL monitor e acessar uma base de dados, o minibuffer (localizado embaixo da modeline) vai esperar que o usuário entre com o nome do usuário, a senha, o host e o nome da base de dados. Se a opção do gerenciador de banco de dados escolhida não for reconhecida, primeiro deve-se carregar o SQL-mode e depois procurar chamar o modo desejado. Continuando com o exemplo do MyS- SQL O SQL-mode e o SQLi-mode oferecem recursos de highlight e de auto-completar. O highlight, além de colorir o código fonte também colore as mensagens exibidas no console. Para facilitar a digitação de certos comandos, o SQL-mode disponibiliza abreviações que podem ser auto-completadas com um clicar na barra de espaço. Por exemplo: sel para select , upd para update, ins para insert, del para delete, entre outros. QL seguem os procedimentos detalhados para acesso e interação com este banco de dados: A) Preparando o ambiente (este procedimento pode ser pré-configurado no arquivo .emacs): 1) Entrar no emacs 2) Abrir um arquivo em um buffer: C-x C-f *nomearq* RET 3) Habilitar o modo sql no buffer atual: M-x sql-mode RET 4) Habilitar o highlight no buffer atual: M-x font-lock-mode RET 5) Habilitar abreviações no buffer atual: M-x Abbrev-mode RET B) Acessando o banco de dados 6) Abrir o monitor do mysql: M-x sqlmysql RET 7) Entrar com o nome de um usuário do banco no minibuffer e RET 8) Entrar com a senha deste usuário no minibuffer e RET SQL Magazine - 35 9) Entrar com o nome do servidor onde está localizado o mysql no minibuffer e RET 10) Entrar com o nome da base de dados a ser acessada no minibuffer e RET 11) Avisar ao emacs qual é o buffer que contem o mysql monitor: M-x sql-setsqli-buffer RET *SQL* RET 12) Passar o foco para a janela com o buffer em sql-mode: C-x o ou com o clique do botão esquerdo do mouse sobre o buffer 13) Enviar o buffer em sql-mode para o buffer do monitor mysql: M-x M-b Pronto ! Estamos dentro do MySQL monitor! ( Figura 2 ) C) Organizando a tela 14) para quebrar a tela verticalmente: M-x 3 15) para ativar o follow-mode: M-x follow-mode RET Quem diria, o MySQL monitor a cores! Se você não estiver vendo as cores, habilite o font-lock-mode, como foi explicado anteriormente. Você terá o prazer de ter highlight na linha de comando, não é formidável? Agora você não tem mais riscos de perder tudo pela ausência do scroll na linha de comando e se quiser pode até gravar o buffer: C-x C-s ( M-x save-buffer ) *NomeDoArquivo* RET Para habilitar o modo de auto-completar, basta digitar: M-x abbrev-mode RET Como passar a Query de um buffer no SQL-mode para o MySQL monitor ? Temos várias possibilidades e a mais fácil, por enquanto, é enviar o buffer inteiro de uma só vez, assim: C-c C-b ( M-x sql-send-buffer ) *NomeDoBuffer* RET Caso apareça no echo-area, “no SQL process started”, é porque o buffer em SQL-mode não sabe qual é o nome do buffer que está em SQLi-mode. O nome do buffer aparece na mode-line à esquerda. Para passar o nome do buffer em 36 - Magazine SQL Figura2. SQLi-mode para o buffer em SQL-mode, basta entrar com o nome do buffer em SQLi-mode, assim: M-x sql-set-sqli-buffer RET *NomeDoBuffer* RET Janelas contínuas ( Follow mode ) Como sempre o resultado da Query pode ter muitas linhas, não cabendo na área visível da janela. Pois bem, o emacs oferece a possibilidade de dividir verticalmente cada janela em duas outras janelas (Figura 3), digitando: C-x 3 ( M-x split-window-vertically ) As duas janelas que aparecem apresentam o mesmo conteúdo! Para que uma janela seja a continuação da anterior, deve-se digitar: M-x follow-mode RET Para dividir uma janela na horizontal, basta digitar: C-x 2 ( M-x split-window-horizontally ) Para fechar uma única janela, basta colocar o foco do mouse sobre ela e digitar: C-x 0 (M-x delete-window) Para expandir uma janela em todo o frame: C-x 1 (M-x delete-other-windows) Modo texto O emacs não depende de ambientes gráficos multi-janelas como o MS-Windows ou Xwindow para rodar. O emacs funciona perfeitamente em modo texto podendo ser executado em modo DOS e até mesmo em uma estação de trabalho como um terminal burro. Antes mesmo que os ambientes gráficos multi-janelas se difundissem, o emacs oferecia um ambiente multi-janelas. Sem o emacs não podíamos editar, compilar e executar um programa sem precisar fechar o editor de textos para compilar e executar na linha de comando. FRAME, WINDOW E BUFFER Uma “janela” do emacs exibe o conteúdo de um único buffer. O buffer é um objeto que contém o texto editado em uma “janela” do emacs. O frame do emacs é uma janela do MS-windows ou do Xwindow. Acesso e manutenção de bando de dados com Emacs Figura3. Para evitar confusão, vamos reservar a palavra janela para as subdivisões de um frame do emacs e a palavra frame para as janelas do MS-windows ou Xwindow. Um frame do emacs pode ser subdividido em duas ou mais “janelas”. Quando executamos o emacs, por default, o frame aparece com uma única janela aberta. Este frame pode ser subdividido em duas ou mais janelas, verticalmente ou horizontalmente. Cada janela aberta tem a sua mode-line particular, porém todas as janelas de um frame compartilham a mesma barra de títulos e a mesma echoarea do frame. Um buffer inteiro, ou uma parte de um buffer, pode ser editado em uma ou mais janelas. Cada arquivo aberto é carregado em um buffer diferente. Podemos carregar inúmeros arquivos enquanto houver memória suficiente no computador. Para carregar um arquivo em um buffer, basta fazer: C-x C-f ( M-x find-file ) *nomearq* RET Todas as modificações feitas em uma janela serão refletidas em todas as janelas que estiverem editando o mesmo buffer. Quando fechamos uma janela, o espaço físico da janela é liberado para que outra janela se expanda nele, porém o buffer continua aberto. Para salvar o conteúdo do buffer, basta fazer: C-x C-s ( M-x save-buffer ) Buffer list O emacs armazena os buffers abertos na buffer-list, que é uma lista de buffers. Para saber quais buffers estão abertos, deve-se consultar a buffer-list digitando o comando abaixo (A lista de buffers abertos vai aparecer na janela adjacente): C-x C-b ( M-x list-buffers ) Vamos analisar o resultado: Estamos com 2 buffers abertos em 2 janelas. Uma janela apresenta o arquivo editado, no caso, o /tmp/teste.sql e a segunda janela apresenta o buffer que contém a própria lista de buffers. O buffer *scratch* é aberto por default depois da tela de apresentação do emacs. O buffer *messages* mantém um log das mensagens que aparecem na echo area. Podemos ver que, com exceção do buffer teste.sql, todos os outros estão entre asteriscos. O asteriscos indicam que se trata de um buffer que interage com o sistema. ANUNCIO A buffer-list também trás outras informações interessantes. Se o arquivo foi modificado, vai aparecer um * na primeira coluna e se o arquivo for read-only, vai aparecer um % na segunda coluna. A coluna size exibe o tamanho do arquivo em bytes. A coluna mode exibe o majormode do buffer. E a coluna file exibe o caminho do arquivo. Buffer Menu mode O buffer que contém a buffer-list não é um simples buffer de dados estáticos. A buffer-list está sendo editada no major-mode BUFFER MENU, que permite ao usuário manipular os buffers listados. Caso tenhamos aberto inúmeros buffers e queiramos fechar parte deles basta navegar na buffer list e marcar os buffers para serem fechados com um d (de delete), e logo aparecerá um D no lugar da primeira coluna da linha selecionada. Selecionamos todos aqueles que queremos fechar e pressionamos a letra x para fechar os buffers selecionados. Para salvar arquivos, basta selecionar com a SQL Magazine - 37 RM Buffer Size Mode *% *Buffer list* 90 Buffer Menu teste.sql 0 SQL /tmp/teste.sql * *scratch* 182 Lisp Interaction * *Messages* 1501 Fundamental letra s as linhas desejadas e executar com x. Podemos também combinar o S e o D na mesma linha. Para desmarcar, basta pressionar a letra u (de unmark) sobre a linha desejada. Para ver o conteúdo do buffer na janela adjacente, basta clicar em C-o quando o cursor estiver na linha do buffer desejado. O foco é mantido na buffer list. Para passar o foco do cursor para o buffer selecionado, em vez de pressionar o C-o, pressiona-se somente a letra o. Para abrir o buffer em uma janela que ocupe o frame inteiro basta pressionar no numero 1 na linha desejada. Em vez de entrar na buffer-list para exibir outro buffer na janela, pode-se digitar: C-x b ( M-x switch-to-buffer ) : ( default: *sql* ) RET O nome do buffer selecionado por default aparece entre parêntesis e o usuário poderá introduzir o nome do buffer desejado. Caso ele não se lembre, basta pressionar o TAB e a lista de buffer aparecerá na janela adjacente. File O emacs funcionava em terminais burros com teclado e monitor de fósforo verde, desprovidos de mouse. para mudar o foco de uma janela para outra janela do mesmo frame sem o mouse basta digitar: C-x o (M-x other-window) Boa parte dessas operações podem ser executadas via menu. Em ambiente gráfico é só clicar com o mouse no item de menu e será exibido um item pop-up. Mas em ambiente texto pressiona-se o F10 e os itens de menu aparecerão na janela adjacente. Se pressionássemos o F10 com o foco do cursor no buffer *scratch*, apareceria na janela adjacente os itens exibidos na barra de menus: Possible completions are: b==>Buffers f==>Files t==>Tools e==>Edit s==>Search m==>Mule h==>Help b==>buffers ANUNCIO 38 - Magazine SQL Para selecionar, um deles basta clicar na letra que antecede o item de menu, como b para buffer e t para tools, assim por diante. Se pressionássemos a letra b apareceria: Possible completions are: s==> *scratch* * b==>*Buffer List* *% m==> *Messages* * c==>*Completions* * l==> List All Buffers (C-x C-b) Se o teclado não pussuir o F10, não tem problema, é possível substituí-lo com M-`. Para sair dos menus, basta clicar C-g ou três vezes escape: ESC ESC ESC. Conclusão: O emacs é um ambiente de desenvolvimento integrado padronizado que pode ser compilado e executado em qualquer plataforma. Multi-janelas, multi-tarefas e multi-funcional. Não depende de ambientes gráficos, monitores coloridos, mouses e teclas especiais. Customizável, o usuário pode editar e gravar suas configurações particulares no arquivo ~usuario/.emacs para torná-las permanentes. O emacs traz consigo inúmeros componentes, entre eles o SQL-mode e o SQLi- mode. O SQL-mode facilita a edição de código SQL. O SQLi-mode incrementa a linha de comando que acompanha os gerenciadores de banco de dados. SBGD no Linux: MySQL por Clementino Leal E m se tratando de soluções em banco de dados para o linux, um dos pré-requisitos é a exibilidade na aquisição da licença do produto. Este fator é também verdade para a maioria dos softwares para este sistema operacional. o MySQL traz, além de uma política de licenciamento bastante exível, salvo algumas exceções, recursos que fazem so produto uma solução ideal para ser utilizado em ambiente Linux. O MySQL é conhecido por ser um servidor de banco de dados extremamente rápido e robusto, configurando-se numa das soluções de menor custo para redes mistas onde, por exemplo, temos estações clientes com Windows e servidores com Linux. É um Banco de dados utilizado principalmente em servidores web para persistência de dados em sites, foi desenvolvido pela T.c.X. DataKonsultAB (http://www.tcx.se) e está disponível para download em http://www.mysql.com. Ao contrário do que se pensa, O MySQL não é totalmente “free”. Com relação a sua política de licenciamento podemos destacar que ele é grátis para ser utilizado tanto em uso privado como comercial, existindo algumas restrições para aplicações a serem utilizadas em ambiente Windows ou quando for distribuído como parte VANTAGENS • Possui versões disponíveis para vários sistemas operacionais, entre eles FreeBSD, Unix, Mac OS X, OS/2 Warp 3 e 4, Solaris, SunOS, Windows 9x, Me, NT, 2000 e XP. • Facilidade de instalação e administração do Banco de Dados. • Capacidade de gerenciamento de um número ilimitado de usuários simultâneos. • Alta capacidade de manipulação de registros (mais de 50.000.000 de registros por tabela). • Execução de comandos super otimizada; • Simples e eficiente sistema de privilégio de usuários. integrante de uma solução. A versão utilizada aqui do MySQL é a 3.23. O MySQL também está disponível na versão MySQL/Max, que disponibiliza através de configurações adicionais o suporte a transações e foreign keys para determinados tipos de tabelas. A versão 4.0, em desenvolvimento, inclui o suporte completo a transações, além de suportar locks de linhas. Para versões futuras estão previstas as implementações de backup online e recursos de recuperação segura contra falhas no desligamento. Mais informações estão disponíveis em http://www.mysql. com/products/mysql-4.0/index.html; Instalação No Linux Os arquivos de instalação do MySql Servidor e Cliente estão disponíveis para download em http://www.mysql.com. DESVANTAGENS • Não suporta transações (Commit, rollback, níveis de isolamento ) • Não faz lock de linhas na atualização • Não suporta constraints (Chave primária e chave estrangeira, com capacidade de habilitar/desabilitar ou dropar/adicionar. ) • Não tem recursos contra falhas no desligamento do banco durante atualizações de dados. • Não executa backup consistente com a base de dados no ar e se atualizações estiverem sendo efetuadas. 1) Instale o servidor com o comando: Shell do Linux> rpm –ivh MySQL-3.23.53a-1.i386.rpm 2) Instale o cliente com o comando: Shell do Linux> rpm –ivh MySQL-client-3.23.53a-1.i386.rpm 3) Depois da instalação teremos que definir uma senha para o usuário root com o comando: Shell do Linux> mysqladmin –u root –p password ‘senha’ Ele pedirá para confirmar a senha, pois no primeiro acesso após a instalação a mesma não estará ainda definida. O tempo total de instalação foi de aproximadamente 2 minutos sem a necessidade de configurações adicionais, disponibilizando de imediato o banco para uso. Durante a instalação do MySQL é criado um banco de dados, chamado mysql, contendo cinco tabelas: db, host, user, tables_priv e columns_priv, que implementam o controle de acesso aos dados no MySQL. Conectando ao Banco Para entrar no banco digite: Shell do Linux> mysql –u root –p ‘-p’ Pedirá a senha do usuário. Welcome to the MySQL monitor. Commands end with ; or \g. Type ‘help’ for help. Tipos de Dados mais utilizados no MSQL CHAR(M) – É usado para representar strings de tamanho fixo, onde M pode ter de 1 à 255 caracteres. VARCHAR(M) – Também é usada para representar strings, sendo mais flexível do que o tipo CHAR, por armazenar o dado de forma variável, onde M pode ter de 0 à 255 caracteres. É aconselhável usar este tipo de dados no lugar do CHAR, uma vez que só é armazenado a quantidade de caracteres que o dado contém. Para o tipo CHAR, todo o “tamanho” referente ao campo é alocado, mesmo que ele não preencha todos os caracteres. INT [(M)] [Unsigned] – Este tipo armazena inteiros que variam de -2147483648 a 2147483647 com sinal. Se for usado Unsigned, o intervalo será 0 a 4294967295. FLOAT [(M,D)] – Representa números decimais de precisão simples. DOUBLE [(M,D)] – Representa números decimais de precisão dupla. DATE – Armazena datas. O formato default é ‘AAAA-MM-DD’ Intervalo de ‘1000-01-01’ a ‘9999-12-31’. DATETIME – Armazena data e hora no formato ‘AAAA-MM-DD HH:MM:SS’. Intervalo de ‘1000-01-01 00:00:00’ a ‘999912-31 23:59:59’. TEXT / BLOB – Este tipo de dado é utilizado para strings de 0 ate 65535 caracteres de armazenamento. SET (“valor1”,”valor2”,...) [NOT NULL] – Permite especificar uma lista com até 64 valores dos quais um ou mais podem ser atribuídos a coluna. Exemplo: sexo SET(“M”,”F”) NOT NULL; transporte set (“caminhao”,”furgao”); contendo arquivos que correspondem a tabelas do mesmo. Para criar uma base digite: mysql> create database sqlmagazine; Após a execução deste comando, será criado no diretório de dados do MySQL um subdiretório vazio com o nome sqlmagazine. Ocorrerá um erro se o banco de dados sqlmagazine já existir ou se o usuário logado não possuir o privilégio apropriado para criação de uma base de dados. Uma vez criada a base de dados deve-se “usá-la”, ou seja, torná-la ativa para que sejam manipulados os objetos e dados contidos nesta base. Digite: mysql> use sqlmagazine; mysql> Criando Tabelas A partir da entrada no MySQL Monitor, é possível criar uma base, usar uma já existente, consultar informações etc. Alguns comandos administrativos podem ser visualizados digitando help, \h ou ? na linha de comando. Para consultar as bases existentes digite: mysql> show databases; Uma vez conhecidos os tipos de dados mais utilizados, é possível criar as tabelas do banco de dados. Para tal digite: mysql> create table cliente ( > codigocliente INT NOT NULL, > nome VARCHAR(30), > endereco VARCHAR (30), > cidade VARCHAR (30), > uf CHAR (2), > PRIMARY KEY(codigocliente)); Nota-se que o comando foi seguido por um ponto-e-vírgula (;). Quase todos os comandos no MySQL são seguidos por um ponto-e-vírgula. Caso este não seja digitado, o cursor passará para a próxima linha do prompt aguardando o complemento do comando. Para consultar as tabelas existentes, digite na base em uso: Criando um Banco de dados Atribuindo Privilégios No MySQL os bancos de dados são implementados como diretórios Como citado anteriormente, o MySQL possui um sistema simples e eficiente 40 - Magazine SQL mysql> show tables; Para consultar as colunas da tabela cliente criada anteriormente, digite: mysql> show columns from cliente; para atribuição de privilégios de acesso a usuários. No nosso exemplo, estamos conectados com o usuário local root e com o banco sqlmagazine em uso. Poderíamos atribuir direitos de acesso a tabela cliente criada em nosso exemplo a outro usuário através do comando mysql> grant select on cliente to nomedousuario; A opção de grant é bem mais abrangente que o simples acesso a uma tabela por determidado usuário. Vejamos a sintaxe geral do comando: grant privilégio [ (colunas) ] [, privilégio [ (colunas)... ] on {*.* | * | bd.* | bd.tabela | tabela } to usuário@host [ identified by ‘senha’] [, ...] [ with grant option ] Onde os termos entre colchetes são opcionais, os termos entre parênteses representam um ou mais elementos e os termos entre chaves são obrigatórios com os possíveis valores indicados. Para os termos em destaque temos: privilégio: Se refere ao privilégio a ser atribuído. Podemos destacar os seguintes: all [ privileges ] - Todos os Privilégios. alter -Alterar tabelas e índices. create - Criar bancos de dados e tabelas. delete - Eliminar linhas de tabelas. drop - Eliminar bancos de dados e tabelas. index - Criar e eliminar índices. insert - Inserir linhas em tabelas. select - ler dados de tabelas. update - alterar linhas em tabelas. usage - sem privilégios. colunas: Nomes das colunas às quais os privilégios devem ser aplicados on:Especifica o nível do privilégio *.* - Atribui os privilégios a todas as tabelas em todos os bancos de dados do servidor. * - Atribui os privilégios a todas as tabelas do banco de SGBD no Linux: MySQL dados corrente. bd.* - Atribui os privilégios a todas as tabelas do banco de dados especificado. bd.tabela - Atribui os privilégios a todas colunas da tabelas especificada. tabela - Atribui os privilégios a todas colunas da tabelas especificada no banco de dados default. to: Especifica o(s) nome(s) do(s) usuário(s) a ter(em) privilégios atribuídos. Formato usuário@host. usuário - Nome do usuário ou string vazio para especificar um usuário anônimo. host - Nome do host, ou endereço IP. Identified By - Atribui uma senha ao usuário, ou altera a senha de um usuário existente. with Grant option: Permite ao usuário atribuir a outros usuários qualquer um dos seus privilégios no nível de privilégio especificado. Manipulando o Banco de dados A manipulação dos dados armazenados num banco se dá de quatro formas: inserção, alteração, deleção e seleção de um ou mais registros. Com base na tabela de cliente criada anteriormente seguem alguns exemplos: Para inserir um registro numa tabela já existente digite: mysql> INSERT INTO cliente (codigocliente, nome, endereço, cidade, uf) VALUES Ø (1,”JOSE DA SILVA”,”RUA ALTA,30”, “RIO DE JANEIRO”,”RJ”); mysql> INSERT INTO cliente (codigocliente, nome, endereço, cidade, uf) VALUES Ø (2,”MARIA DA SILVA”,”RUA BAIXA, 25”, “NITEROI”,”RJ”); mysql> INSERT INTO cliente (codigocliente, nome, endereço, cidade, uf) VALUES Ø (3,”JOAO SOUZA”,”RUA ESTREITA, 50”, “SAO PAULO”,”SP”); Para selecionar registro(s) de uma tabela já existente, digite: mysql> SELECT * FROM cliente; Para apagar registro(s) numa tabela já existente, digite: mysql> DELETE FROM cliente WHERE codigocliente = 3; Operadores Lógicos AND (&&) mysql> SELECT * FROM cliente WHERE uf = “RJ” AND cidade = “NITEROI”; mysql> SELECT * FROM cliente WHERE uf = “RJ” && cidade = “NITEROI”; Mostrará os registros que tenha uf=“RJ” e ao mesmo tempo a cidade= NITEROI” OR ( || ) mysql> SELECT * FROM cliente WHERE uf = “RJ” OR cidade = “SAO PAULO”; mysql> SELECT * FROM cliente WHERE uf = “RJ” || cidade = “SAO PAULO”; Mostrará os registros que tenha uf = “RJ” ou cidade = “SAO PAULO” NOT (!) mysql> SELECT * FROM cliente WHERE uf != “RJ” ; Mostrará os registros que tenha uf diferente “RJ”. Modificando uma Tabela Para Renomear uma tabela já existente, digite: mysql> ALTER TABLE cliente RENAME c-lientenovo; Para adicionar uma coluna a uma tabela já existente, digite: mysql> ALTER TABLE clientenovo ADD datanasc DATE; Para alterar uma coluna de uma tabela já existente digite: mysql> ALTER TABLE clientenovo CHANGE nome nomecliente VARCHAR(30); Para remover uma coluna de uma tabela já existente, digite: mysql> ALTER TABLE clientenovo DROP complemento; Mostrará todos os registros da tabela. Conclusão mysql> SELECT * FROM cliente WHERE uf = “SP”; Até então a ausência de transações vinha se mostrado um ponto negativo para a utilização do Mysql de forma mais abrangente, embora existam muitas aplicações, como por exemplo as de armazenamento de conteúdo dinâmico para websites, que não exijam transações e se beneficiem sobremaneira do ganho de performance obtido com a sua ausência, uma vez que desfazer programaticamente uma operação com múltiplas tabelas é trabalhoso e não muito utilizado. Hoje, esta questão já não pesa tanto para utilização do MySQL devido ao suporte parcial a transações, constraints e foreign keys. No futuro o próximo o Mostrará todos os registros com a uf=“SP”. mysql> SELECT * FROM cliente WHERE uf = “RJ” ORDER BY nome; O “Order By” trará os registros ordenados por nome. mysql> SELECT * FROM cliente WHERE nome LIKE“J%”; O “LIKE” substitui o “=” para fazer uma procura estimada e não exata. O “%” funciona como um coringa que substitui qualquer caractere. Para alterar registro(s) numa tabela já existente, digite: mysql> UPDATE cliente SET endereco = “RUA ESTRELA, 65” WHERE codigocliente = 3; Um pequeno exemplo Segue um pequeno exemplo escrito em Java mostrando o acesso ao banco e as tabelas criadas neste artigo. A aplicação não disponibiliza uma interface gráfica, ela simplesmente efetua a conexão com o banco e lista num console os dados da tabela CLIENTENOVO criada anteriormente. O Driver JDBC MySQL utilizado para o exemplo pode ser baixado no endereço http://www.mysql.com/ downloads/api-jdbc-stable.html. import java.sql.*; public class Principal { public static void main (String[] args) { Connection conn = null; try { //registra o driver do mysq no jdbc DriverManager.registerDriver ( new com.mysql.jdbc.Driver() ); //verifica se o driver está registrado e abre uma conexão com o banco de acordo //com os parâmetros do método getConnection conn =DriverManager.getConnection (“jdbc:mysql://localhost/sqlmagazine?user=root”); } catch (SQLException e) { System.out.println (‘\n’+“Erro na conexão com o banco.”); e.printStackTrace(); System.exit(1); } try { //envia o comando para o banco de dados para que / //ele seja “compilado” pelo banco //otimizando dessa forma a resposta do banco //quando o mesmo for executado PreparedStatement pstmt = conn. prepareStatement(“SELECT * FROM CLIENTENOVO”); //executa o comando preparado e retorna um //ResultSet para ser manipulado pela aplicação ResultSet rs = pstmt.executeQuery(); while ( rs.next() ) { System.out.println(rs.getInt(“CODCLIENTE”) +“ -“ + rs.getString(“NOMECLIENTE”)); } pstmt.close(); conn.close(); } catch (SQLException e) { System.out.println (‘\n’ + “Erro ao recuperar dados no banco.”); e.printStackTrace(); System.exit(1); } } } suporte completo a transações, locks de linhas durante a atualização, backup on-line e recuperação segura agregarão valores a benefícios já existentes como alta performance, simplicidade de instalação, manutenção reduzida e versões para vários sistemas operacionais, fazendo com que o MySQL seja utilizado de forma mais abrangente. SQL Magazine - 41 Conquistando novas fronteiras PostgreSQL A por Giselli Nichols pesar dos sistemas de código aberto se mostrarem desaadores para muitos desenvolvedores, uma parcela considerável de usuários ainda resiste em adotar um software que não pertence a ninguém. Preocupada com a questão da credibilidade e continuidade de desenvolvimento do PostgreSQL, um banco de dados relacional que permite ao desenvolvedor a criação de operações totalmente personalizadas, a dbExperts resolveu fazer a ligação do mundo virtual com o real. De acordo com Roberto Stern, diretor da softhouse brasileira, a necessidade de um contato físico com o produto ainda faz parte do processo de fidelização do cliente. “O consumidor quer tocar o produto e ter a certeza de que no dia seguinte não vai sumir da internet. Apesar de trabalharmos com o mundo virtual, vivemos no mundo real e é ele que fala mais alto.”, esclarece. Segundo o executivo, a estratégia da empresa está apresentando resultados. Desde seu lançamento em março do ano passado, foram vendidas 1.350 cópias do PostgreSQL. Só este ano, 900 cópias foram comercializadas e a expectativa para 2003 é de que 1.500 licenças sejam contratadas. Para justificar o preço de R$ 485 praticado para um sistema originalmente open source, a dbExperts fez algumas alterações no PostgreSQL agregando valor ao banco de dados. Introduziu um instalador para Linux e uma versão única para Windows e Mac OS X. O pacote de distribuição da versão dbExperts PostgreSQL Professional inclui ainda toda documentação em português, 30 dias de acesso a suporte local e um cartão-resposta que dá direito a um incidente de suporte de desenvolvimento. “Tivemos cuidado com o usuário. Criamos um canal de distribuição e desenvolvemos o design da embalagem”, acrescenta Stern. A escolha do PostgreSQL pela dbExperts foi criteriosa. A empresa brasileira, há mais de 12 anos no mercado de desenvolvimento de banco de dados, viu no aplicativo um meio seguro de conquistar mercado. “O banco é robusto, rápido e era pouco conhecido até iniciarmos nossa distribuição, o que nos garantia uma boa margem comercial”. A empresa está preparando uma nova versão, com lançamento previsto para janeiro do próximo ano e promete muitas novidades. Entre as implementações está a replicação das instalações centralizadas, agenda, ferramentas de CRM e gerenciador de projetos. A estratégia original da dbExperts em alcançar pequenas e médias empresas está mudando um pouco de foco. Hoje, o mercado corporativo é um dos alvos de venda. A mais recente aquisição do pacote foi feita pela Vésper. A empresa de telefonia fixa, com presença em 80 municípios brasileiros, adotou o PostgreSQL para algumas aplicações. Para José Luis Dadario, Diretor de Projetos Especiais de TI, o PostGre substitui com vantagens outros bancos de dados similares. “Resolvemos adotar o Pos- Conquistando novas fronteiras PostgreSQL tgreSQL pela redução de custo, pois vimos que em algumas aplicações não haveria necessidade de continuarmos com bancos shareware”. A empresa iniciou a migração dos dados em abril e pretende concluir o processo até o final do ano. A versão brasileira do PostgreSQL opera em múltiplas plataformas, incluindo Windows 95/98/ME/NT e 2000, Linux e FreeBSD. Com características adequadas ao padrão ACID (Atomicidade, Consistência, Isolamento e Durabilidade) de bancos de dados, pode ser utilizado tanto em redes ponto-a-ponto, cliente/servidor ou em ambientes mono-usuários. O licenciamento é por servidor, suportando inúmeros usuários simultâneos sem custo adicional. Para os ambientes Linux e FreeBSD, a licença da dbExperts permite que o software seja livremente utilizado e distribuído. O mesmo CD pode ser reinstalado um número ilimitado de vezes em qualquer servidor. Já a licença para os sistemas operacionais Windows e Mac OS X é limitada por servidor, de acordo com a quantidade de licenças adquiridas. Se o cliente possuir dois servidores vai precisar de duas licenças separadas. Não há limite para o número de estações de trabalho locais ou usuários de Internet que acessem o servidor simultaneamente. O dbExperts PostgreSQL Professional 7.2 é um sistema de gerenciamento de banco de dados relacional (SGBDR) avançado que possui extensões objeto-relacionais e características de banco de dados orientado a objetos (OODB). Fornecido com o código fonte para as versões Linux e FreeBSD, permite ao desenvolvedor criar e adicionar novas funções, adequando totalmente a operação do banco de dados às suas necessidades específicas. O PostGreSQL é um banco de dados com uma gama considerável de recursos, incluindo o suporte a transações, stored procedures e triggers, internacionalização e diversos recursos de segurança. Overview O PostgreSQL surgiu em 1977, na Califórnia, EUA, como um projeto acadêmico para a criação de um sistema 100% Unix. Batizado inicialmente como Ingres, o SGBDR deu origem à Relational Technologies, empresa que melhorou o código original, sendo posteriormente adquirida pela Computer Associates. Características MySQL Freeware Open Source Portabilidade PostgreSQL Interbase Adabas X X X X versão D personal X X menos para NT X - Linux, NT, FSDB, Sun SI, Windows 95, 98, ME, NT, 2000, XP e Mac OS X Linux, NT - Windows NT, 95 e 98 UNIX- IBM AIX - SNI Sinix - SUN Solaris- Linux - Windows NT, 95 e 98 Referencial X X X Linux, FSDB Stored Procedures/Triggers NT, - Transações concorrentes - X - X Sem limite de usuários X X X 3 sessões concorrentes Integridade referencial - X X X Transações - X X - ODBC Free X X X - Estabilidade X X X X Disponibilidade (backup HOT) - X X X Amigabilidade/Interface * *** *** * Suite de apoio ao desenvolvimento Exige ferramentas adicionais Extrator de relatórios Exige ferramentas adicionais Enquanto isso, na Universidade de Berkley, uma equipe de universitários passou a desenvolver um servidor de banco de dados objeto-relacional que foi nomeado de Posgres (“pós” Ingres). Em 1986, a empresa Illustra Corporation lançou a versão comercial do produto. Comprado pela Informix, o banco foi integrado ao Informix Universal Server. Em 1995, dois estudantes de graduação de Berkeley incrementaram o projeto, adicionando a linguagem SQL, resultando no Postgres95. A partir de 1996, o banco ganhou o nome denitivo de PostgreSQL. Principais Características Transações – Suporte a múltiplas transações online concorrentes entre usuários. Comandos COMMIT e ROLLBACK totalmente suportados. Backup Online – Realiza cópia de segurança de um ou todos os bancos de dados sem a necessidade de desconectar os usuários, mesmo com transações simultâneas ativas. Triggers – Perfeitamente suportados. Segurança de acesso – Respeita definição de grupos e perfis e ainda oferece a opção de limitação por HOST que poderá acessar o banco. Stored Procedures – São perfeitamente aceitos. Objeto-relacional – Permite ao PostgreSQL herdar tipos de dados, tabelas e bancos de dados inteiros. Tipos de dados definidos pelo usuário – Além dos tipos de dados convencionais, o usuário pode criar um tipo de dados customizado que atenda às suas necessidades. Funções definidas pelo usuário – Além das funções já disponíveis no PostgreSQL, o usuário pode criar funções nas linguagens internas (PL/pgSQL, PL/Tcl e PL/Perl) ou em C através de módulos carregáveis .so e .dll. Integridade de dados – As transações são escritas em um log além de serem registradas nos arquivos de dados, permitindo que o sistema aplique um rollback/ rollforward no caso de um encerramento anormal do servidor. webSITES www.postgresql.org www.dbexperts.com.br developer.postgresql.org SQLAutor Giselli Nichols (gnichols@sqlmagazine) é jornalista, com pós-graduação em Assessoria de Imprensa, webwriter e webdesigner. SQL Magazine - 43 Os melhores recursos para Replicação por Paulo Ribeiro R eplicação é uma feature importantíssima nos SGBD’s atuais - consiste em copiar, distribuir e manter a sincronia entre dados, estes normalmente situados em servidores distintos. O modelo desenvolvido pela Microsoft para o SQL Server, que desde a versão 6.0 agregou replicação de dados em seu engine, será o enfoque nesta edição. No mundo corporativo, a replicação de dados está nitidamente ligada a ambientes distribuídos, onde o acesso a dados básicos (descrição de um produto numa loja, por exemplo) é feito no próprio local da consulta. Acessando dados localmente, reduzimos a possibilidade de conflitos e otimizamos tráfego de dados nos links de comunicação entre as instalações distribuídas, que muitas vezes constituem gargalos nos sistemas. A escolha do modelo de replicação adequado depende das características do negócio. Considere-se uma empresa com gestão de preços centralizada chamada “Corp”, com matriz de mesmo nome em São Paulo-SP e filiais no Paraná-PR, Rio de Janeiro-RJ e Rio Grande do Sul-RS. Abaixo, seguem algumas perguntas que direcionam na escolha do modelo apropriado: a) A distribuição de dados deve ser efetuada de maneira unilateral (da base central para as filiais) ou a própria loja poderá alterar o preço dos produtos? Se a própria loja alterar o preço de um produto, será preciso distribuí-lo para as demais? b)Qual a latência desejável para sincronia dos dados? c) As filiais devem receber somente os preços praticados naquele local ou uma loja deve possuir acesso aos preços praticados em toda a rede? d) A sincronização deve ser feita sempre para toda a lista de produtos ou somente para os produtos cujo preço foi alterado? A Microsoft, em face desses questionamentos, sugere três modelos para réplica de dados - Transacional, Merge e Snapshot - que serão analisados tomando por base a empresa fictícia “Corp”, onde toda a rede pratica a mesma política de preços, ditada pela matriz em atualizações semanais de listas. O Modelo Transacional Como o próprio nome sugere, esse modelo baseia-se na atualização das filiais a partir do log de transações copiado do servidor principal. Ao atualizar o preço de um produto em “Corp” (figura-1), o log do comando que gerou essa alteração será copiado para uma base específica (“Distrib”), para posterior distribuição nas filiais de RJ, PR e RS. Resumidamente, a replicação transacional armazena e distribui comandos de manipulação de dados (Insert/Update/Delete) nas tabelas assinaladas para réplica de dados. Note que a atualização é unidirecional (Central => Filiais). Os Melhores recursos para replicação de dados O Modelo Snapshot Na replicação Snapshot, os objetos são exportados integralmente a cada execução de um job específico no distribuidor, também conhecido como “agente de sincronização”. Isto significa que as listas de preços nas filiais seriam substituídas semanalmente por cópias atualizadas, independentemente de alteração de preços. Essa modalidade de replicação não controla atualizações, inserções e/ou deleções; simplesmente substitui uma cópia por outra. O Modelo Merge Baseia-se em triggers criadas nas tabelas replicadas. Essas triggers fazem a movimentação de dados para tabelas de sistema responsáveis pela sincronização entre as bases replicadas. Os Jobs ou “Agentes de Sincronização” que, no modelo snapshot eram específicos do distribuidor, agora funcionam em todas as instalações distribuídas. Eles identificam as alterações e desencadeiam o processo de atualização nas bases replicadas. Observe-se que, na figura-3, o preço Y, alterado diretamente no ponto de venda PR, deve ser atualizado primeiramente em “Corp” para que depois seja sincronizado com os outros pontos. Um fato interessante diz respeito ao que aconteceria se, na empresa “Corp”, após uma reestruturação, fosse permitido que as filiais tivessem autonomia para alterar e divulgar preços para as outras filiais e, conseqüentemente, em duas filiais, o preço de um mesmo produto fosse alterado para valores diferentes. Na sincronização semanal, surgiria um impasse: que preço aplicar para a rede? O mais baixo? Aquele que foi primeiramente registrado? A replicação merge possui um tratamento especial para conflitos, que permite rastrear e resolver esse tipo de problema. O algorítmo é bastante simples: na criação do modelo, são definidas prioridades para cada participante, vencendo quem possuir a maior. Se o preço do produto X for alterado na filial RJ (prioridade 0.3) para R$ 4,00, e na filial RS (prioridade 0.8) para R$5,00, na ocasião do conflito o preço da filial RS seria vencedor, sendo então repassado para a rede. Segue agora um exemplo prático para criação do processo de replicação. Serão definidas, passo a passo, as etapas existentes na criação de um modelo que atenda Figura1. a empresa “Corp” na distribuição de listas de preços para suas filiais. O primeiro passo é registrar no Enterprise Manager todos os servidores envolvidos (\\Corp, \\Distrib, \\PR, \\RJ e \\RS ) com uma conta que possua privilégios de “system administrator”, aqui chamada de “replicador”, especialmente criada para esse fim. Definição do distribuidor A replicação é um processo complexo que envolve agentes específicos para o controle das diversas operações. O passo inicial é, portanto, definir um servidor, aqui chamado de Distribuidor, para gerenciar esses agentes. As atribuições de um distribuidor envolvem armazenamento, distribuição e controle das cópias de dados. É aconselhável que o Distribuidor esteja num servidor separado do banco de dados por questões de segurança (uma vez que ele precisa ter acesso as instalações distribuídas e, se o banco de dados estivesse fisicamente na mesma máquina, teríamos o risco do acesso indevido a dados da base corporativa) e também da otimização do processamento tanto do distribuidor, que executa os jobs referentes a replicação, quanto do banco de dados que, se acessado por outros clientes, não teria sua performance prejudicada. No servidor \\Distrib, selecione Replication\ ConfigurePublishing . Na próxima tela confirme Make “Distrib” its own Distributor e prossiga (Vide Figura 4). “Snapshot Folder” é uma pasta que deve ser criada no distribuidor para armazenamento temporário do schema e dados para inicialização das subscrições (como podemos chamar as filiais receptoras das atualizações). Deve ser uma pasta pública e visível pelas subscrições. (Vide Figura 5) Pra prosseguir selecione No, user the following default settings em Customize Configuration. Figura2. Figura3. Figura4. Definição do publicador, publicação e modelo de réplica É necessário definir que o servidor \\ Corp (onde é efetuado o cadastro e alteração das listas de preços), utilizará os serviços de \\Distrib para divulgação das listas nas filiais. Nesse contexto, \\Corp passa a ser chamado de “Publicador”, por ser responsável pela publicação da lista de preços. Inicialmente, é preciso liberar o acesso de \\Corp aos serviços do distribuidor. SQL Magazine - 45 Figura5. Figura6. Figura7. Figura8. server (the selected server must already be configured as distributor) “. Em seguida seleciona-se o database “db_Corp” como publicador e posteriormente o modelo de replicação. Note que as listas são atualizadas somente no Publicador (\\Corp); as alterações de preços devem ser enviadas de maneira incremental para as filiais, o que justifica a escolha do tipo Transacional. Clique em next para a definição dos tipos de subscrições. Para isso, na máquina \\Distrib, entre no Enterprise Manager e clique com o botão direito do mouse em Replication. No menu, selecione “Configure Publishing, Subscribers and Distributor” e escolha a guia Publishers conforme a figura 6. Na guia Publishers, deve-se liberar o acesso de \\Corp para utilização dos serviços de \\Distrib (preste atenção pois esse procedimento é executado no distribuidor \\Distrib) identificando o servidor Corp como Publisher. Para isso, marque a Check Box e clique nas reticências ao lado de “...distribution...”. Informe a conta e senha que devem ser utilizadas quando o agente de leitura – também conhecido como “Log Reader”- se conectar no publicador para leitura do log de transações a fim de efetuar a replicação. Essa conta, como informado no início, é conta definida no servidor de domínio da rede e deve possuir privilégios de “system administrator” em todos os servidores envolvidos na replicação (\\Corp, \\Distrib, \\RJ, \\PR, \\RS). Uma vez definido que \\Corp poderá efetuar publicações controladas por \\Distrib o próximo passo será a criação da publicação. Para isso, no servidor \\Corp, clique com o botão direito do mouse em Publication e selecione “New Publication” (figura 7). O modelo selecionado para a replicação será o modelo transacional, pois, de acordo com as regras de negócio do exemplo que envolve a replicação de uma tabela de preços, a entrada de dados ocorre num único ponto, com distribuição centralizada, as bases replicadas não inserem ou alteram dados e, neste caso, é exigido uma alta fidelidade da réplica com as bases publicadas. Dando continuidade, na tela “…Select a Distributor ...”, é indicado o servidor \\Distrib, na opção “...Use the following As filiais receptoras das alterações de preços passam a ser conhecidas por Subscrições. Serão criadas, portanto, três subscrições, uma para cada filial (RJ, PR e RS). Nesse momento, será definido também que cada filial deverá receber uma carga inicial, que inclui criação do schema da tabela “Preco_Item” e respectiva carga de dados. Como nosso ambiente é baseado na plataforma SQL Server 7.0 & 2000 é aconselhável a seleção das duas opções marcadas na figura 9. No próximo passo especificaremos os Artigos. Artigo é a unidade básica de replicação. Um artigo pode representar uma tabela ou uma stored procedure. Consideraremos o artigo “Preco_Item”, envolvendo, a tabela de mesmo nome, localizada no database “db_Corp” no servidor \\Corp. (Vide Figura 10) Nas reticências (...) ao lado da tabela “Preço_Item”, são confirmadas as opções em evidência na guia “Snapshot” , conforme é mostrado na figura-11. O snapshot (carga inicial da tabela “Preço_Item” nas subscrições) deverá criar a estrutura da tabela, carregando também índices e foreign keys. Se por algum motivo a tabela já existir no destino, sua es- Figura11. Figura12. Definição dos tipos de subscrições Figura9. Figura10. 46 - Magazine SQL Os Melhores recursos para replicação de dados trutura deverá ser atualizada. Após a indicação do nome da publicação como “Lista_Preços” a etapa é confirmada e não é aconselhável mais nenhuma customização, pois todas as filiais recebem o preço de todos os produtos, bastando apenas a finalização da criação da publicação. Criação e inicialização das subscrições Ao término da criação da publicação definiremos as subscrições em \\PR, \\ RJ e \\RS. Antes, porém, é necessário conceder permissão a essas subscrições para que assinem a publicação “Lista_Preços” definida no servidor \\Corp. Para isso, deve-se expandir o servidor \\Corp, o database “db_Corp” e clicar com o botão direto do mouse em “Publication” acessando o menu “ Configure Publishing, Subscribers and Distribution ...” conforme demonstrado na figura-12. Na guia Subscribers as subscrições \\ PR, \\RJ e \\RS devem estar habilitadas para que possam assinar a publicação a ser definida em \\Corp . Clicando nas reticências, é obrigatório que o usuário “replicador” - utilizado pelos jobs de sincronização – esteja assinalado em “Use SQL Server”. Basicamente, a replicação Transacional fornece dois tipos de subscrição: Push e Pull. Na modalidade “Push”, o distribuidor “empurra” as alterações para as subscrições; todo o processo de distribuição é controlado por jobs localizados no Distribuidor. No modo “Pull”, as filiais “puxam” as alterações do distribuidor; o job que controla esse processo está localizado na própria subscrição. Por facilidade de administração (todas as filiais podem ser controladas de um ponto único no distribuidor) escolheremos o modelo “Push”. Para isso selecione a publicação Lista_Preços no database db_Corp em \\Corp e, com o botão direito do mouse, selecione o menu “Push New Subscription”. Vide figura 14. Prossiga selecionando as subscrições (figura-15) e o nome dos databases nas mesma (figura-16). Os nomes dos databases nas subscrições \\PR, \\RJ e \\RS são, respectivamente, “db_PR”, “db_RJ” e “db_RS”. O Próximo passo é definir a periodicidade de sincronização. Neste exemplo utiliza- Figura13. remos um schedule para sincronizar as filiais aos domingos, às 07:00hs da manhã. Vide figura 17. Confirme a inicialização da subscrição em “Yes, inicialize the schema and data” (figura 18) e prossiga finalizando o processo. Confirme no Enterprise Manager em \\Distrib a criação da subscrição. Vide figura 19. O último passo é a execução do snapshot, que irá inicializar a réplica na loja. Selecione em Distrib “Lista_Precos” e no painel da direita clique com o botão direito do mouse em “Snapshot”. selecione “Start”. Será então efetuada a cópia do schema da tabela “Lista_Item” seguida da carga inicial dos dados. À partir daí um job schedulado no servidor \\Distrib se encarregará da atualização semanal. Para criação das outras subscrições, basta repetir os processos a partir do passo 4. Figura14. Figura15. Figura16. EscolhaReplicaçãoTransacionalquando: - A entrada de dados ocorre num único ponto, com distribuição centralizada; - As subscrições não inputam dados; - As características do negócio exigem alta fidelidade da réplica com as bases publicadas (=latência baixa). Escolha Replicação Snapshot quando: Figura17. - O volume de alterações de dados for significativamente alto e justifique a substituição por completo das réplicas; - A atualização das bases replicadas ocorrer com menor frequência (=latência alta); - As subscrições utilizarem as bases replicadas somente para leitura. Escolha Replicação Merge quando: Figura18. - Todos os participantes são responsáveis por alterações, inclusões e deleções nas estruturas replicadas. Seu objetivo é tornar o ambiente homogêneo, mesclando dados oriundos de vários locais. Figura19. SQL Magazine - 47 O banco de dados Java da Borland JDataStore por Edgar Silva A Borland ao longo dos anos vem ganhando cada vez mais respeito no mercado Java. A companhia, que tornou o JBuilder o IDE mais utilizado do mundo, mantém mais uma frente Javanesa: O JDataStore. Além de ser “Pure Java”, o banco possui uma característica curiosa: seu arquiteto, Sérgio Cardoso, é um dos brasileiros que trabalham na Borland USA. Para utilização de um banco de dados em Java, é necessário que se utilize a JDBC. Semelhante ao modelo ODBC da Microsoft, a JDBC é uma “ponte” entre o aplicativo e o banco de dados. O JDBC e o ODBC têm por base a mesma idéia: deixar transparente para o aplicativo qual banco de dados que está sendo utilizado. A API JDBC é dividida em quatro classes de acesso. Cada uma destas classes possuem características únicas que definem como o banco será acessado, apresentando vantagens e desvantagens, dependendo do tipo da aplicação. Veja abaixo um pequeno resumo dos tipos de acesso: Tipo1: JDBC-ODBC - A aplicação Java se conecta à um driver ODBC e este se conecta ao banco. A vantagem é a ampla gama de banco de dados que oferecem conexões via ODBC. O ponto negativo é a baixa performance e o fato de a ODBC ser instalada em cada máquina cliente. Tipo2: Native-API partly Java technologyenabled driver – O driver JDBC se comunica diretamente com o client do banco. É mais veloz do que o tipo1 pela ausência da ODBC. Como no tipo1, o cliente do banco precisa estar instalado em cada máquina cliente. Tipo3: Pure Java Driver for Database Middleware – A aplicação se comunica com uma camada intermediária, que traduz as chamadas e repassa para o banco de dados. Elimina a necessidade do cliente do banco estar instalado na máquina cliente. Entretanto, não é recomendável para aplicações de pequeno porte. Tipo4: Direct-to-Database Pure Java Driver. A mais rápida de todas. A aplicação se comunica diretamente com o banco de dados, sem a necessidade de intermediário, através do protocolo nativo do banco de dados. O driver nativo JDBC para o JDataStore 6 é classe 4, assim como o do Oracle e do novo InterBase 7. JDataStore - O Banco de dados da Borland JDataStore6: Banco de Dados 100% Java, Ágil, Simples, Móvel e Distribuível. O JDataStore é relacional e transacional, com suporte a StoredProcedures, UDF´s (User Defined Functions), conexões simultâneas e concorrentes. Apesar de conter esses recursos é um produto compacto, podendo até ser executado em dispositivos wireless. É portável e multi-plataforma, já que foi desenvolvido totalmente em Java. Suporta o padrão ansi92, tornando o acesso aos dados praticamente sem mistérios para quem já usa algum outro banco relacional. Um dos principais focos do JDataStore na versão 6 é possibilitar a criação de aplicações em dispositivos wireless, permitindo sua utilização em plataformas como Compaq Ipaq, Sharp Zaurus e outros que suportem a plataforma Jeode (PersonalJava e EmbeddedJava). O Palm OS ainda não é suportado pelo JDS. Segundo Sérgio Cardoso, arquiteto do JDataStore, “Quando o PalmOS disponibilizar pelo menos 8Mbytes para processos Java, poderemos rodar nestes modelos”. Pontos Fortes Baixo custo de investimento: Uma licença para 10 usuários custa em torno de US$ 1000,00. Perfomance: Por se tratar de um banco de dados simples, o JDS apresenta boa performance. Fácil Distribuição: É possível distribuir os recursos necessários do engine do JDS num disquete de 1.4 Mb. Distribuir o Run time em formato Jar file do JDS consome apensa 1 Mb. Desenvolvimento: O JDataStore possui integração nativa com o JBuilder, fornecendo um ambiente mais produtivo do que em outras plataformas de desenvolvimento. Isso não impede que o JDataStore seja acessado por outras ferramentas. Resumo das Caracteríticas Básicas do JDataSore • Totalmente escrito em Java; • Roda em dispositivos com apenas 16Mbytes de memória; • Suporta versões Java 1.1.8 à 1.4; • Certificado para rodar em Windows (XP, 2000, NT, 98 SE), Linux (RedHat 7.x, Mandrake 7.x), Solaris (7, 8) e Mac OS X; • Suporte à padrões (JavaBeans, SQL 92, stored procedures, foreign keys, JDBC 3.0 scrollable, updatable cursors, batch updates); • Alta Performance; • Suporte a transações; • Suporte à múltiplos processadores; • Recuperação automática de erros; • Requer mínima administração; • Fácil distribuição; • Um único arquivo .jar file contém toda funcionalidade; • Pode ser distribuído junto à aplicação; • Arquivo de dados tem o mesmo formato para todas as plataformas de instalação do produto e é até 50% menor que um com a mesma estrutura gerado em um banco de dados similar; Imagem 1 – JDataStore Explorer Algumas das Melhorias na Versão 6.0 • Maior suporte aos padrões adotados pelo mercado; • Maior suporte as propriedades da API JDBC e Implementações adicionais para interfaces JDBC 2 e JDBC 3; • Mudanças para tipos de dados FLOAT, DATE e TIME; • Implementação de novas funções de sistema; • Suporte a Subqueries ; • Suporte a Foreign keys ; • Suporte a Table expressions; • Suporte a Stored procedures e UDFs (User Defined Funcion); Imagem 2 – Criando o Arquivo JDS na versão 6.0 Sobre as Stored Procedure e UDF´s Stored Procedures: A maioria dos servidores de banco de dados utilizam o TransactSQL e o PL-SQL para implementação de Stored Procedures. No JDataStore 6 a linguagem de procedures é o Java, de forma que todos os recursos de funções de sistema, mecanismos de conversão, funções com tipos primitivos, bem como manipulação de Strings e outras classes Java, podem ser utilizados. UDF (User Defined Functions): Como no InterBase, é possível criar funções personalizadas para o JDS. Com isso, as possibilidades para tratamento dentro do banco se tornam praticamente infinitas. A desvantagem, assim como qualquer UDF, é a queda de performance quando o código realiza uma chamada à função. Utilizando o JDataStore pela primeira vez O JDataStore está disponível juntamente com a instalação do JBuilder para download no site da Borland no endereço http://www.borland.com/products/ Imagem 3 – Manipulção da tabela criada. downloads/download_jdatastore.html. A instalação é simples e rápida, bem como a utilização dos seus recursos. O banco acompanha um utilitário para manutenção visual, chamado JDataStore Explorer (imagem 1). Para criar um novo banco de dados selecione o menu File->New. Na janela de opções, indique a versão do banco a ser criada, defina o diretório e dê um nome para o arquivo de dados. A extensão do banco será .jds. (Imagem 2). Uma tabela pode ser construída através do menu Tools/Create Table. A janela para criação é intuitiva, deixando qualquer um a vontade. Os dados da tabela estão disponíveis na guia “View”, conforme mostra a figura 3. SQL Magazine - 49 Entrevista com Sérgio Cardoso (Engenheiro de Produtos da Borland USA) Durante os últimos nove anos, Sérgio Cardoso teve a oportunidade de participar no desenvolvimento de vários releases do Borland C++, JBuilder, Borland Application Server e trabalhar no desenvolvimento do Borland JDataStore. Esteve presente este ano em São Paulo, na 1º BorCon Brasil, ministrando uma palestra sobre o JDS. O que é o JDataStore? JDataStore é um banco de dados relacional totalmente desenvolvido em Java. Usuários do JBuilder Enterprise e do Borland Enterprise Server contam com a tecnologia do JDataStore nestes produtos. O JDataStore também é distribuído em uma versão standalone. Ele integra-se de maneira transparente ao JBuilder, nossa solução para desenvolvimento Java. Qual a missão do JDataStore? O objetivo principal do JDataStore está em facilitar o desenvolvimento de aplicações Java que necessitem de um banco de dados com alta performance, instalação transparente, manutenção zero e pouco uso de memória. Procuramos garantir que o JDataStore seja compatível aos padrões de mercado tais como J2EE, JDBC e SQL. Por sua versatilidade e robustez, o JDataStore tanto pode ser usado em dispositivos móveis como em aplicações distribuídas. A portabilidade do ambiente Java permite também que o mesmo código e arquivos de dados de uma aplicação que use JDataStore possa ser utilizado sem a necessidade de portes e conversões. O mesmo arquivo .jar com cerca de 1Mbyte contendo todo a funcionalidade do produto pode ser usada em Windows, Linux, Solaris e Mac OS X. Exitem concorrentes do JDS? Cloudscape e PointBase são dois outros bancos de dados Java no mercado norteamericano. Depois da compra da Informix pela IBM, não se ouve muita coisa a respeito do futuro do Cloudscape. PointBase está oferecendo hoje recursos que já existem no JDataStore há vários releases. Como funciona o JDataStore dentro de dispositivos Móveis e como seria a relação J2ME e JDataStore? Boa parte do que se fala hoje sobre 50 - Magazine SQL J2ME está concentrado no MIDP. Muitos dos modelos de telefone celular disponíveis hoje possuem cerca de 2Mbytes para execução de programas. Estamos trabalhando para o mercado de dispositivos com 16Mbytes de memória RAM ou mais, que oferecem suporte para Personal Java hoje e ao CDC/Personal Profile no futuro, como os modelos baseados na arquitetura ARM, rodando Pocket PC. O iPaq da Compaq possui modelos com 32Mbytes de memória RAM. Desses 32Mbytes metade pode ser utilizado como área de armazenamento e outra metade para execução de aplicações. A mesma quantidade de memória está disponível nos modelos Zaurus da Sharp que usam Embedded Linux como sistema operacional. A Nokia possui o Communicator 9210i que é uma mistura de PC e telefone celular. Conseguimos executar aplicações com o JDataStore neste equipamento. Mas enfrentamos baixa velocidade nas transferências de dados por estarem baseados em redes GSM. Esses equipamentos deverão ter uma aceitação muito maior quando suportarem redes GPRS que oferecem velocidades maiores para transferência de dados. Vai ser possível um dia utilizar JDataStore com Palm´s? Quando o PalmOS disponibilizar pelo menos 8Mbytes para processos Java, poderemos rodar nestes modelos. É simples trabalhar com repositórios locais JDataStore e depois realizar a sincronização com outros servidores de banco de dados? Sim, isso é possível. O JDataStore possui uma solucao “lightweight” para sincronização de dados entre dispositivos remotos e servidores de dados. O JDataStore deixará de ser relacional para tornar-se um banco de dados orientado à objetos? Você pode armazenar instâncias de objetos em uma tabela com o JDataStore. Todo o suporte para a serialização existe hoje. Também contribuímos com tecnologia de mapeamento relacional/objeto na implementação do CMP do Borland Enterprise Server (Enterprise Java Beans). Como funciona o mecanismo de licença do JDS? O JDataStore possui basicamente 3 ti- pos de licença: Developer, Local Server e Server. Quando você compra o JBuilder Enteprise ou o Borland Enterprise Server (BES), você também está adquirindo uma licença para desenvolvimento do JDS. Quando uma aplicação desenvolvida com o JDataStore precisa ser distribuída você pode adquirir licenças para um servidor local onde, por exemplo, o arquivo de dados será acessado pelo mesmo usuário em uma mesma máquina. Caso você precise que a base de dados seja acessada por diferentes usuários, você poderá utilizar o JDataStore Server em um servidor por usuários remotos. A licença de Servidor permite que até 10 conexões simultâneas sejam feitas a uma mesma base de dados. Novas licenças podem ser adquiridas e adicionadas. O que podemos esperar no futuro do JDataStore? Estamos explorando os avanços em .NET, segurança e dispositivos móveis. Conclusão Assim como o Interbase da Borland, o JDataStore é uma solução para quem busca um banco leve, portável, rápido e de simples manutenção. Seu baixo custo, aliado as vantagens de ser PureJava, faz dele uma solução única para alguns tipos de aplicação. webSITES http://bdn.borland.com http://www.borland.com/jdatastore/index.html http://wireless.java.sun.com/getstart/ http://java.sun.com/products/jdbc/. SQLAutor Edgar Silva é Diretor Técnico da Argos Tecnologia, atuando em projetos envolvendo Multi-camadas com J2EE e outras tecnologias Borland com BizSnap e DataSnap. Está atuando no desenvolvimento de várias API´s Java, bem como o Argos Framework (EJB, Servlets, JSP e Struts). Foi durante muitos anos um dos principais instrutores da Borland, viajando o país inteiro para formação de novos instrutores e profissionais certificados. É Borland Delphi Certified Developer & Instructor e Borland JBuilder Certified Developer & Instructor. É lider do Grupo de Usuários Java de Belém (http://beljug.locaweb.com.br) e pode ser contactado em [email protected].