Você está na página 1de 30

Revista The Club Megazine - 12/2002

A utilização, reprodução, apropriação, armazenamento em


banco de dados, sob qualquer forma ou meio, de textos, fotos e
outras criações intelectuais em cada publicação da revista “The
Club” são terminantemente proibidos sem autorização escrita
dos titulares dos direitos autorais.
Copyright© The Club® 2002
EDITORIAL

Editorial
Enquanto isso, aproveite a revista desde mês, onde temos vários
THE CLUB artigos interessantes! Iniciamos uma série sobre UML, uma linguagem
Rua Acre, 950 - Avaré - SP - CEP 18.700-260
Informações: (0xx14) 3732-3689
de modelagem estruturada que esta se tornando um padrâo mundial na
Suporte: (0xx14) 3733-1588 metodologia da Engenharia de Software. Temos também, um ótimo
Fax: (0xx14) 3732-0987 artigo sobre WebServices, pois hoje, não dá para falar em internet sem
falar em WebServices...
Internet
http://www.theclub.com.br Na série DataSnap, é demonstrado de forma bastante simples o
Cadastro: cadastro@theclub.com.br temido Master/Detail, provando não ser tão difícil assim!
Suporte: suporte@theclub.com.br
Informações: info@theclub.com.br E finalizando, temos dois artigos sobre banco de dados, um sobre
Oracle e outro demonstrando a facilidade na utilização dos Domains no
Dúvidas Firebird.
Correspondência ou fax com dúvidas devem ser
enviados ao - THE CLUB, indicando "Suporte".
Aproveite!
Opinião
Se você quer dar a sua opinião sobre o clube em
geral, mande a sua correspondência para a seção Feliz Natal e próspero ano novo!
"Tire sua dúvida".

Reprodução
A utilização, reprodução, apropriação,
armazenamento em banco de dados, sob qualquer
forma ou meio, de textos, fotos e outras criações
intelectuais em cada publicação da Revista
“The Club” são terminantemente proibidos sem
autorização escrita dos titulares dos direitos
autorais.

Copyright© The Club® 2002 Celso Jefferson Paganelli


Presidente - The Club
Impressão e acabamento:
Impressos Gril - Gril Gráfica e Repr. Ind. Ltda.
Tel.: (0xx14) 3762.1345 - Fax: (0xx14) 3762.1259
Rua São Paulo, 447 - Cep 18.740-000
Taquarituba - SP
Tiragem: 5.000 exemplares

Editorial ...................................................................................... 03
Diretor - Presidente

Celso Jefferson M. Paganelli News ......................................................................................... 04


UML - Linguagem de Modelagem Unificada .......................... 05
Diretor Técnico
WebServices ............................................................................... 07
Mauro Sant’Anna
Colaboradores Criando um Banco de Dados (instance) no Oracle 9i (2) ...... 14
Marcelo Nogueira, Alexandre Magno, Anderson H.
Rodrigues, Emerson Facunte, Mario C. Bohm
DataSnap - O Cliente COM+ - Master/Detail - Parte IIV ....... 16
Delphi é marca registrada da Borland
International, as demais marcas citadas são
Tudo Sobre Domínios................................................................ 27
registradas pelos seus respectivos proprietários.
Perguntas & Respostas .............................................................. 30

MeGAZINE 3
NEWS

Sistemas Multicamadas com Delphi - Aplicações Cliente/Servidor.


Também aborta o que é e quando usar as palavras/
dbExpress e DataSnap tecnologias que vimos no dia a dia: COM, OLE , DCOM, MTS,
COM+, ActiveX, MSTDC, Sockets, CORBA, ORB, Stub,
Rodrigues, Anderson Haertel Skelleton, SOAP, DSOM, Interface, Stateless, Statefull, DCE,
ISBN: 85-7502-105-2 RPC, Stack, GUID, CLSID, IID, Early Binding, Late Binding,
Editora: Visual Books Regra de negócios, etc.
www.visualbooks.com.br São explicados (e exemplos de como usar) todos os
componentes (suas propriedades, métodos e eventos) da Guia
Aprender sobre o Desenvolvimento de Sistemas utilizando a DataSnap do Delphi 6 e do Delphi 7.
tecnologia multicamadas é uma tarefa possível, basta um Além de ensinar detalhadamente (conceitos, implementação e
pouco de esforço e perseverança e, é claro, um bom livro para macetes) o desenvolvimento de um sistema MultiCamadas em
seguir. Delphi usando o Protocolo COM+ (da família DCOM), o livro
Este livro se propõe a ir além de apenas mostrar como ensina o que é e como usar as Interfaces, a dbExpress
construir os cadastros e explicar como são usados os (SQLConnection, SQLDataSet, SQLQuery, SQLStoredProc,
componentes. Isso, com certeza, você aprende no Help da SQLTable, SQLMonitor, SQLClientDataSet e SimpleDataSet,
ferramenta Delphi. Esta publicação explica o conceito e tenta suas propriedades, métodos e
quebrar o paradigma do leitor que está acostumado com a eventos) do Delphi 6 e Delphi 7, mostra as principais classes
tecnologia Client/Server. envolvendo a dbExpress e ainda mostra as Interfaces envolvidas
São explicados todos os protocolos que o DataSnap suporta na construção da
na versão 7.0 do Delphi, mas, enfatiza o seu desenvolvimento dbExpress) estuda e mostra o que é e como usar o
no protocolo COM+. componente ClientDataSet (suas propriedades, métodos e eventos
Veremos, também, os conceitos envolvidos no uso das e como usar e criar MyBase e XML envolvendo o componente
ferramentas de acesso a Banco de Dados que acompanham o ClientDataSet) e o componente DataSetProvider (Providing,
Delphi 6.0/7.0 (dbExpress) e a explicação em detalhes do uso Resolving, Transações, Regras de Negócios e suas propriedades,
dos componentes ClientDataSet e DataSetProvider, além dos métodos e eventos)
seus conceitos. O Livro se destina a usuários iniciantes, intermediários e
Conheça esses componentes e os benefícios que os mesmos avançados.
oferecem e aplique-os em seus projetos. O Livro ainda contempla os eleitores com Cases de Sucesso no
O livro inicia mostrando o que é uma aplicação Cliente/ uso da tecnologia DataSnap. As cases de Sucesso são descritas/
Servidor, o que é uma aplicação 3 Camadas e quais as faladas por ilustres/prestigiados amigos da Comunidade Delphi
vantagens das Aplicações 03 Camadas em relação as Nacional.

HOTShow - www.mlsoftware.com.br perfeita para aplicações nos mais diversos segmentos:


publicitário, marketing, fotográfico, médico, odontológico, perícia,
Sistema de Apresentações Multimídia imobiliário, organizadores de eventos, agências de modelos,
Agora você pode criar e distribuir em arquivos EXE, em artístico, decoradores e acabamentos em geral.
poucos minutos, as mais incríveis aplicações interativas • Ambiente intuitivo e amigável
multimídia, sem ter que gastar meses aprendendo uma • Apresentações interativas
linguagem de programação. HOTShow é um sistema de • Suporte aos formatos comuns de imagem: BMP, JPG,
apresentações multimídia que possui um ambiente bastante WMF, EMF e ICO
intuitivo e amigável. Permite combinar objetos como textos, • Suporte à filmes digitais nos formatos AVI e MPEG
shapes, imagens, botões, sons, músicas, animações, filmes, links • Adicione som e música para sua apresentação (WAVE /
e variáveis. Você poderá construir, com qualidade, rapidez e MP3 / MIDI)
facilidade, aplicações interativas multimídia em CD-ROM, • Assistente de Criação de Botões
apresentações diversas, albuns de fotografias e slide-shows, • Assistente de Criação de Animações
proteção de telas (screen savers), quiosques de informações, • Inspetor de Ações
tutoriais, programas de treinamento, catálogos de produtos, • Assistente de Transporte
cartões digitais, histórias, desenhos animados, arquivamento • Ferramenta de Procura e Substituição
digital de imagens, vídeos e documentos e projetos de apoio para • Mega clipart (apenas para versão CD-ROM), com imagens,
áreas de educação e RH, dentre outras utilidades. Fácil de usar, filmes, sons e músicas
HOTShow não requer nenhuma programação! É a solução E muito mais !!!

4 MeGAZINE
Delphi

UML
Linguagem de Modelagem Unificada
Orientação à Objeto na Modelagem

Autor: Marcelo Nogueira

As empresas cada vez mais estão voltadas às Ela é utilizada para descrever pontos de um sistema e da
informações.Com isso, o volume de informações vem crescendo forma como ele é percebido de várias visões durante a análise e
exageradamente e nem sempre podemos retirar vantagens sua arquitetura.
competitivas devido à falta de uniformidade com que elas são É uma linguagem que visa capturar conhecimento e
postadas. expressar esse conhecimento.
O desenvolvimento de sistemas deve acompanhar a mutação Seu propósito é a modelagem de sistemas, documentar de
constante das informações e para isso, devemos construir maneira interativa e visual, proporcionar melhor compreensão e
aplicações mais flexíveis e com menor taxa de manutenção. sinergia entre o analista e o cliente envolvido no processo de
Para que isso ocorra, é necessário adotar uma metodologia de desenvolvimento.
trabalho que se aproxime mais da realidade da empresa, que
consiga descrever seus fluxos operacionais e trâmite dos negócios, Devemos adotar a UML?
retratando de fato toda a sua concepção. Além da sua alta e rápida adesão no mercado mundial, aqui
É percebível por todos que os métodos de modelagem no Brasil, sempre tivemos a grande necessidade da adoção de um
tradicionais, especificamente o modelo estruturado, tornam o modelo mais eficiente e que resultasse maior produtividade,
desenvolvimento mais demorado, custos de manutenção maiores menos erros no desenvolvimento, encurtamento dos prazos de
e em casos mais caóticos, levam o projeto a naufragar. entrega, menor custo de manutenção do software.
Isso porque existe uma dificuldade enorme em extrair do Falando assim, parece a solução que todos esperaram por
cliente a verdadeira necessidade da empresa e principalmente as anos, mas também não é bem assim.Os resultados aparecem, se
expectativas que estão focadas encima daquele desenvolvimento. bem utilizados os recursos disponíveis e a perfeita compreensão
Por este motivo, o contato humano e habilidade de entrevistar dos conceitos da orientação à objetos que se pretende
o cliente, já não é mais eficiente, necessitando de apoio de uma sensibilizar.Caso contrário será mais um método que tentaremos
ferramenta que possa de alguma forma, colaborar utilizar e os resultados não virão.Abandonar os atuais métodos
metodicamente para que as informações venham condizer com a que você utiliza pode ser catastrófico.Afinal, muitos projetos
empresa e os requisitos que o analista de sistemas necessita para foram bem sucedidos, apesar das estatísticas serem bastante
o desenvolvimento, bem como atender as necessidades do cliente e assustadoras, quando institutos americanos respeitados,
resultar em algo mais nas estratégias de negócios. afirmam que 60% dos sistemas começados, não chegam a ser
finalizados, e muito menos a serem utilizados.
Onde entra a UML ? Desenvolvemos sistemas que enfocam demandas e requisitos
A UML é uma linguagem de modelagem, totalmente de clientes.
orientada à objetos, que une as melhores práticas e metodologias Requisitos são considerados os problemas.Os sistemas são
da Engenharia de Software. considerados a solução.O problema e a solução ocorrem dentro de
É considerada a sintaxe geral para criar um modelo lógico de um mesmo contexto.
um sistema. Para ser desenvolvida uma boa solução, primeiramente deve

MeGAZINE 5
Delphi

existir compreensão do problema.A solução deve ser entendida Adotando a UML para os novos projetos, explorando e
para que possa ser criada e utilizada. utilizando todos os seus recursos e juntamente com uma
Partindo deste princípio, a solução deve ser arquitetada, a fim ferramenta para modelar os dados é o primeiro grande passo.
de aderir às restrições de suas necessidades. A ferramenta mais conhecida para a utilização da UML é da
Para adotarmos a solução apropriada ao problema, precisamos empresa Rational, e chama-se Rational Rose.A Borland,
modelar, organizar, e representar através de diagramas, onde percebendo a evolução global da UML, incluiu somente na versão
permitirão comunicação e disseminação dos conhecimentos Enterprise do Delphi 7, o ModelMaker, ferramenta muito similar
extraídos ao Rational Rose, capaz de modelar o projeto utilizando UML e já
. gerar código no Delphi.
Que tipos de diagramas são utilizados? Utilizar metodologias de modelagem de sistemas que de
Na UML podemos utilizar vários diagramas para melhor alguma forma vão melhorar nosso desempenho e resultados, o
compreender a complexidade de nosso problema explorando ao desafio é grande, no entanto o objetivo, é atenuar ao máximo os
máximo todo o conceito de orientação a objeto.Entre eles podemos desperdícios de tempo e de recursos financeiros empregados em
destacar: projetos de sistemas.
• Diagramas de casos de uso A cada artigo mensal, demonstraremos a utilização de cada
• Diagramas de objeto diagrama e posteriormente a sua utilização na ferramenta de
• Diagramas de classe modelagem UML. Acompanhe!
• Diagramas de seqüência Sobre o autor
• Diagramas de colaboração
• Diagramas de estado Marcelo Nogueira é Analista de Sistemas,
• Diagramas de atividade Instrutor e Desenvolvedor Delphi, na SoftWay
• Diagramas de componentes Informática, Santos - SP.
• Diagramas de Implantação e-mail: softway@iron.com.br

6 MeGAZINE
Delphi

WebServices Autor: Emerson Facunte

Para explicar de maneira adequada o significado da Tecnologias do nosso cenário exemplo


tecnologia WebServices, é interessante fazer uma breve
introdução aos problemas atuais no mundo da tecnologia.
Banco S.O. Banco Dados Terminais
Com o grande avanço de sistemas operacionais, bancos de Facunte Unix DB2 Terminais Linux
dados, hardware, software, enfim, todo o tipo de tecnologia que
envolve o mundo dos negócios, vêm surgindo a necessidade de X NT SQL Server Windows
compartilhamento de informações entre parceiros comerciais, Y Solaris Oracle Terminais Linux
governo e sociedade, e até mesmo entre departamentos de uma
empresa.
Integrar informações de diferentes plataformas não é
Acontece que interligar diferentes plataformas, bancos de
novidade, e como já foi mencionado é possível, mas muito
dados, operações, entre outros conceitos, é uma tarefa muito
trabalhoso.
complicada e trabalhosa.
A proposta da tecnologia WebServices neste cenário, é a de
Para concluir o conceito de WebServices, vamos imaginar um
facilitar a troca de informações, fazendo o Banco Facunte
cenário simples, onde precisamos integrar informações de
entender e tratar as informações dos Bancos X e Y, independente
diferentes departamentos e filiais, que foram desenvolvidos em
do banco de dados, sistema operacional, ou outro fator não citado.
plataformas diferentes. Um bom exemplo para isso, são os bancos
que estão adquirindo outros bancos em todo o mundo, e que
Com algumas linhas de programação e um bom
utilizam conceitos e plataformas diferentes de trabalho.
planejamento, as informações essenciais serão interligadas
A figura 1 ilustra o Banco Facunte, adquirindo outros dois
facilmente.
bancos com diferentes tecnologias.
Meus amigos, isso é WebServices!

Em resumo, WebServices, é um padrão não-proprietário, que


possibilita o processamento distribuído em sistemas heterogêneos.

E acredito que muitos de vocês neste ponto estão ansiosos


para produzir o seu primeiro WebService.

Antes, devemos conhecer os padrões que fazem parte da


tecnologia.

WebService Exemplo

Vamos criar nosso primeiro WebService para aprender melhor


seu conceito.

Através das opções File/New..., seção WebServices, selecione a


Figura 1: Banco com diferentes plataformas opção SOAP Server Application (figura 2).

MeGAZINE 7
Delphi

Com isso estamos criando uma Interface com o nome wsexemplo, e


gravando a unit com o mesmo nome.

Em Code generation selecione as opções Generate Comments e


Generate Sample Methods. Com isso estamos gerando exemplos de
métodos e comentários.

Figura: 5 Identificação do serviço


Figura 2: Nova aplicação WebService
Clique em OK para finalizar.
Em seguida selecione a opção CGI para o tipo da aplicação
servidora SOAP (figura 3). Vamos gravar nossa aplicação.

Unit WebModule un_ws1.pas

Unit Implementação WsExemplo wsexemploImpl.pas

Unit Interface WsExemplo wsexemploIntf.pas

Projeto ws1.dpr

Vamos analisar o que o nosso amigo Delphi criou.

Figura 3: Tipo da aplicação servidora

Em seguida o Delphi pergunta se deseja criar uma Interface


SOAP padrão (figura 4). Em nosso exemplo, vamos criar a tal
Interface, a fim de conhecer sua implementação

Figura: 6 WebModule1

A figura 6 ilustra nosso WebModule com três componentes no


padrão WebService (HTTPSoapDispatcher,
Figura 4: Criação da Interface HTTPSoapPascalInvoker,WSDLHTMLPublish).

Em seguida (figura 5) devemos informar os dados da nova Vejamos sua implementação.


Interface.
procedure
Nos campos Service Name e Unit identifier coloque wsexemplo. TWebModule1.WebModule1DefaultHandlerAction(Sender:

8 MeGAZINE
Delphi

TObject; function echoEnum(const Value: TEnumTest):


Request: TWebRequest; Response: TWebResponse; var TEnumTest; stdcall;
Handled: Boolean); function echoDoubleArray(const Value:
begin TDoubleArray): TDoubleArray; stdcall;
WSDLHTMLPublish1.ServiceInfo(Sender, Request, function echoMyEmployee(const Value:
Response, Handled); TMyEmployee): TMyEmployee; stdcall;
end; function echoDouble(const Value: Double):
Double; stdcall;
A única função do nosso WebModule1,é a criação de um handler end;
para o WebService e publicação do documento WSDL.
implementation
Na unit wsexemploIntf estamos definindo a Interface de nossa
aplicação. initialization
{ Invokable interfaces must be registered }
{Invokable interface Iwsexemplo } InvRegistry.RegisterInterface(TypeInfo(Iwsexemplo));

unit wsexemploIntf; end.

interface Esta unit na realidade está seguindo as regras da O.O.


(Orientação a Objeto), onde definimos uma Interface como base,
uses InvokeRegistry, Types, XSBuiltIns; para que possamos implementar nossas classes. Além disso
estamos registrando a Interface no modelo SOAP.
type
Repare que os métodos criados são apenas exemplos de
TEnumTest = (etNone, etAFew, etSome, etAlot); implementação, que solicitamos previamente, justamente para
estudar e analisar.
TDoubleArray = array of Double;
Na unit wsexemploImpl, temos a implementação da Interface
TMyEmployee = class(TRemotable) que vimos anteriormente.
private
FLastName: AnsiString; Acredito que deu pra perceber, que os métodos apenas
FFirstName: AnsiString; retornam os mesmos valores informados.
FSalary: Double;
published Para compreender melhor, vamos fazer uma pequena
property LastName: AnsiString read alteração no método echoDouble. Substitua a linha de retorno,
FLastName write FLastName; pelo código que segue em negrito:
property FirstName: AnsiString read
FFirstName write FFirstName; function Twsexemplo.echoDouble(const Value: Double):
property Salary: Double read FSalary Double; stdcall;
write FSalary;
end; begin
{ TODO : Implement method echoDouble }
{ Invokable interfaces must derive from Result := Value * 3;
IInvokable } end;
Iwsexemplo = interface(IInvokable)
[‘{A391DC0F-CDA7-4929-97B8-DAECA7C2CF18}’] Perceba que estamos multiplicando por 3, só para quebrar o
gelo (Double = Dobro)
{ Methods of Invokable interface must
not use the default } Antes de compilar vamos definir o diretório para geração do
{ calling convention; stdcall is recommended } nosso WebService.

MeGAZINE 9
Delphi

Através das opções Project/Options.../Directories_Conditionals,


configure a opção Output Directory, apontando para o o seu diretório
cgi-bin (figura 7).

Figura 8: Aplicação ws1


- <types>
Figura 7: Configuração do diretório
- <xs:schema targetNamespace=”urn:wsexemploIntf”
xmlns=”urn:wsexemploIntf”>
Grave novamente a aplicação.
- <xs:simpleType name=”TEnumTest”>
- <xs:restriction base=”xs:string”>
Agora vamos compilar a aplicação.
<xs:enumeration value=”etNone” />
<xs:enumeration value=”etAFew” />
Vamos executar a aplicação no browser para analisar o seu
<xs:enumeration value=”etSome” />
conteúdo. Lembre-se que para isso você deverá configurar um
<xs:enumeration value=”etAlot” />
servidor web, como o Apache, IIS, Xitami, etc.
</xs:restriction>

Digite: http://localhost/cgi-bin/ws1.exe/
Passando pelo bloco das definições inicias (<?xml
version=”1.0"...), chegamos no bloco de definições de tipos e
A figura 8 ilustra o resultado da primeira fase de nossa
métodos.
aplicação.
Neste bloco são definidos todos os métodos da nossa Interface,
com o descritivo completo. Repare que a classe TEnumTest é
Repare que temos todos os métodos listados na Interface
descrita com perfeição.
Iwsexemplo (echoEnum, echoDoubleArray, echoMyEmployee,
echoDouble).
No bloco que segue, são descritos os métodos Request e Response
da Interface em questão.
O documento gerado está de acordo com o padrão estabelecido
pelo W3C-UDDI (órgão responsável pelo padrão WebService).
- <message name=”echoEnum0Request”>
<part name=”Value” type=”ns1:TEnumTest” />
Clicando no link WSDL da Interface Iwexemplo será apresentado
</message>
um documento WSDL.
- <message name=”echoEnum0Response”>
<part name=”return” type=”ns1:TEnumTest” />
Vamos analisar algumas partes do documento para
</message>
compreender melhor seu funcionamento.

10 MeGAZINE
Delphi

A seguir, temos o bloco que define o nome da porta (Port), e Unit un_teste_ws1.PAS
as operações Request e Response, descritas no bloco anterior.
Projeto teste_ws1.DPR
- <portType name=”Iwsexemplo”>
- <operation name=”echoEnum”> Agora vamos importar a Interface em nossa aplicação. Através
<input message=”tns:echoEnum0Request” /> das opções File/New.../WebServices (figura 9), selecione a opção WSDL
<output message=”tns:echoEnum0Response” /> Importer.
</operation>

Em seguida temos o bloco que “envelopa” e define a camada de


transporte dos métodos.

- <binding name=”Iwsexemplobinding”
type=”tns:Iwsexemplo”>
<soap:binding style=”rpc” transport=
”http://schemas.xmlsoap.org/soap/http” />
- <operation name=”echoEnum”>
<soap:operation soapAction=
”urn:wsexemploIntf-Iwsexemplo#echoEnum”
style=”rpc” />
- <input message=”tns:echoEnum0Request”>
<soap:body use=”encoded” encodingStyle=
”http://schemas.xmlsoap.org/soap/encoding/”
namespace=”urn:wsexemploIntf-Iwsexemplo” />
</input> Figura 9: WSDL importer
- <output message=”tns:echoEnum0Response”>
<soap:body use=”encoded” Em seguida, como ilustra a figura 10 , digite endereço que
encodingStyle= segue.
”http://schemas.xmlsoap.org/soap/
encoding/”namespace= http://localhost/cgi-bin/ws1.exe/wsdl/Iwsexemplo
”urn:wsexemploIntf-Iwsexemplo” />
</output> Este endereço faz a chamada ao documento WSDL da Interface
Iwsexemplo.
O último bloco finaliza o documento, declarando o nome do
serviço, bem como o nome da porta e a sua camada de transporte.

- <service name=”Iwsexemploservice”>
- <port name=”IwsexemploPort”
binding=”tns:Iwsexemplobinding”>
<soap:address location=”http://localhost/delphi/
cgi-bin/ws1.exe/soap/Iwsexemplo” />
</port>
</service>
</definitions>

Agora vamos criar uma aplicação cliente para testar nosso


primeiro WebService.

Através das opções File/New Application cria uma nova


aplicação, e grave os arquivos como segue: Figura: 10 Importação da Interface através do WSDL

MeGAZINE 11
Delphi

Este procedimento está importando toda a Interface para a


nossa aplicação.

Com isso teremos acesso aos métodos definidos.

É interessante destacar que um WebService poderá ter


inúmeras Interfaces, onde poderemos importar apenas as que
condizem com a nossa necessidade.

Aperte o botão Next para avançar à próxima fase.


Com isto configuramos o objeto de acesso à Interface,
A figura 11 ilustra a Interface gerada pelo assistente. informando a localização do documento WSDL (WSDLLocation), o
serviço (Service), e a porta (Port).
Agora insira os objetos que seguem, configurando suas
respectivas propriedades.

Figura: 11 Interface gerada pelo assistente

Para concluir aperte a tecla Finish.

O assistente gerou uma Unit com toda a Interface


implementada.

Grave a Unit com o nome Iwsexemplo1.pas.

O que acabamos de fazer, na realidade, foi a importação de


uma Interface para facilitar o uso do WebService.

Agora com o foco na unit un_teste_ws1, insira a unit


Iwexemplo1.pas gerada pelo assistente.
A figura 12 ilustra o formulário da nossa aplicação.

implementation
uses Iwsexemplo1;

Neste ponto iremos configurar o acesso para este formulário.

Insira um objeto do tipo THTTPRIO, e configure as


propriedades que seguem, respeitando a seqüência apresentada,
caso contrário, uma exceção ocorrerá. Figura 12: Formulário da aplicação

12 MeGAZINE
Delphi

Agora vamos codificar a aplicação. Insira o código que segue


no evento OnClick do objeto Button1.

var
Iexemplo: Iwsexemplo;
begin
Iexemplo:= HR1 as Iwsexemplo;
lbResultado.Caption:=FloattoStr(Iexemplo.echoDouble Figura 13: Aplicação em tempo de execução
(StrtoFloat(edValor.Text)));
end; Perceba que a primeira vez que pressionamos o botão, existe
um delay, que é justamente o tempo de conexão com o WebService.
O código é bastante simples, onde estamos definindo um Repita a operação, e repare que já não existe mais o delay.
objeto do tipo Iwsexemplo. Em seguida estamos instanciando o
objeto a partir do nosso HTTPRio (HR1), adotando o modelo Amigos isto é apenas o começo. Em meu livro Delphi 7
Iwsexemplo. E por fim, apresentamos o resultado em nosso objeto Internet e Banco de Dados, explico através de exemplos práticos
lbResultado, através da função IExemplo.echoDouble. todo o poder dos WebServices. Temos WebServices utilizando banco de
dados como serviço, e também conexões concorrentes utilizando o
O mais importante até aqui, é justamente a compreensão de protocolo SOAP.
como conseguimos implementar o WebService em nossa aplicação. Forte abraço e imenso sucesso a todos !!!
Sobre o autor
Vamos testar nossa aplicação.
Emerson Facunte é Consultor de Tecnologia com diversos
Compile e execute a aplicação, informando um número no livros publicados, especialista em desenvolvimento de
campo e pressionando o botão. A figura 13 ilustra nossa aplicação aplicações e-Business utilizando a ferramenta Delphi, baseado
em tempo de execução. em WebSnap, DataSnap, BizSnap e ISAPI/Apache Modules.

MeGAZINE 13
Delphi

Criando um banco de dados (instance)


no Oracle 9i... (Parte 2)

Autor: Mário Camilo Bohm - Bohm,Interal

Vamos lá então, continuar nossa instalação de uma instance que for utilizado.
Oracle !
Recomendamos, para instalações típicas, utilizar 70% da
Nesta próxima fase da instalação, teremos que definir memória disponível no servidor.
aspectos importantes de nossa instalação. (ver figura 1)
Com essa opção pelo gerenciamento automático, a própria
Um primeiro aspecto é a maneira como a instance irá tratar instance “resolverá” necessidades de alocação para
o gerenciamento de memória, principalmente para a SGA shared_pool_size, db_block_buffers, etc, limitada obviamente à
(System Global Área), uma alocação de memória onde quantidade física de memória. O desempenho da instance sobe
praticamente todas as tarefas do banco são executadas. consideravelmente com a opção pelo gerenciamento automático
de memória.
A partir do Oracle 9i essa configuração, que antes era A partir do 9i você pode utilizar até 4GB de RAM para
obrigatoriamente manual através de parâmetros configurados no ambientes Windows. (ver figura 2)
init.ora, pode ser definida como automática, bastando para isso Uma outra definição importante se refere ao conjunto de
você escolher a opção “Típico” e definir qual percentual da caracteres que você vai utilizar na instance. Prefira, para o
memória do servidor irá ser disponibilizada para o Oracle. Brasil, o conjunto WE8ISO8859P1, que oferece total
compatibilidade com instalações típicas de versões anteriores e
É importante considerar que nem toda memória pode ser com conjunto de caracteres “asc ii”, que contém acentuação,
disponibilizada, mesmo que no servidor rode apenas o banco de cedilha, etc...(ver figura 3)
dados (o que é altamente recomendável), pois existem processos
importantes do sistema operacional que precisam ser Para o parâmetro sort_área_size, chamado dimensionamento
considerados. para área de classificação, o número padrão de 524288 bytes é
uma excelente escolha para a maioria das instalações.
Se você precisar instalar outras funcionalidades corporativas,
como servidor de Internet, servidor de email, firewall, servidor de Vale lembrar que essa alocação não faz parte da SGA, e será
anti-vírus, etc, tenha em mente prioritariamente utilizar multiplicada pelo número de usuários conectados à instance, isto
servidores separados para cada função, em grau a ser definido é, para cada conexão neste caso a instance reservará 524288
segundo o porte da empresa e das aplicações que irão rodar. O bytes.
importante é que no servidor Oracle não tenhamos mais
aplicações rodando! Se a sua empresa tiver uma base muito Esse parâmetro, que define o quanto de memória cada sessão
pequena, talvez você consiga obter resultados satisfatórios com terá disponível para efetivar tarefas como “sort”, é fundamental
“tudo instalado no mesmo servidor”. para o desempenho. Alocações baixas serão sentidas
sensivelmente pelos usuários. (ver figura 4)
É importante ainda ressaltar que esse conceito não vale
apenas para Oracle, mas para qualquer banco de dados Em localização dos arquivos, defina sempre como necessária
relacional competente (Oracle, SQL Server, Sybase, Informix) a criação de arquivo de parâmetros (SPFILE), que é uma

14 MeGAZINE
Delphi

Figura 1 Figura 4

Figura 2 Figura 5

Aliás um comentário: esse recurso é fundamental num banco


de dados, já veio tarde ! (ver figura 5)
A última definição desta fase da instalação diz respeito ao
arquivamento automático, para backups “a quente”.

Na instalação, não defina esta opção, porque vamos falar dela


futuramente e porque você pode fazê-lo a qualquer momento
depois de criada a instance.

Bem, continuamos na próxima. Feliz Natal a todos !!!

E um bom 2003, 2004, 2005, 2006...


Figura 3

Sobre o autor
evolução do init.ora, do qual falaremos no futuro. Com essa
opção, o init.ora perde muito de sua importância e, o que é Mário Camilo Bohm - Bohm,Interal
melhor, para praticamente todos os parâmetros de inicialização Fone (011) 4223.9911
não será mais necessário re-iniciar a instance em casos de mario@bohminteral.com.br
alteração. Em outras palavras, você modifica os parâmetros da http://www.bohminteral.com.br
instance sem tirar a instance do ar !

MeGAZINE 15
Delphi

DataSnap
Parte VII - O Cliente COM+ - Master/Detail

Autor: Anderson Haertel Rodrigues

Introdução dbExpress), 03 DataSources (Guia Data Access) e 01 (Um)


No artigo anterior vimos como funciona o SharedConnection DataSetProvider (Guia Data Access). O 1o SQLDataSet devemos
e criamos nossa aplicação COM+ com manutenção a base de colocar o name = SQLDtStTAB_PARCEIROS, o 2o o name deve ser
dados simplificada, uma tabela e uma nova regra de negócios, o = SQLDtStTAB_PARCEIROS_CONT, o 3o igual a:
AutoIncremento. SQLDtStTAB_PARCEIROS_REFER_B e o 4 igual a:
SQLDtStTAB_PARCEIROS_REFER_C. O 1o DataSource a
Nesse artigo, reforço de forma reduzida a criação de um RDM propriedade name deve ser = DtSrcTAB_PARCEIROS_CONT, o 2o
com ligação ao nosso RDM de Conexão e criaremos um exemplo deve ser = DtSrcTAB_PARCEIROS_REFER_C e o 3o deve ser =
com atualizações e manutenções Master-Detail. DtSrcTAB_PARCEIROS_REFER_B. O name do DataSetProvider
deve ser = DtStPrvdrParceiros.
Mãos a Obra. Vamos abrir o Delphi!
Já que estamos com o DataSetProvider selecionado, devemos
RDM Master/Detail - SharedConnection. alterar as seguintes propriedades:
Vamos abrir o BPG (Borland Package Group - Project UpdateMode = upWhereKeyOnly, DataSet =
Manager) que se encontra no diretório C:\DataSnap e escolher SQLDtStTAB_PARCEIROS, Options = [poCascadeDeletes,
nosso servidor de aplicação como o projeto de trabalho. Vamos poPropogateChanges,poAllowCommandText], devemos ter a
agora em: File|New|Other|MultiTier| Transaction Data seguinte tela, Figura (1):
Module e indicar os seguintes
parâmetros e escolher as
seguintes opções:
CoClass = RDMParceiros,
Threading Model=Both e
Transaction Model=Requires
a new transaction, temos
novamente um RDM novinho
em folha na nossa frente.
Vamos salvar o mesmo com o
nome de
RDMCadParceiros.pas, no
diretório do Servidor:
C:\DataSnap\Servidor. No
RDM, vamos mudar a
Propriedade Pooled=True. Figura 1: O Object Inspector com os parâmetros do
Devemos colocar 04 (Quatro) SQLDataSets (Guia DataSetProvider.

16 MeGAZINE
Delphi

Antes de prosseguirmos, necessitamos ligar (unir) dois


RDM´s. ALT+F11 e devemos escolher: RDMConexao. Salve Tudo! ALTER TABLE TAB_PARCEIROS_REFER ADD
CONSTRAINT FK_1015_1013 FOREIGN KEY (ID_PARC)
A opção diferenciada de Options do DataSetProvider é: REFERENCES TAB_PARCEIROS (ID_PARC) ON DELETE
poCascadeDeletes, onde, se o Servidor de Banco de Dados que CASCADE;
usamos der suporte a deleção em Cascata, a mesma será
executada. Para o nosso exemplo, implementamos a deleção em Iremos fazer o teste de deleção em cascata quando iniciarmos
Cascata através das seguintes declarações: os nossos testes de manutenção na Tabela Master/Detail.

ALTER TABLE TAB_PARCEIROS_CONT ADD Com a união (uses) dos dois RDMs podemos enxergar o
CONSTRAINT FK_1014_1013 FOREIGN KEY (ID_PARC) SQLConnection que se encontra no RDMConexao, e ligar a
REFERENCES TAB_PARCEIROS (ID_PARC) ON DELETE propriedade SQLConnection de todos os SQLDataSet´s igual a:
CASCADE; Server_COMPlus.SQLCnctnBASE. Ok.

Vamos selecionar os três


DataSources e colocar a propriedade
DataSet=SQLDtStTAB_PARCEIROS.
Vamos selecionar o
SQLDtStTAB_PARCEIROS, a
propriedade CommandText deve ser a
seguinte:
SELECT CNPJ,ID_PARC,
INSC_EST,NOME FROM
TAB_PARCEIROS, (Duplo Click na
propriedade para abrir o CommandText
Editor), Figura (2).

Figura 2 (ao lado): A Propriedade


CommandText de
SQLDtStTAB_PARCEIROS.

Vamos selecionar o SQLDtStTAB_


PARCEIROS_CONT, a propriedade
CommandText deve ser a
seguinte:
SELECT
EMAIL_CONTATO, ID,
ID_PARC,
NOME_CONTATO,
TEL_CONTATO FROM
TAB_PARCEIROS_CONT
WHERE ID_PARC =
:ID_PARC, Figura (3):

Figura 3 (ao lado): A


Propriedade
CommandText de
SQLDtStTAB_
PARCEIROS_CONT.

MeGAZINE 17
Delphi

Vamos selecionar o SQLDtStTAB_PARCEIROS_REFER_C, a Vamos selecionar o SQLDtStTAB_PARCEIROS_REFER_B, a


propriedade CommandText deve ser a seguinte: SELECT propriedade CommandText deve ser a seguinte: SELECT
BCO_AGENCIA, BCO_CHEQUE_ESP, BCO_AGENCIA, BCO_CHEQUE_ESP,
BCO_DT_ABERT_CONTA, COM_DT_ULT_COMPRA, BCO_DT_ABERT_CONTA, COM_DT_ULT_COMPRA,
COM_DT_VCTO_ULT_PARC, COM_VL_PRESTACAO, COM_DT_VCTO_ULT_PARC, COM_VL_PRESTACAO,
COM_VL_TT_COMPRA, ID, ID_PARC, NOME_REF, TP_REF COM_VL_TT_COMPRA, ID, ID_PARC, NOME_REF, TP_REF
FROM TAB_PARCEIROS_REFER WHERE ID_PARC = FROM TAB_PARCEIROS_REFER WHERE ID_PARC =
:ID_PARC AND TP_REF = ‘C’, Figura (4): :ID_PARC AND TP_REF = ‘B’, Figura (5):

Figura 4: A Propriedade CommandText de SQLDtStTAB_PARCEIROS_REFER_C.

Figura 5: A Propriedade CommandText de SQLDtStTAB_PARCEIROS_REFER_B.

18 MeGAZINE
Delphi

Nos falta ligarmos os DataSources aos seus respectivos O RDM que acabamos de criar está pronto (nos falta uma
SQLDataSets para criarmos os relacionamentos. O Componente regra que escreveremos mais adiante para a manutenção correta
SQLDtStTAB_PARCEIROS_CONT deve ter sua propriedade dos registros Master/Detail).
DataSource igual a: DtSrcTAB_PARCEIROS_CONT, o
Componente SQLDtStTAB_PARCEIROS_REFER_C deve ter sua Devemos Salvar tudo!
propriedade DataSource igual a:
DtSrcTAB_PARCEIROS_REFER_C e o Componente Devemos abrir o nosso RDMConexao, ALT+F11 e devemos
SQLDtStTAB_PARCEIROS_REFER_B deve ter sua propriedade escolher: RDMCadParceiros.
DataSource igual a: DtSrcTAB_PARCEIROS_REFER_B. Agora,
temos o relacionamento completo. Vamos agora, fazer a ligação das Interfaces de RDMParceiros
com o RDMConexao e vice-versa, através da Type Library (TLB).
O RDM que acabamos de criar deve o seguinte Layout, View|Type Library, devemos ter a seguinte TLB inicial, Figura
Figura (6): (7):

Figura 6: O Remote Data


Module RDMCadParceiros.pas -
RDMParceiros.

Figura 7: A
Type Library
atual.

MeGAZINE 19
Delphi

Devemos criar uma nova Interface com o name de: RDMCadParceiros tem uma nova function e uma nova
IChildCadParceiros, vamos criar duas propriedades, uma Read- procedure.
Only e outra Write-Only, com o name de: RDMCadParceiros, a
propriedade Read-Only deve ter o seu Type igual a: Antes vamos criar a variável: FIServer_COMPlus:
IServer_COMPlus*, ficando igual a: struct tag IServer_COMPlus IServer_COMPlus, na seção private.
*. IChildCadParceiros deve ter seu Parent Interface igual a:
IAppServer. A Interface IRDMParceiros deve ter o seu Parent A function Get_RDMCadParceiros: IServer_COMPlus;
Interface igual a: IChildCadParceiros. safecall; deve ter a seguinte codificação: Result :=
FIServer_COMPlus, é claro entre o begin e end;, a procedure
Vamos agora criar uma nova propriedade Read-Only na Set_RDMCadParceiros(const Value: IServer_COMPlus); safecall;,
Interface IServer_COMPlus, com o name igual a: deve ter a seguinte codificação: FIServer_COMPlus := Value;, a
RDMCadParceiros, seu Type deve ser igual a: IRDMParceiros*, seção initialization, deve-se ter o seguinte código:
ficando igual a: struct tag IRDMParceiros *. Antes de fecharmos RDMCadParceirosFactory :=
a Type Library, vamos escolher todas as CoClass ( ), ir até a TComponentFactory.Create(ComServer,
Guia COM+, colocar os seguintes valores e parâmetros: Marcar TRDMParceiros,Class_RDMParceiros, ciMultiInstance,
Object Pooling, Creation Timeout=10000, Call tmBoth);. Em RDMConexao devemos ter o seguinte código na
Syncronatization=Required e Transaction Model=Requires a function Get_RDMCadParceiros: IRDMParceiros; safecall;
new transaction, devendo todas as CoClass ficarem com os Result := RDMCadParceirosFactory.CreateCOMObject(nil)
seguintes parâmetros, Figura (8): as IRDMParceiros;

Figura 8: Mostrando como deve ficar os parâmetros de todas as CoClass.

20 MeGAZINE
Delphi

Result.RDMCadParceiros := Self; 01 (Um) DBNavigator - Align=alBottom;


01 (Um) PageControl - (Guia Win32), seu name deve ser
Para quem perdeu a Parte VI, eu expliquei detalhadamente igual a: PgCntrlParceiros, coloque a sua propriedade Align igual
como se trabalha com SharedConnection. Aqui, como citado na a: alClient. Logo após vamos criar duas TabSheets, clique com o
introdução, foi apenas um pequeno exemplo de como fazer para botão direito do Mouse no PageControl e escolha New Page duas
os dois RDM´s (Objetos COM) se conversarem. Após isso tudo, vezes. TabSheet1 o seu name deve ser igual: TbShtFormulario e
salve e vá até o menu: Run|Register ActiveX Server, dessa seu Caption igual a: Formulario, TabSheet2 o seu name deve ser
forma registramos as alterações na nossa DLL COM+. Clique em igual a: TbShtCont_Refer e seu Caption igual a: Contatos e
Ok. Referências. Pronto, temos o básico do FORM pronto.

Cliente COM+ Necessitamos agora, colocar os componentes de acesso ao


Servidor de Aplicação e os Data-awares para manutenção dos
CTRL+ALT+F11 e vamos escolher o projeto dados.
ClienteCOMPlus.exe para trabalharmos.
04 (Quatro) ClientDataSet´s (Guia Data Access);
Necessitamos criar o nosso Formulário para dar manutenção 04 (Quatro) DataSource´s (Guia Data Access);
no nosso Cadastro Master/Detail. 01 (Um) ConnectionBroker (Guia DataSnap);
01 (Um) SharedConnection (Guia DataSnap);
Vou nesse momento explicar a intenção do cadastro de
Parceiros. Temos a tabela principal TAB_PARCEIROS, a tabela Na Guia Formulário do PageControl:
de Contatos do Parceiro - TAB_PARCEIROS_CONT, a tabela de 02 (Dois) Buttons;
Referências Comerciais e Bancárias na tabela
TAB_PARCEIROS_REFER, o que diferencia cada referência uma Na Guia Contatos e Referências:
da outra é a coluna: TP_REF. Por isso se você olhar, existe um 03 (Três) DBGrids;
TP_REF = ‘?’ no CommandText da tabela
TAB_PARCEIROS_REFER. Ok, agora que já expliquei a Antes de iniciar os testes, devemos fazer as seguintes
estrutura do nosso exemplo, vamos passar a parte de montagem ligações, até para que possamos utilizar os TFields da Tabela
do formulário. Principal e deixar o mesmo criar para nós os Data-Awares.

Você verá que, o Delphi trata quase tudo internamente para A propriedade Name do SharedConnection deve ser igual a:
nós, não necessitamos de quase nenhuma linha de programação ShrdCnctnParceiros, e seu ChildName igual a:
para montar o nosso Master/Detail. RDMCadParceiros.
Se a mesma não aparecer na lista, reveja as ligações feitas na
E afirmo que você pode confiar no mecanismo do Delphi para Type Library, ParentConnection deve ser igual a:
tal tarefa, até o momento não tive problemas com essa estrutura, DMConexao.DCOMCnctnConexao.
e já criei alguns Master´s/Detail´s dentro do meu sistema.
A propriedade Name do ConnectionBroker deve ser igual a:
Mãos a Obra! CnctnBrkrParceiros, Connection deve ser igual a:
ShrdCnctnParceiros (O SharedConnection que se encontra no
Vamos criar um novo FORM no Delphi. Já vamos salvar o Formulário).
mesmo com o seguinte nome: uFrmParceiros.pas no diretório do
projeto Cliente, isto é, em: C:\DataSnap\Cliente. A propriedade Name do ClientDataSet1 deve ser igual a:
ClntDtStTAB_PARC, ConnectionBroker deve ser igual a:
O name do nosso Formulário deve ser igual: FrmParceiros, e CnctnBrkrParceiros (O ConnectionBroker que se encontra no
seu Caption igual a: Cadastro de Parceiros. Já temos o nosso Formulário) e ProviderName deve ser igual a:
FORM pronto para colocarmos os componentes necessários para DtStPrvdrParceiros, o mesmo deve aparecer na lista se todas as
criarmos o nosso cadastro Master/Detail. ALT+F11 e devemos ligações feitas na Type Library estão corretas.
escolher: uDMConexao, Salve Tudo ( )!
Duplo click para editar os TFields, e peça para incluir todos os
Vamos colocar os seguintes componentes no formulário: campos, após isso devemos ter a seguinte Figura (9):

MeGAZINE 21
Delphi

DtSrcTAB_PARC e seu DataSet ligado a: ClntDtStTAB_PARC.

ClientDataSet2 deve ter seu name igual a:


ClntDtStTAB_PARC_CONT e, seu DataSetField igual a:
ClntDtStTAB_PARCSQLDtStTAB_PARCEIROS_CONT.

DataSource2 deve ter o seu name alterado para:


DtSrcTAB_PARC_CONT e seu DataSet ligado a:
ClntDtStTAB_PARC_CONT.

ClientDataSet3 deve ter seu name igual a:


ClntDtStTAB_PARC_REF_C e, seu DataSetField igual a:
ClntDtStTAB_PARCSQLDtStTAB_PARCEIROS_REFER_C.

DataSource3 deve ter o seu name alterado para:


DtSrcTAB_PARC_REFER_C e seu DataSet ligado a:
ClntDtStTAB_PARC_REF_C.

ClientDataSet4 deve ter seu name igual a:


ClntDtStTAB_PARC_REF_B e, seu DataSetField igual a:
ClntDtStTAB_PARC_REF_B.

DataSource4 deve ter o seu name alterado para:


Figura 9: TFields de ClntDtStTAB_PARC. DtSrcTAB_PARC_REFER_B e seu DataSet ligado a:
ClntDtStTAB_PARC_REF_B.
As três últimas colunas são colunas DataSetFields. As
mesmas não existem na Base de Dados, mas, fazem parte do Com as ligações feitas acima, ligamos o Master ao seus
esquema de Ligação Master/Detail do Delphi. Details.

DataSetField não é um conceito novo, já existia antes da Devemos apenas ligar os Grids aos seus respectivos
chegada da dbExpress, mas, está se tornando quase que DataSources:
obrigatório o uso do mesmo. DBGrid1 seu name= DBGrdTAB_PARC_CONT e seu
DataSource= DtSrcTAB_PARC_CONT - DBGrid2 seu name=
Quando criamos um relacionamento em DataSet´s no DBGrdTAB_PARC_REFER_C e seu DataSource=
Servidor de Aplicação e exportamos o DataSet através do DtSrcTAB_PARC_REFER_C - DBGrid3 seu name=
DataSetProvider, o Delphi cria este novo tipo de Coluna, para DBGrdTAB_PARC_REFER_B e seu DataSource=
facilitar a nossa vida. DtSrcTAB_PARC_REFER_B.

Esta nova Coluna é criada no DataSet Master e representa Também vamos colocar o name do DBNavigator1=
todas as linhas do Detalhe para apenas uma linha do Master. DBNvgtrTAB_PARC e seu DataSource= DtSrcTAB_PARC.

É através dos DataSetFields que ligaremos os E por último, ligar os DBEdits ao DataSource:
ClientDataSet´s que se encontram no Formulário. DtSrcTAB_PARC e ligar os mesmos as suas respectivas colunas.

Para colocarmos os DBEdits, devemos executar um Duplo Após tudo isso, nos falta apenas modificar os names dos
Click no ClientDataSet- ClntDtStTAB_PARC e arrastar os Buttons:
TFields criados, mas, deixaremos de fora as Colunas Button1 = BtnAtualizar;
DataSetField. Button2 = BtnCancelar;

DataSource1 deve ter o seu name alterado para: Devemos ter a seguinte tela, Figura (10) e Figura (11):

22 MeGAZINE
Delphi

Figura 10: A Guia Formulário - Layout Sugerido.

Figura 10: A Guia Formulário - Layout Sugerido.

Figura 11: A Guia Contatos e Referências - Layout Sugerido.

MeGAZINE 23
Delphi

Vamos implementar nesse momento a unit. No evento procedure TFrmParceiros.BtnCancelarClick


OnCreate() do Formulário, devemos ter o seguinte código, (Sender: TObject);
Listagem 1: begin
if ClntDtStTAB_PARC.ChangeCount > 0 then
procedure TFrmParceiros.FormCreate(Sender: TObject); ClntDtStTAB_PARC.CancelUpdates;
begin end;
ClntDtStTAB_PARC.Open;
end; Listagem 5: O método responsável por desfazer as alterações
locais.
Listagem 1: O Evento OnCreate() do Form e a abertura
da Tabela. A Listagem 5 mostra o método que cancela as alterações
locais. É necessário apenas uma chamada a CancelUpdates para
O Evento OnClose() deve ter o seguinte código, Listagem 2: que todas as alterações, inclusive as dos Detalhes sejam desfeitas.
Se quisermos desfazer apenas as alterações de um determinado
procedure TFrmParceiros.FormClose(Sender: TObject; Detalhe, devemos ter o mesmo método ligado ao ClientDataSet
var Action: TCloseAction); em específico.
begin
ClntDtStTAB_PARC.Close; Agora precisamos definir as “quatros linhas” que “auxiliam”
Action := caFree; o Delphi na tarefa de gravação.

end; No Evento BeforePost() do ClntDtStTAB_PARC, devemos ter


o seguinte código, Listagem 6:
Listagem 2: O Evento OnClose() do Form, o fechamento da
tabela e a liberação dos recursos utilizados pelo formulário. procedure TFrmParceiros.ClntDtStTAB_PARCBeforePost
(DataSet: TDataSet);
O Evento OnDestroy() deve ter o seguinte código, Listagem 3: begin
if DataSet.FieldByName(‘ID_PARC’).IsNull then
procedure TFrmParceiros.FormDestroy(Sender: DataSet.FieldByName(‘ID_PARC’).AsInteger := 0;
TObject); end;
begin
FrmParceiros := nil; Listagem 6: A “Ajuda” para o Delphi gravar sem erros a
end; atualização Local.

Listagem 3: Indicando a referência do formulário para A ajuda na gravação dos dados no Delta. O por que dessa
nil. ajuda eu expliquei na Parte VI.

Devemos ter o seguinte código para o botão - Atualizar - Da mesma forma, devemos proceder para os outros três
Enviar para o Servidor, Listagem 4: ClientDataSets. Como eu utilizei o mesmo nome de Coluna para
a Chave Primária (como sempre faço, PK tem o nome da coluna
procedure TFrmParceiros.BtnAtualizarClick sempre de “ID”, salvo alguns casos, onde necessito de Master/
(Sender: TObject); Detail), posso implementar apenas um evento para os três
begin ClientDataSets. No Evento BeforePost() do
ClntDtStTAB_PARC.ApplyUpdates(0); ClntDtStTAB_PARC_CONT devemos ter o seguinte código,
end; Listagem 7:

Listagem 4: O método responsável por enviar o Delta para o procedure


Servidor de Aplicação. TFrmParceiros.ClntDtStTAB_PARC_CONTBeforePost
(DataSet: TDataSet);
Devemos ter o seguinte código para o botão - Desfazer Dados begin
Locais, Listagem 5: if DataSet.FieldByName(‘ID’).IsNull then

24 MeGAZINE
Delphi

DataSet.FieldByName(‘ID’).AsInteger := 0; DeltaDS.FieldByName(‘ID’).NewValue :=
end; FIServer_COMPlus.AutoIncremento(‘TAB_PARCEIROS_REFER’,’ID’);
DeltaDS.FieldByName(‘TP_REF’).NewValue := ‘C’
Listagem 7: Novamente a “Ajuda” para o Delphi gravar sem end
erros a atualização Local, neste caso, para os Detalhes. else if SourceDS = SQLDtStTAB_PARCEIROS_REFER_B
then
Agora devemos ligar o evento BeforePost() de
ClntDtStTAB_PARC_REF_C e ClntDtStTAB_PARC_REF_B, begin
para o mesmo evento de ClntDtStTAB_PARC_CONT. DeltaDS.FieldByName(‘ID_PARC’).NewValue :=
DeltaDS.DataSetField.DataSet.FieldByName(‘ID_PARC’).AsInteger;
É necessário apenas uma chamada do ApplyUpdates() para DeltaDS.FieldByName(‘ID’).NewValue :=
as tabelas envolvidas em Master/Detail e ligadas através de FIServer_COMPlus.AutoIncremento(‘TAB_PARCEIROS_REFER’,’ID’);
DataSetFields. DeltaDS.FieldByName(‘TP_REF’).NewValue := ‘B’;
end;
Server COM+ end;
Mais uma vez o vai e volta de “lados”. Necessitamos apenas end;
programar o evento BeforeUpdateRecord do DataSetProvider que
se encontra em: RDMParceiros, Listagem 8: Listagem 8: A regra de negócios Master/Detail.

procedure Vamos analisar a regra:


TRDMParceiros.DtStPrvdrParceirosBeforeUpdateRecord
(Sender: TObject; SourceDS: TDataSet; DeltaDS: Estamos verificando apenas se é Inclusão (if UpdateKind =
TCustomClientDataSet; UpdateKind: TUpdateKind; var ukInsert then), após verificamos qual tabela está sendo
Applied: Boolean); atualizada (if SourceDS = SQLDtStTAB_PARCEIROS then... e
demais else ifs...), se for SQLDtStTAB_PARCEIROS, geramos o
begin AutoIncremento() para a coluna ID_PARC
if UpdateKind = ukInsert then ( DeltaDS.FieldByName(‘ID_PARC’).NewValue :=
FIServer_COMPlus.AutoIncremento(‘TAB_PARCEIROS’,’ID_PARC’);
begin ), se for SQLDtStTAB_PARCEIROS_CONT, passamos a coluna
if SourceDS = SQLDtStTAB_PARCEIROS then ID_PARC o relacionamento e criamos o AutoIncremento() para a
coluna ID, fizemos a mesma coisa para as tabelas
begin SQLDtStTAB_PARCEIROS_REFER_C e
DeltaDS.FieldByName(‘ID_PARC’).NewValue := SQLDtStTAB_PARCEIROS_REFER_B, apenas com a diferença
FIServer_COMPlus.AutoIncremento(‘TAB_PARCEIROS’,’ID_PARC’); de passarmos o tipo de referência:
end (DeltaDS.FieldByName(‘TP_REF’).NewValue := ‘C’ e ou
else if SourceDS = SQLDtStTAB_PARCEIROS_CONT DeltaDS.FieldByName(‘TP_REF’).NewValue := ‘B’ ), para suas
then respectivas tabelas.

begin Salve Tudo e registre a DLL!


DeltaDS.FieldByName(‘ID_PARC’).NewValue :=
DeltaDS.DataSetField.DataSet.FieldByName(‘ID_PARC’).AsInteger; Agora, nos resta apenas testar o exemplo Master/ Detail que
DeltaDS.FieldByName(‘ID’).NewValue := criamos.
FIServer_COMPlus.AutoIncremento(‘TAB_PARCEIROS_CONT’,’ID’); Fiz questão de usar colunas e situações que usamos no dia-a-
end dia, para, uma melhor compreensão e visualização de como
else if SourceDS = SQLDtStTAB_PARCEIROS_REFER_C funciona e como é fácil de criarmos Master/Detail.
then
A forma que exemplifiquei para a criação de Master/Detail,
begin não funciona apenas para 3 Camadas, pode ser usada em
DeltaDS.FieldByName(‘ID_PARC’).NewValue := Cliente/Servidor e não funciona apenas para a dbExpress,
DeltaDS.DataSetField.DataSet.FieldByName(‘ID_PARC’).AsInteger; também pode ser usada com a BDE, IBX, etc.

MeGAZINE 25
Delphi

Teste todas as opções do Lado Cliente, inclusive a Exclusão Conclusão


em Cascata. Neste artigo implementamos o “temido” Master/Detail em
aplicações 3 Camadas. Vimos que não é um bicho de sete cabeças
Veremos agora, uma figura que representa o Cliente, o como pensávamos. Criamos também a regra de negócios para a
DataSnap(MIDAS) e COM+, Figura (12): atualização correta das tabelas envolvidas no Master/Detail.
No Próximo artigo (Parte final), veremos como distribuir
nossos aplicativos usando COM+.
Usaremos para a distribuição a independência total de
localização!
Qualquer dúvida que surja estou a disposição. Também estou
a disposição para troca de idéias.
Sucesso e Saúde a todos! Um Abraço.
Sobre o autor
Anderson Haertel Rodrigues
Consultor em desenvolvimento de Sistemas
Client/Server- MultiCamadas/DataSnap.
Oferece treinamentos para empresas em: InterBase,
SQL-Server, Delphi e COM+.
anderson.hr@bol.com.br anderson.hr@zipmail.com.br
Figura 12: O Esquema de Camadas em aplicações COM+. Florianópolis - Santa Catarina - Brasil.

26 MeGAZINE
Coluna do Alexandre Magno

Tudo Sobre Domínios


Autor: Alexandre Magno

O que são domínios? Veja no Capítulo 5 do manual Data Definition Guide a sintaxe
completa da instrução CREATE DOMAIN.
Um domínio é um template de definições de colunas. Quando O nome do domínio deve ser único em todo o banco de dados e
você define uma tabela, você pode especificar o tipo de dado, valor o tipo de dado deve ser um dos que foram vistos na seção
“default”, character set, null constraints e check constraints para anterior. Por exemplo:
cada coluna individualmente, ou você pode informar que esta
coluna deve ser definida por um domínio previamente criado com CREATE DOMAIN Cidade AS VARCHAR(15);
todas as informações necessárias. Domínios são usualmente Em adicional, você pode especificar as seguintes opções –
definidos antes da criação das tabelas, para que você possa nesta ordem – na parte de definição do domínio:
utilizá-los na definição destas tabelas.
Use domínio para tipos de colunas que estejam presentes em • O parâmetro DEFAULT
várias tabelas do seu banco de dados para tornar fácil a
passagem de parâmetros para estas colunas. Por exemplo, em O parâmetro DEFAULT especifica um valor “padrão” para
um sistema comercial, você deve definir um domínio “CEP” que ser usado se nenhum valor for aplicado. O valor “padrão”
será utilizado nos seguintes lugares: somente é aplicado quando o registro é inserido pela primeira vez
no banco de dados, se você depois remover o valor original, o
• CEP do Cliente; DEFAULT não será inserido. A sintaxe da opção default é:
• CEP do Fabricante;
• CEP da Filial; nome_col DEFAULT [valor_default | NULL | USER]
• CEP do Vendedor;
• entre outras... Colocando USER como valor “default” o Firebird adicionará o
nome do usuário que está conectado em cada nova inserção.
A instrução CREATE DOMAIN DEFAULT geralmente é utilizado nas seguintes situações:
Use esta instrução para criar um novo domínio. Sua sintaxe
básica é a seguinte: • Para colunas caractere, você pode precisar indicar um valor
“default” explicitamente, ou use NULL para especificar um valor
CREATE DOMAIN domain_name AS datatype; nulo, ou use USER para especificar o valor do USER NAME

MeGAZINE 27
Coluna do Alexandre Magno

corrente. uma coluna diretamente na tabela, a restrição CHECK possui


• Para colunas numéricas, você pode precisar indicar um opções adicionais. A sintaxe para a restrição CHECK em
valor “default” explicitamente, ou use NULL para especificar um definições de domínio é:
valor nulo.
• Para colunas data, você pode precisar indicar um valor CHECK(VALUE expression)
“default” explicitamente, ou utilizar uma das seguintes palavras
reservadas: YESTERDAY, TODAY, NOW, TOMORROW, ou Na definição CHECK, a palavra reservada VALUE
NULL. representa o valor da coluna definida neste domínio.
• Default não é válido para colunas BLOB.
A tabela a seguir mostra os operadores suportados pelo
A seguir alguns exemplos de criação de domínios: Firebird para trabalharem juntamente com o parâmetro
CREATE DOMAIN UltimoAtualizador AS VARCHAR(31) VALUE, tabela abaixo.
DEFAULT USER;

Expressão Descrição
CREATE DOMAIN DataCadastro AS DATE
DEFAULT ‘Today’;
= value Igual a

CREATE DOMAIN Desconto AS SMALLINT < value Menor que


DEFAULT 0;
> value Maior que
CREATE DOMAIN NumCartaoCredito AS CHAR(19)
DEFAULT NULL; <= value Menor ou igual a

Quando você usa um domínio na definição de uma tabela, o >= value Maior ou igual a
valor DEFAULT pode ser sobrescrito por uma nova condição.
!< value Não menor que

• O parâmetro NOT NULL !> value Não maior que

Este parâmetro força que um valor seja armazenado na <> value Diferente de
coluna. Ele é muito similar à opção REQUIRED encontrada em
alguns bancos de dados de PC, como o Paradox. != value Não igual a

O parâmetro NOT NULL é testado sempre que o registro é BETWEEN value AND value Entre a faixa de valores passada
gravado no banco de dados, e também nas operações de inserção
e atualização. LIKE value Use '%' para 0 ou mais caracteres
Use '_' para 1 único caractere

Não use ambos DEFAULT NULL e NOT NULL na mesma


IN (value,value,...value) Um dos elementos da lista
definição de domínio.

IS NULL Testa se o valor é nulo(ausência


• A restrição CHECK do valor)

CHECK testa o valor inserido dentro da coluna definida pelo IS NOT NULL Testa se o valor é não nulo
domínio para verificar se este valor satisfaz as condições da
expressão. Para definições de domínio, restrições CHECK são CONTAINING value Procura em string case insensitive
limitadas à comparação com um valor ou uma lista de valores, e
somente uma restrição CHECK é permitida. Quando você define STARTING WITH value Procura em string case sensitive

28 MeGAZINE
Coluna do Alexandre Magno

Por exemplo: A sintaxe do ALTER DOMAIN é como mostramos a seguir:

CHECK(VALUE <= 5) ALTER DOMAIN domain_name


CHECK(VALUE BETWEEN 0 and 10) TYPE novo_tipo(tamanho);
CHECK(VALUE STARTING WITH ‘(091)’)
CHECK(VALUE LIKE ‘%SEN%’) ALTER DOMAIN domain_name
CHECK(VALUE NOT IN(PA, AM, SP)) DROP DEFAULT;
CHECK((VALUE >= ‘YESTERDAY’) AND (VALUE <=
‘TODAY’)) ALTER DOMAIN domain_name
CHECK((VALUE IS NULL) OR (VALUE < 60)) SET DEFAULT default_value | NULL | USER;

• A cláusula COLLATE ALTER DOMAIN domain_name


Somente para colunas CHAR e VARCHAR, você pode DROP CONSTRAINT;
especificar um seqüência de coleção(COLLATE) válida para o ALTER DOMAIN domain_name
character set utilizado. O character set é definido como parte da ADD CHECK(value_expression);
definição do banco de dados, ou com o tipo de dados. Por exemplo,
assumiremos que o character set definido em nosso banco de A instrução DROP DOMAIN
dados foi o ISO8859_1.
O Firebird fornece a instrução DROP DOMAIN para remover
A seguinte definição de domínio seleciona uma das definições um domínio de um banco de dados. Esta instrução só será
de COLLATE deste character set: permitida se nenhuma tabela estiver utilizando o domínio
naquele momento. A sintaxe é:
CREATE DOMAIN Cidade VARCHAR(20)
COLLATE PT_PT; DROP DOMAIN domain_name;

A instrução ALTER DOMAIN Sobre o autor


O Firebird fornece uma instrução ALTER DOMAIN para
mudar o valor default, uma restrição CHECK e/ou o tipo e Alexandre Magno é diretor da Argos Tecnologia em
tamanho do domínio. Esta alteração é aplicada imediatamente Belém do Pará.
em todas as colunas que utilizem aquele domínio. amagno@argostecnologia.com

Windows ou Linux? Ambos!


CLXpert: O mais novo produto Argos já está no mercado
O CLXpert Wizard, é um aplicativo desenvolvido pela Argos
Tecnologia, que porta com extrema desenvoltura e facilidade seu
projeto Delphi, para um projeto nativo Kylix.Saiba mais sobre o
produto e solicite logo o seu!

Argos Tecnologia Ltda - Av. Almte. Wandenkolk, nº 811, sala 1003, Umarizal - Belém / PA
Fones: (91) 222-6578 - http://www.argostecnologia.com/clxpert/

MeGAZINE 29
Perguntas & Respostas

Perguntas &
Respostas
Pergunta: Como fazer o componente SQLConection receber Pergunta: Criei uma aplicação usando o IntraWeb e preciso
as configurações de um arquivo INI que eu criei? Eu vi que que ao ser executado seja carregado um arquivo INI que
existe uma propriedade LoadFromFileIni mas como usá-la? configura o acesso ao Oracle. Este arquivo INI está junto a
aplicação no servidor.
Resposta: Para passar as configurações para o Tentei:
sqlConnection, primeiro crie um arquivo INI contendo os WebApplication.GetNamePath;
parâmetros necessários para a conexão: WebApplication.UrlBase;
WebApplication.IP;
[MINHA_CONEXAO]
DriverName=Interbase Nenhum funcionou a contento. A forma que consegui foi usando
BlobSize=-1 o caminho dentro da aplicação:
CommitRetain=False vCaminho := ‘c:\inetpub\wwwroot\Isapi\MeuArq.INI’;
Database=192.168.0.1:C:\PASTA\ARQUIVO.GDB Mas preciso de algo dinâmico. Vocês tem alguma solução para o
ErrorResourceFile= problema?
LocaleCode=0000 Resposta: Existe uma variável de ambiente no Intraweb que
Password=masterkey retorna o path físico onde a aplicação está rodando, veja o código
RoleName=RoleName abaixo:
ServerCharSet=
SQLDialect=3 uses
Interbase TransIsolation=ReadCommited SWSystem;
User_Name=sysdba procedure TformMain.IWButton1Click(Sender: TObject);
WaitOnLocks=True begin
IWEdit1.Text := gsAppPath; // retorna o path
A propriedade “LoadParamsOnConnect” deve estar “False”; end;

Importante: As propriedades abaixo devem estar Dúvida enviada Nirlan E. Fundão, São Mateus/ES.
preenchidas:
Pergunta: Estou precisando mudar a propriedade
GetDriverFunc = getSQLDriverINTERBASE DisplayFormat dos TFields de um componente TIBQuery em
LibraryName = dbexpint.dll tempo de execução, para que em uma consulta os dados
VendorLib = GDS32.DLL aparecam formatados. Sendo que a propriedade referida
é somente leitura, gostaria de saber de que forma eu conseguiria
Após isso, para carregar os parâmetros e ativar o realizar esta formatação.
sqlConnection utilize o método abaixo: Resposta: Para fazer este processo basta utilizar a seguinte
instrução:
sqlConnection.LoadParamsFromIniFile(
ExtractFilePath(ParamStr(0)+’Config.Ini’); TFloatField(IBQuery.FieldByName(
sqlConnection.Open; ‘NomeCampo’)).DisplayFormat := ‘###,##0.00’;

Dúvida enviada por Editora Alto Astral, Bauru/SP. Dúvida enviada por Edson Murilo Maestri, Blumenal/SC

30 MeGAZINE

Você também pode gostar