9 771808 726072 40015 · 4 FireBird Trabalhando com UDFs Sobre o autor Thiago Cavalheiro...

32
1 9 771808 726072 4 5 1 0 0

Transcript of 9 771808 726072 40015 · 4 FireBird Trabalhando com UDFs Sobre o autor Thiago Cavalheiro...

1

9 771808 726072 45100

3

THE CLUBAv. Profº Celso Ferreira da Silva, 190

Jd. Europa - Avaré - SP - CEP 18.707-150Informações: (14) 3732-3689

Suporte: (14) 3733-1588 - Fax: (14) 3732-0987

Internethttp://www.theclub.com.br

Cadastro: [email protected]: [email protected]

Informações: [email protected]

DúvidasCorrespondência ou fax com dúvidas devem

ser enviados ao - THE CLUB, indicando"Suporte".

OpiniãoSe você quer dar a sua opinião sobre o clube

em geral, mande a sua correspondência para aseção "Tire sua dúvida".

ReproduçãoA utilização, reprodução, apropriação,

armazenamento em banco de dados, sobqualquer forma ou meio, de textos, fotos e

outras criações intelectuais em cada publicaçãoda revista “The Club Megazine” são

terminantemente proibidos sem autorizaçãoescrita dos titulares dos direitos autorais.

Impressão e acabamento:HIPERGRAF Indústria Gráfica

Tel.: (14) 3641-1665 - Cep 17340-000Rua Francisca A. Pereira Borges, 436

Barra Bonita - Vila São CaetanoTiragem: 5.000 exemplares

Copyright The Club Megazine 2007

Diretor TécnicoMauro Sant’Anna

ColaboradoresMauto Sant´Anna

EDITORIAL

Editorial

Editorial .................................................................................. 03Trabalhando com UDFs ......................................................... 04Silverlight ................................................................................ 12Acessando o Firebird com o Driver DBX específico (UB) ...... 14Firebird 2.1 (Beta) .................................................................. 17Perguntas & Respostas ......................................................... 22Dicas & Truques .................................................................... 27

Delphi é marca registrada da Borland International,as demais marcas citadas são registradas

pelos seus respectivos proprietários.

Olá Amigos do The Club,

Esta edição está recheada de matérias interessantes. O Nossoconsultor técnico Vitor Scarso traz muitas novidades, uma tratandode algumas novidades do “Delphi 2007 for Win 32” e outra do novoFirebird 2.1 (versão beta). Outras matérias ditas também comoimportantes para os senhores, uma denominada “Trabalhando comUDFs” ( Funções definidas pelo usuário) e outra chamada“Acessando o Firebird com seu Driver Específico”, estas duas foramescrita pelo nosso consultor técnico Thiago CavalheiroMontebugnoli. Não deixem de verificar nossa seção clássica de“Perguntas e Respostas” e “Dicas e Truques”, onde irão encontraras perguntas mais frequentes realizadas em nosso suporte e dicasque certamente irão ajudá-los.

Boa Leitura.

4

FireBird

Trabalhando com UDFsTrabalhando com UDFsTrabalhando com UDFsTrabalhando com UDFsTrabalhando com UDFsSobre o autorThiago Cavalheiro Montebugnoli é tecnólogo, formado pelaFaculdade de Tecnologia de Botucatu – SP (FATEC) econsultor técnico do The Club.

Por Thiago Cavalheiro [email protected]

O que é uma UDF?

Nesta matéria abordarei um assunto muito interessante emse tratando do Banco de Dados Firebird, as denominadas UDFs,para quem não conhece UDF(User Defined Function) sãofunções definidas pelo usuário, uma função escrita em qualquerlinguagem de programação capaz de gerar uma bibliotecacompartilhada. No Windows são conhecidas pelo nome deDynamic Link Libraries (as conhecidas DLLs).

Utilizando as UDFs

De primeiro momento estarei demonstrando como utilizar asUDFs vindas do próprio Interbase/Firebird e estarei listando asprincipais, consequentemente as que são mais utilizadas e emseguida estarei apresentando algumas Bibliotecas de terceiros.

As UDFs são armazenadas por padrão no seguinte diretórioC:\Arquivos de programas\Firebird\Firebird_x\UDF. Quando ofirebird é instalado, como padrão teremos quatro arquivos, umchamado ib_udf.dll outro fbudf.dll (as UDFs) e mais doisdenominados ib_udf e fbudf (onde ficam as declarações dasrespectivas UDFs).

Primeiramente clique com o botão direito sobre o ib_udf eabra com o bloco de notas. Percebam que aparecerão váriasdeclarações de UDFs que poderão ser utilizadas pelo Firebird.

Iremos utilizar a conhecida ferramenta para gerenciamentode Banco de Dados chamada Ibexpert (caso não possuam, ela

Figura 01. Registrando o Banco Employee.

5

FireBird

possui uma versão Freeware que poderá ser baixada através do sitewww.ibexpert.com). Abra o Ibexpert e registre o banco de dados quejá vem com o Firebird, a partir do menu Database selecione a opçãoRegister Database e configure o banco de dados EMPLOYEE.FDBcomo na figura 01. (Por padrão esta Base de Dados é encontrada noseguinte diretório

C:\Arquivos deprogramas\Firebird\Firebird_x\examples\EMPLOYEE.FDB ondex é a versão do Firebird utilizado).

Com o Ibexpert aberto clique no ícone (New SqlEditor) para podermos declarar as nossas UDFs. Neste momentoirei utilizar uma UDF explicando como deve ser declarada seguidade um exemplo.

Abra o arquivo ib_udf e copie o seguinte código:

DECLARE EXTERNAL FUNCTION absDOUBLE PRECISIONRETURNS DOUBLE PRECISION BY VALUEENTRY_POINT ‘IB_UDF_abs’ MODULE_NAME

‘ib_udf’;

Cole no ibexpert em seguida pressione F9 ou clique em Executee por final dê um Commit Transacion. Vejam quoi adicionado aoBanco de Dados ma UDF chamada ABS (Figura 02).

Figura 02. UDF Criada no Banco Employee.

Select codigo,Abs(valor) from tabela Este select iráretornar valores positivos, ou seja, teremos como

resultset os seguintes registros.

Conhecendo as UDFs

A partir daqui irei apresentar algumas das principaisUDFs deste arquivo ib_udf seguida de uma breve explicaçãosobre elas.

a s c i i _ c h a r

DECLARE EXTERNAL FUNCTION ascii_charINTEGERRETURNS CSTRING(1) FREE_ITENTRY_POINT ‘IB_UDF_ascii_char’

MODULE_NAME ‘ib_udf’;

Utilização: Recebe como parâmetro um valor inteiro eretorna seu valor em código Ascii.

Exemplo: select ascii_char(cust_no) from sales

a s c i i _ v a l

DECLARE EXTERNAL FUNCTION ascii_val CHAR(1) RETURNS INTEGER BY VALUE ENTRY_POINT ‘IB_UDF_ascii_val’MODULE_NAME ‘ib_udf’;

Utlização: Recebe como parâmetro um valor ascii e retornaum valor inteiro correspondente.

Exemplo: select ascii_val(campo) from tabela

Esta UDF recebe como parâmetro um valor numérico(double

precision) e irá retornar um número absoluto (positivo). Iremos

simular uma situação.

Temos a seguinte tabela:

6

FireBird

div

DECLARE EXTERNAL FUNCTION divINTEGER, INTEGERRETURNS DOUBLE PRECISION BY VALUEENTRY_POINT ‘IB_UDF_div’ MODULE_NAME

‘ib_udf’;

Utilização: Esta UDF recebe como parâmetros dois valoresinteiros e retorna a parte inteira da divisão do primeiro pelosegundo.

Exemplo: select div(cust_no,qtyordered) from sales

floor

DECLARE EXTERNAL FUNCTION floorDOUBLE PRECISIONRETURNS DOUBLE PRECISION BY VALUEENTRY_POINT ‘IB_UDF_floor’ MODULE_NAME

‘ib_udf’;

Utilização: Recebe como parâmetro um valor do tipo doubleprecision e retorna a parte inteira deste parâmetro

Exemplo: select floor(new_salary) from salary_history

log

DECLARE EXTERNAL FUNCTION logDOUBLE PRECISION, DOUBLE PRECISIONRETURNS DOUBLE PRECISION BY VALUEENTRY_POINT ‘IB_UDF_log’ MODULE_NAME

‘ib_udf’;

Utilização: Útil para operações matemáticas, esta UDF recebecomo parâmetro dois valores(x e y) e tem como retorno ologaritmo base x por y

Exemplo: select log(x,y) from tabela

lower

DECLARE EXTERNAL FUNCTION lowerCSTRING(255)RETURNS CSTRING(255) FREE_ITENTRY_POINT ‘IB_UDF_lower’ MODULE_NAME

‘ib_udf’;

Utilização: Recebe como parâmetro um campo tipo string deaté 255 caracteres e como retorno um valor com caixa baixa

Exemplo: select lower(last_name) from employee

lpad

DECLARE EXTERNAL FUNCTION lpadCSTRING(255), INTEGER, CSTRING(1)RETURNS CSTRING(255) FREE_ITENTRY_POINT ‘IB_UDF_lpad’ MODULE_NAME

‘ib_udf’;

Utilização: Recebe como parâmetros uma string de até 255caracteres, um inteiro e um caracter.

Exemplo: select lpad(first_name,20,’ ‘) from employeeEntendendo: No exemplo acima, insere espaços em branco à

esquerda do campo fisrt_name até obter um total de 20caracteres (contando os espaços em branco).

ltrim

DECLARE EXTERNAL FUNCTION ltrimCSTRING(255)RETURNS CSTRING(255) FREE_ITENTRY_POINT ‘IB_UDF_ltrim’ MODULE_NAME

‘ib_udf’;

Utilização: Recebe como parâmetro uma string de até 255caracteres e tem como retorno esta mesma string com remoçãodos espaços em branco da esquerda.

Exemplo: select ltrim(first_name) from employee

mod

DECLARE EXTERNAL FUNCTION modINTEGER, INTEGERRETURNS DOUBLE PRECISION BY VALUEENTRY_POINT ‘IB_UDF_mod’ MODULE_NAME

‘ib_udf’;

Utilização: Recebe como parâmetros de entrada dois valoresinteiros e como retorno o resto da divisão do primeiro parâmetropelo segundo.

Exemplo: select mod(campo1,campo2) from tabela

substr

DECLARE EXTERNAL FUNCTION substrCSTRING(255), SMALLINT, SMALLINTRETURNS CSTRING(255) FREE_ITENTRY_POINT ‘IB_UDF_substr’ MODULE_NAME

‘ib_udf’;

7

FireBird

Utilização: Recebe como parâmetro uma string de até 255caracteres e dois valores inteiros (o primeiro indica a posição e osegundo a quantidade de caracteres). Útil para pegar pedaços destrings.

Exemplo: select substr(last_name,1,3) from employee.Percebam que este select irá trazer como resultset apenas os trêsprimeiros caracteres do campo last_name.

strlen

DECLARE EXTERNAL FUNCTION strlenCSTRING(32767)RETURNS INTEGER BY VALUEENTRY_POINT ‘IB_UDF_strlen’ MODULE_NAME

‘ib_udf’;

Utilização: Recebe como parâmetro uma string e tem comoretorno o tamnho desta string

Exemplo: select strlen(last_name) from employee

Neste momento iremos verificar algumas UDFs interessantesvindas do arquivo fbudf.dll. Faça o mesmo procedimento citadoacima. Abra este arquivo e perceba a quantidade imensa de UDFspara serem utilizadas.

dow

declare external function dowtimestamp,varchar(15) returns parameter 2entry_point ‘DOW’ module_name ‘fbudf’;

Utilização: Recebe como parâmetro um campo tipo timestamp eretorna o dia da semana correspondente

Exemplo: select dow(’05.07') from employee ou select dow(’05.07.2007') from employee ou select dow(’05.07.2007 10:25:32') from employee

addDay

declare external function addDaytimestamp, intreturns timestampentry_point ‘addDay’ module_name ‘fbudf’;

Utilização: Recebe como parâmetro um campo tipo timestamp eum inteiro. Ela serve para adicionar dias a data informada.

Exemplo: select addday(’06.07.2007', 20) from employee

Obs: Esta biblioteca de Funções possui várias UDFsrelacionadas às datas e horas. Todas seguem a mesma linhade raciocínio, veja abaixo:

AddWeek – Adiciona Semanas a uma data.AddMonth – Adiciona meses a uma data.Addyear – Adiciona ano a uma data.AddMillisecond – Adiciona milisegundos a uma hora.AddSecond – Adiciona segundos a uma hora.AddMinute – Adiciona minutos a uma hora.AddHour – Adiciona horas a uma hora.

sright

declare external function srightvarchar(100) by descriptor, smallint,varchar(100) by descriptor returnsparameter 3entry_point ‘right’ module_name ‘fbudf’;

Utilização: Recebe como parâmetro um campo do tipovarchar(100) e um inteiro. O segundo parâmetro determinaquantos caracteres são mostrados da direita para a esquerdado campo informado no primeiro parâmetro.

Exemplo: select sright(first_name, 5) from employee

round

declare external function Roundint by descriptor, int by descriptorreturns parameter 2entry_point ‘fbround’ module_name ‘fbudf’;

Utilização: Recebe como parâmetro um valor a serarredondado. Ela serve para arredondar valores.

Exemplo: select round(25.99) from tabela

dPower

declare external function dPowerdouble precision by descriptor, doubleprecision by descriptor,double precision by descriptorreturns parameter 3entry_point ‘power’ module_name ‘fbudf’;

Utilização: Recebe como parâmetro dois valores que podemser do tipo double precision, sendo o primeiro o número a serelevado pelo segundo. É uma UDF de exponenciação.

Exemplo: select dPower(2.36, 2.58) from tabela

8

FireBird

Utilizando UDFs de terceiros

Depois de conhecermos algumas UDFs vindas dopróprio Firebird agora iremos adicionar algumas de terceiros nonosso Banco de Dados. Iremos utilizar uma chamadaFreeUdfLib do seguinte autor Greg Deatz e alterada por CláudioValderrama. Baixe esta biblioteca através do seguinte link http://www.ibphoenix.com/downloads/freeudflib.zip . Descompacte nodiretório de sua escolha e copie os seguintes arquivos: ext_funcs eFreeUDFLib.dll para o diretório C:\Arquivos deprogramas\Firebird\Firebird_x\UDF.

Abra o Arquivo ext_funcs e observem a quantidadeenorme de UDFs. Encontraremos tratando de campos do tipoBlob, Data e Hora, Funções Matemáticas entre outras. Abaixomostrarei algumas que considero mais interessantes.

f_blobsize

declare external function f_BlobSizeblobreturns integer by valueentry_point ‘BlobSize’ module_name‘FreeUDFLib.dll’;

Utilização: Recebe como parâmetro um valor do tipo blob eretorna um inteiro.Como o próprio nome já diz, tem como retornoo tamanho do campo Blob.

Exemplo: select f_blobsize(job_requirement) from job

f_strblob

declare external function f_StrBlobcstring(254),blobreturns parameter 2entry_point ‘StrBlob’ module_name‘FreeUDFLib.dll’;

Utilização: Recebe como parâmetro uma string e tem comoretorno um campo do tipo Blob.

Exemplo: select f_strblob(job_country) from job

f_AddMonth

declare external function f_AddMonthdate,integerreturnsdate /* free_it */entry_point ‘AddMonth’ module_name

‘FreeUDFLib.dll’;

Utilização: Recebe como parâmetros: um campo do tipo Date eum valor inteiro. Adiciona meses à data informada.

Exemplo: select F_addmonth(’10.05.2007’,5) from tabela

Importante: A Biblioteca fbudf também contém UDFs paratrabalhar com Datas, mas observem que o tipo de campo étimestamp. Abaixo verifiquem a quantidade de funçõesinteressantes sobre datas, estarei dando uma breve explicaçãosobre elas.

f_year: Retorna o ano de uma data.f_month: Retorna o mês de uma data.f_AddYear: Adiciona anos a uma data.f_AgeInDays: Verifica a quantidade de dias no intervalo

entre duas datas.f_CdowShort: retorna o dia da semana.f_CmonthLong: retorna o mês da data informada.f_dayofmonth: retorna o dia do mês da data informada.

f_lrTrim

declare external function f_lrTrimcstring(254)returnscstring(254) /* free_it */entry_point ‘lrTrim’ module_name

‘FreeUDFLib.dll’;

Utilização: Recebe e retorna como parâmetro uma string.Sua função é de remover espações em branco localizado naesquerda e na direita de uma string.

Exemplo: Select f_lrTrim(‘ The Club - O Maior clube deprogramadores ‘) from tabela

f_propercase

declare external function f_ProperCasecstring(254)

returnscstring(254) /* free_it */entry_point ‘ProperCase’ module_name

‘FreeUDFLib.dll’;

Utilização: Recebe e retorna como parâmetro uma string. Oretorno desta UDF será a primeira letra em maiúscula e o restoem minúscula.

Exemplo: select f_propercase(‘thiago’) from tabela

9

FireBird

f_ibpassword

declare external function f_IBPasswordcstring(32)returnscstring(32) /* free_it */entry_point ‘IBPassword’ module_name‘FreeUDFLib.dll’;

Utilização: Recebe como parâmetro uma string e retorna estastring criptografada.

Exemplo: Select f_IBPassword(job_country) from job

Além desta biblioteca de Funções existem outras(também ditas open-source) que poderão ser úteis para ossenhores. Eu particularmente recomendo uma chamada tbudf(Tecnobyte UDF para Firebird) do autor Daniel PereiraGuimarães que poderá ser baixada no seguinte link http://www.tecnobyte.com.br/tbudf2_2.zip. Esta biblioteca além de sertão boa quanto a FreeUDFLib possui uma ótima documentaçãoem português. Para utilizá-la siga os mesmos passos ditosanteriormente.

Criando uma UDF

Quando iremos criar uma UDF nãopodemos esquecer uma regra básica, érecomendável ser uma função simples erápida. Significa que uma função quemanipula strings, realiza cálculosmatemáticos, manipula datas como nosexemplos citados acima são ótimascandidatas a virarem uma UDF.

A ferramenta para criarmos nossaUDF será o delphi 7. Abra o Delphi, váem File/New/Other. Na aba New escolhaDLL Wizard, veja figura 03.

Logo em seguida clique em ok.Aparecerá os seguintes códigos.

library Project1;

{ Important note about DLLmemory management: ShareMemmust be the first unit in yourlibrary’s USES clause AND Figura 03. Criando uma UDF.

your project’s (select Project-View Source) USES clause if yourDLL exports any procedures or functions that pass strings as parametersor function results. This applies to all strings passed to and fromyour DLL—even those that are nested in records and classes. ShareMemis the interface unit to the BORLNDMM.DLL shared memory manager,which must be deployed along with your DLL. To avoid using BORLNDMM.DLL,pass string information using PChar or ShortString parameters. }

uses SysUtils, Classes;

{$R *.res}

beginend.

10

FireBird

Logo após Library iremos colocar o nome da Biblioteca.Defina como quiser, neste caso específico iremos definir comoTHECLUB. Em uses iremos utilizar apenas a unit chamadaSysUtils e por final remova a cláusula {$R *.res} que não iremosutilizar.Veja abaixo como está ficando nosso código:

library THECLUB;

uses SysUtils;

beginend.

Iremos construir uma UDF simples, receberá uma stringcomo parâmetro e retornará esta mesma string com espaço embranco entre seus caracateres. Veja abaixo nossa função:

Function ESPACO(var1:pchar): pchar;cdecl; export;var i:integer; var2, var3: string;begin for i:=1 to Length(var1) do begin var2 := copy(var1,i,1) + ‘ ‘; var3 := var3 + var2; end; result := pchar(var3);end;

Fica uma dúvida, porque utilizar pchar ao invés de string?Para quem não sabe pchar é um ponteiro para caracter. Ponteiroé uma variável que contém um endereço de memória. Esteendereço é a posição de outra variável ou de um determinadodado na memória. Tratando-se de UDFs (criação de DLLspropriamente ditas) não seria recomendável a utilização destrings como variáveis (seja de retorno ou de entrada) e sim dotipo pchar ou shortstring.

Outra dúvida, o que significa cdecl e export?

Cdecl: Significa o tipo de chamada, determina a ordem na

qual os parâmetros são passados para a rotina. Ele passa os

parâmetros da direita para a esquerda. Na forma cdecl o

chamador é responsável por remover da pilha os parâmetros de

retorno das funções.

Export: indica que a função poderá ser chamada por outros

aplicativos.(No nosso caso o Firebird)

Mas não iremos nos aprofundar muito neste assunto, paraquem se interessar veja nossa matéria chamada Trabalhandocom Procedures e Funções encontrada no seguinte link http://www.theclub.com.br/revista/trab1203.aspx do mês de Dezembrode 2003.

Veja abaixo como ficou a UDF criada pelo Delphi.

library THECLUB;

uses SysUtils;

Function ESPACO(var1:pchar): pchar; cdecl;export;var i:integer; var2, var3: string;begin for i:=1 to Length(var1) do begin var2 := copy(var1,i,1) + ‘ ‘; var3 := var3 + var2; end; result := pchar(var3);end;

exports ESPACO;

beginend.

Após construirmos nossa UDF iremos salvá-la em File/SaveAll em seguida compilá-la. Fiquem atentos, não podemosexecutar uma DLL pelo Delphi, através do RUN do Menu Run,pois não se trata de uma aplicação. Clique em Project/ CompileTHECLUB.

Percebam que ao compilar nosso projeto será criado umarquivo chamado THECLUB.dll, ou seja, estamos terminando oprocesso de criação de nossa UDF, basta apenas declará-la nonosso Banco de Dados.

Copie o arquivo THECLUB.dll para a seguinte diretórioC:\Arquivos de programas\Firebird\Firebird_x\UDF (que é odiretório onde ficam armazenadas as UDFs do Firebird e as deterceiros). Em seguida abra o Ibexpert para declararmos nossaUDF. Observe abaixo como fica:

11

FireBird

DECLARE EXTERNALFUNCTION UDF_ESPACOCSTRING(32)RETURNS CSTRING(32)ENTRY_POINT ‘ESPACO’MODULE_NAME ‘TESTE.dll’

DECLARE EXTERNALFUNCTION UDF_ESPACO: coloqueo nome da UDF.

ENTRY_POINT ‘ESPACO’MODULE_NAME ‘TESTE.dll’:ESPACO seria o nome da UDFcriada no Delphi e TESTE.dll o nomeda biblioteca.

Clique em Execute e logo apósCommit Transaction, veja na figura04 a nossa UDF criada com sucesso

no banco de dados.

Figura 04. UDF criada no Banco de Dados.

Figura 05. Resultado de nossa instrução SQL.

Utilizando nossa UDF chamada udf_espaco:

select udf_espaco(last_name) as LAST_NAME from employee

Veja o resultado (Figura 05)

Conclusão

Vimos neste artigo como se trabalhar comUDFs, desde sua definição até a criação de uma peloDelphi. Espero que tenha ajudado e gostado damatéria.

Um forte abraço e até o mês que vem.

12

Silverlight

Em 2001 durante sua palestra de abertura no PDC, oprincipal evento para desenvolvedores da Microsoft, Bill Gatescitou a reunificação das interfaces com usuário como uma dasprincipais razões por trás do desenvolvimento da plataforma.NET, depois da cisão causada pelo aparecimento da Web.

Efetivamente, a Web oferece enormes vantagens de alcance,distribuição e atualização, mas à custa de uma experiência com ousuário pobre. Já os aplicativos gráficos tinham boa interfacecom usuário, mas traziam problemas de distribuição eatualização. A idéia de unir as vantagens das duas plataformasna tecnologia então batizada de “SmartClient” sempre mepareceu uma ótima idéia. Não só eu, mas também o GartnerGroup ficou entusiasmado com a novidade e previu que em 2006a maioria dos novos aplicativos na plataforma Microsoft seria“SmartClient” e não Web. Lógico que o apoio do Bill Gatestornaria a tecnologia imbatível!

Infelizmente, isso não aconteceu.A maior parte dos novos aplicativos desenvolvidos hoje é feita

para a Web. “Para a Web” quer dizer que o aplicativo roda emum servidor e troca páginas HTML com um navegador como oInternet Explorer ou Mozilla. O aplicativo em si pode ser “mais oumenos burro”, dependendo da quantidade de scripts de cliente(“JavaScript”) que se coloca na página.

Caso a página não contenha nenhuma linha de script decliente, ela é HTML “pura” e todo o código é executado noservidor, mesmo para as coisas mais simples como validar se umcampo foi preenchido. Hoje em dia é muito difícil encontrar umapágina assim, até porque ferramentas como o ASP.NET geramautomaticamente scripts de cliente para coisas relativamentesimples, como validação de campos texto e processamentoimediato (“postback”) de ações como seleção em “listboxes” ouclique em links.

Algumas coisas mais sofisticadas, como menus de navegação,estão disponíveis gratuitamente na Web e também não dão muitotrabalho para incluir nos aplicativos, até porque o script não écompilado e é fácil conseguir “inspiração” em outros sites.

Até aqui, tudo bem. Infelizmente, os “chatos” dos usuáriosestão acostumados com um padrão de interface muito maisinterativa e agradável, que já é oferecida atualmente pelosaplicativos GUI escritos com ferramentas tradicionais comoVisual Basic ou Delphi. Em alguns casos, é até possível imitarestes mesmos recursos como barras de ferramentas e caixas de

SilverlightSilverlightSilverlightSilverlightSilverlightPor Mauro Sant’Anna diálogo através do uso de scripts de cliente desenvolvidos

especialmente para os aplicativos.As coisas ficam complicadas quando desejamos fazer coisas

mais complexas com os scripts de cliente, especialmenterelacionadas à lógica exclusiva dos aplicativos. A programação descripts de cliente é, em geral, muito mais complexa e menosprodutiva que a programação de aplicativos comuns em VisualBasic. Esta perda de produtividade é enorme, usualmente nacasa de uma ordem de magnitude. Na verdade, uma página queenvia scripts para o navegador é essencialmente um gerador deaplicativos e desenvolver geradores de aplicativos não é fácil.

Recentemente a tecnologia AJAX, exemplificada naplataforma Microsoft pelo Atlas, facilitou a inclusão de scriptsnas páginas, sem que o programador precise se preocupar muitocom isso. Mesmo assim, a interface Web não tem a mesmainteratividade da interface Windows.

A plataforma .NET trouxe outra alternativa: os aplicativosSmartClient, capazes de ser distribuídos pela Web masmantendo a interface Windows e com programação naslinguagens tradicionais do .NET como VB.NET ou C#.

No início, por volta de 2002, SmartClient significava colocarem páginas Web controles .NET e tags “href” referenciandoexecutáveis. Esta tecnologia evoluiu para o “ClickOnce” no .NET2.0 em 2005. Infelizmente nenhuma das duas teve granderepercussão. Elas sofreram dois problemas, um técnico e outro demarketing.

Tecnicamente, o modelo de segurança chamado “CAS” (CodeAccess Security) é difícil de entender e implantar. Do ponto devista de divulgação, ninguém de fora do grupo que cuidava daprópria tecnologia jamais deu a menor bola para o SmartClient.Por exemplo, a Microsoft jamais criou um aplicativo de uso amplopara funcionar como demonstração da nova tecnologia. Eumesmo sugeri para várias pessoas da Microsoft idéias deaplicativos que mostrassem as vantagens do SmartClient, comopor exemplo um cliente alternativo para o HotMail ou então umamelhor interface de busca no site MSDN. Onde estava Bill Gatespara fazer essas coisas acontecerem? Será que ele não seimportava mais? Teríamos que nos contentar com o Flash daAdobe ou com o “Java Script” turbinado que a Google chamou de“AJAX”?

Em 2005 Bill Gates anunciou sua aposentadoria e em 2006nomeou Ray Ozzie como seu sucessor. Ozzie seria a pessoaresponsável pela “visão tecnológica” em uma empresa cada vezmais dominada por executivos de vendas extremamentepreocupados com os números de curto prazo.

13

Silverlight

Eu já estava convencido que teria que me conformar comuma mistura de AJAX e Flash quando Ray Ozzie anunciou combandas e fanfarras no evento “MIX” o SilverLight 1.1, uma novaimplementação da tecnologia SmartClient sem seus tradicionaisproblemas.

Em termos de marketing, o Silverlight teve uma divulgaçãoexcelente, incluindo um bom tempo nas principais home pagesdos sites Microsoft. Em todo mundoo Silverlight é consideradoalgo “quente”.

Do ponto de vista técnico ele também não decepciona. O betaque está no ar desde fevereiro e corresponde ao Silverlight 1.0permite a criação de interfaces com usuário mais bonitas atravésdo uso do WPF (Windows Presentation Foundation) misturadocom JavaScript. Mas é o alfa da versão 1.1, colocado no ar depoisdo MIX, que traz a grande novidade: uma versão “light”do .NETFramework. Esta versão é pequena, estará disponível paraplataformas não-Microsoft como MacOS e traz um modelo desegurança bastante simplificado.

Ou seja: o SilverLight 1.1 promete entregar as promessas doSmartClient, unindo a distribuição e alcance da Web com umainterface com usuário bem mais rica e semelhante aos aplicativos“GUI”.

Já surgiram até extensões para Silverlight que emulam ospróprios controles WinForms. Veja em http://www.goasoft.com/

Sobre o autorMauro Sant’Anna nunca trabalhou na Microsoft, masconhece bastante a empresa, já que é MVP e “RegionalDirector of the Year”. Ele coordena os cursos na M. A. S.Informática (www.mas.com.br) e bloga em Português emhttp://blogs.vstsrocks.com.br e em inglês em http://maurosjungle.spaces.live.com .

products/default.aspxÉ claro que “o diabo está nos detalhes”. Embora seja uma

versão simplificada, o Silverlight deve ser capaz de atender àsmaiorias das necessidades de negócio de seus usuários. A versãoatual tem limitações, por exemplo, falta um mecanismodeclarativo de “controles vinculados”, o que facilita bastante odesenvolvimento de aplicativos de negócios que lidam com bancosde dados. Mas ainda é cedo para emitir um parecer completo.Tecnicamente não acredito ser difícil para a Microsoft produzirum produto ao mesmo tempo simples e poderoso em um curtoespaço de tempo.

O mais importante é que com o apoio do Ray Ozzie, o novo“homem de visão” da Microsoft, o Silverlight deve ter um futurobrilhante à sua frente.

14

Acessando o Firebird com oAcessando o Firebird com oAcessando o Firebird com oAcessando o Firebird com oAcessando o Firebird com oDriver Dbexpress específico (UIB)Driver Dbexpress específico (UIB)Driver Dbexpress específico (UIB)Driver Dbexpress específico (UIB)Driver Dbexpress específico (UIB)

Firebird

Neste artigo estarei demonstrando como acessar o Firebirdjunto com seu Driver gratuito específico produzido pelaUIB(Unified Interbase).Na realidade com o passar do tempo cadavez mais o Firebird se diferencia do Interbase. E por que nãoutilizar um próprio driver para o Firebird? Nesta matéria estareiexplicando como utilizar este driver e montar um projeto emDelphi 7.

Estaremos disponibilizando a DLL dbexpUIBfire15.dll nofinal deste artigo para o Download.

Copie a DLL dbexpUIBfire15.dll para a pastaC:\Arquivos de programas\Borland\Delphi7\Bin do Delphi.Após copiar a DLL abra o arquivo dbxdrivers.ini encontrado napasta “C:\Arquivos de programas\Arquivos comuns\BorlandShared\DBExpress” e iremos realizar algumas alterações nestearquivo. Confira abaixo:

Observação Importante: Para realizar estas alterações feche oDelphi.

[Installed Drivers]...

Após esta linha adicione o código abaixo:

UIB FireBird15=1

Em seguida:

[UIB FireBird15]GetDriverFunc=getSQLDriverINTERBASELibraryName=dbexpUIBfire15.dllVendorLib=fbclient.dllBlobSize=-1CommitRetain=FalseDatabase=database.fdbErrorResourceFile=LocaleCode=0000Password=masterkeyRoleName=RoleNameServerCharSet=

Por Thiago Cavalheiro Montebugnoli SQLDialect=3Interbase TransIsolation=ReadCommitedUser_Name=SYSDBAWaitOnLocks=True

Em seguida clique em salvar e feche este arquivo.Coloque aDLL dbexpUIBfire15.dll na pasta C:\Windows\System32.

Utilizando o UIB

Iremos montar um exemplo bem simples utilizando odelphi 7 com o Firebird 1.54. Abaixo a instrução SQL para criarnossa tabela:

CREATE TABLE TBCLIENTE ( COD_CLIENTE INTEGER NOT NULL, NOME_CLIENTE VARCHAR(40), CIDADE VARCHAR(40));

ALTER TABLE TBCLIENTE ADD CONSTRAINTPK_TBCLIENTE PRIMARY KEY (COD_CLIENTE);

Em seguida abra o Delphi 7, clicando em File/NewApplication. Coloque no formulário um Sqlconnection e emseguida iremos utilizar nosso Driver criado anteriormente.Veja aFigura 01 abaixo:

Driver Name: UIB Firebird15Connection Name: THECLUB

Figura 01: Criando uma conexão.

15

Firebird

Figura 02: Propriedades da conexão.

Percebam na Figura 02 as configurações de nossa conexão. Na chave DriverName o valor UIB Firebird15.

Neste momento iremos criar umcadastro simples, como se estivéssemosutilizando o Driver do Interbase.Coloque no formulário os seguintescomponentes:

Sqldataset , DatasetProvider,ClientDataset, Datasource,Dbgrid,Dbnavigator e finalmente um Button.Configure os componentesnormalmente ligando suas respectivaspropriedades. Veja a figura 03 ao lado:

Configure apenas o button com oseguinte código:

procedureTForm1.Button1Click(Sender:TObject);begin ClientDataSet1.ApplyUpdates(0);end; Figura 03: Cadastro de Cliente.

16

Firebird

Figura 04: Layout Final.

Sobre o autorThiago Cavalheiro Montebugnoli é tecnólogo, formado pelaFaculdade de Tecnologia de Botucatu – SP (FATEC) econsultor técnico do The Club.

Pronto, Os senhores estão utilizando o Firebird com seupróprio driver de conexão sem muito esforço. Apenas algumasconfigurações utilizando a DLL dbexpUIBfire15.dll.

Importante: lembre-se de enviar esta nova DLL para ocliente. Esta DLL pode ser armazenada tanto na mesma pasta doexecutável quanto na C:\Windows\System32.

Conclusão

Como já tinha mencionado no início deste artigo, cada vez

mais o Firebird se diferencia do Interbase. A utilização destedriver específico junto com sua DLL Fbclient garante uma

melhor compatibilidade com o Delphi seguida de uma melhor

performance.

Seção PérolasAlguem dai me indicou um livro, outro dia. Agora eu posso compra-lo más infelizmente não me lembromais qual o livro.Se descobrir quem foi, fico grato;

...tem como um texto que está em um dbloockup ser copiado para um edit, afim de que o usuariofaca apenas o complemento.Ex. Anel... (....Rod. Elo coraçao), está confuso? Até mais...

17

A IBPHOENIX lança o Firebird 2.1 (versão beta). Os

apaixonados pelo Firebird irão gostar muito desta versão para

teste, que vem cheio de novas idéias e tecnologias. Nós do The

Club não poderíamos ficar de fora. O Firebird é um excelente

Banco de Dados e usados por muitos usuários pela sua

praticidade e facilidade de uso. A nova versão do FireBird

2.1(beta) está disponível nesse link: http://

umn.dl.sourceforge.net/sourceforge/firebird/Firebird-2.1.0.15999-

0_win32.zip

Esta matéria vem com o objetivo de mostrar os novos

recursos dessa versão com alguns exemplos práticos. Chega de

enrolação e vamos ao que realmente interessa. Para poder

Firebird 2.1 (Beta) Firebird 2.1 (Beta) Firebird 2.1 (Beta) Firebird 2.1 (Beta) Firebird 2.1 (Beta) - Parte I- Parte I- Parte I- Parte I- Parte I

trabalhar com o Banco de Dados estou usando como ferramenta

o IBExpert para manipular os dados.

Criando e Registrando Banco de Dados

O primeiro ponto a ser analisado é com relação a criar e

registrar o BD. Agora todos os bancos criados devem usar a nova

DLL fbclient.dll, que está localizada na pasta seguinte pasta:

C:\Arquivos de programas\Firebird\Firebird_2_1\bin

Veja na Figura 01 como ficará a criação e conexão do Banco

de Dados, após criar o banco de dados é necessário registrar o

importante dessa tela é definir a versão do Firebird a ser usado

no nosso caso é Firebird 2.1 (veja na Figura 02).

Figura 01 - Criando o Banco de Dados

Firebird

18

Firebird

Novidades do Firebird 2.1 (Beta)

Mesmo sendo uma versão para teste a IBPhoenix traz com

essa nova versão algumas novidades muito interessantes como:

· Database Triggers

· Mudanças nas VIEWS

· Cláusula RETURNING

· Função List( )

· Novos JOINS

Essas serão algumas das muitas novidades abordadas nessa

primeira matéria sobre o Firebird 2.1.

DATABASE TRIGGERS

Como sabemos triggers são os chamados “gatilhos” e são

comandos localizados no banco de dados que podem ser acionados

em eventos UPDATE, INSERT, DELETE. Agora com essa

versão é possível desenvolver triggers para eventos de transação

e conexões ocorridas. Segue a sintaxe da criação da Trigger:

Figura 02 – Registrando o Banco de Dados

{CREATE | RECREATE | CREATE OR ALTER} TRIGGER <name> [ACTIVE | INACTIVE] ON <event> [POSITION <n>] AS BEGIN ... END

<event> ::= CONNECT | DISCONNECT | TRANSACTION START | TRANSACTION COMMIT | TRANSACTION ROLLBACK

Para entendermos melhor como funciona esse tipo de Triggervejamos o seguinte exemplo: Caso deseje criar um LOG no bancode dados usando uma tabela no BD para futuras consultas é

19

Firebird

possível criar uma Trigger que quando conectar no banco dedados ele armazene o usuário e a hora que conectou. Vamos veresse exemplo na prática.

Eu criei uma tabela no BD chamada LOG com a seguinteestrutura:

CREATE TABLE LOG ( USUARIO VARCHAR(20), DATA DATE, HORA TIME );

Depois de criado a tabela vamos criar a Trigger segue oscomandos abaixo:

CREATE TRIGGER REG_USERACTIVE ON CONNECT POSITION 0ASbegin Insert into log values( USER, current_date,current_time );end

Para quem está usando o IBExpert é importante observar natela de criação de Trigger uma opção que aparecerá na partesuperior da tela onde você escolhe se a Trigger é direcionada paratabelas ou databases, veja a Figura 03. Esta Trigger estáconfigurada para ser executada no evento CONNECT, ou seja,quando o usuário conectar é executado. Mas existem outroseventos como DISCONNECT, TRANSACTION START,TRANSACTION COMMIT, TRANSACTION ROLLBACK.

No próprio IBExpert é possível testar a Trigger, basta clicarcom o botão direito do mouse em cima do banco de dados eescolher a opção RECONNECT. Veja como ficou os dados

registrados na tabela LOG (Figura 04). Esse é um exemplosimples de como trabalhar com este novo evento. Realmente estanova possibilidade de trabalhar com as Triggers irá alegrarmuitos programadores. Muitos até mesmo eu procurava algumaforma de obter este evento e realizar alguns testes quando seconectar ao banco de dados.

Figura 04 – Dados da tabela LOG

Mudanças nas VIEWS

Um grande problema que nós encontrávamos era não poderusar um Alias nas colunas quando trabalhávamos com visões.Pois agora é possível! Veja como fica a sintaxe:

CREATE VIEW V_TEST AS SELECT * FROM LOG;

Cláusula RETURNING

Em Stored Procedure para retornar um valor usamos oRETURNS. Agora nesta versão é possível usar a cláusulaRETURNING nos comandos DELETE, UPDATE ou INSERT. OReturning não deve ser usado para retorno de vários registros,pois ele somente devolve um único registro. Veja a sintaxe:

Figura 03 – Tela de criação de Trigger

INSERT INTO ... VALUES (...) [RETURNING <column_list> [INTO<variable_list>]]INSERT INTO ... SELECT ... [RETURNING <column_list> [INTO<variable_list>]]UPDATE OR INSERT INTO ... VALUES (...) ... [RETURNING <column_list> [INTO<variable_list>]]UPDATE ... [RETURNING <column_list> [INTO<variable_list>]]DELETE FROM ... [RETURNING <column_list> [INTO<variable_list>]]

Usando a tabela do exemplo anterior executei a seguinteinstrução SQL:

INSERT INTO LOG values(user,current_date,current_time) RETURNING userCom esse comando ele insere o registro eretorna a coluna desejada como parâmetro.Outros exemplos de como usar essa cláusula:INSERT INTO T1 (F1, F2) VALUES (:F1, :F2) RETURNING F1, F2 INTO :V1, :V2;INSERT INTO T2 (F1, F2) VALUES (1, 2) RETURNING ID INTO :PK;DELETE FROM T1 WHERE F1 = 1 RETURNING F2;UPDATE T1 SET F2 = F2 * 10 RETURNING OLD.F2, NEW.F2;

FUNÇÃO LIST()

Esta função retorna uma string, resultado da união devalores não nulos de um grupo. Retorna o ZERO se houver valornulo (NULL).

Veja a sintaxe do comando:

LIST ‘(‘ [ {ALL | DISTINCT} ] <valueexpression> [‘,’ <delimiter value> ] ‘)’

<delimiter value> ::= { <string literal> | <parameter> |<variable> }

Esta função traz algumas regras:1. Se não forem usadas as cláusulas ALL ou DISTINCT, o

ALL será usado como padrão.2. Se não for usado um delimitador <delimiter value>, o

padrão será usar o “;” para separar os valores concatenados.Temos que salientar algumas observações com relação ao

uso desta função. Todos os valores1. Valores numéricos e Data/Hora que são implícitas serão

convertida em strings.2. Os valores dos resultados são do tipo BLOB.3. É possível ordenar os valores com o Group.Vejam alguns exemplos usando esta função com a tabela que

estamos trabalhando nesta matéria, os resultados são muitosinteressantes:

Examples:

/* A */ SELECT LIST(USUARIO, ‘;’) FROM LOG

/* B */ SELECT USUARIO, LIST(USUARIO) FROM LOG GROUP BY USUARIO

NOVOS JOINS

Com a finalidade de facilitar o nosso dia-da a IBPHOENIXadicionou dois novos JOINS nessa versão beta. São eles: OCOLUNA NOMEADA (NAMED COLUMNS) e o NATURALjoin. Primeiramente vamos ver a sintaxes dos dois joins:

<named columns join> ::= <table reference> <join type> JOIN <tablereference> USING ( <column list> )

<natural join> ::= <table reference> NATURAL <join type> JOIN<table primary>

Agora vamos ver as regras do primeiro join NAMED

Firebird

21

Firebird

COLUMNS:· Todas as colunas da seção <column list> deverão

existir nas duas tabelas.· O equi-join (<left table>.<column> = <right

table>.<column>) é criado automaticamente para todas ascolunas.

Regras do segundo join, NATURAL JOIN:· A “named columns join” são criadas automaticamente

com todas as colunas comuns às tabelas da esquerda e direita.· Se não tiver nenhuma coluna em comum, um CROSS

JOIN é criado.Exemplos de como trabalhar com esses JOINS:

/* 1 */select * from employee join department using (dept_no);

/* 2 */select * from employee_project natural join employee natural join project;

Sobre o autorVitor Scarso é consultor técnico do The Club, trabalha comprogramação há 5 anos e é formado em Técnico deInformática.

CONCLUSÃO

Com certeza a IBPhoenix está fazendo grandes avanços comesse produto incrível FIREBIRD. Mesmo sendo uma versão(beta) já possibilita uma visão de como será as futuras versões doFIREBIRD. Nesta primeira parte sobre a abordagem das novastecnologias dou o destaque ao DATABASE TRIGGERs que iráaumentar em muito a produtividade dos programadores. Como éuma versão beta, está sujeito a muitos erros mas como o própriosite da IBPhoenix recomenda testarmos ao máximo esta versão,é o que iremos faze. Caso deseje fazer algum comentário sobre aversão ou falar sobre algum erro entre em contato com aIBPhoenix pelo site WWW.IBPHOENIX.COM.BR. Aguardem apróxima matéria que traremos muito mais novidades sobre oFIREBIRD 2.1(beta). Um abraço a todos! Até a próxima!

22

Perguntas & Respostas

Pergunta: Tenho como identificar qual ou quais máquinasda rede, nome ou ip, estãoacessando o sistema no momento e colocar o resultado em umalista ?

Resposta: Uma das formas que o Senhor pode desenvolveré fazer um pequeno arquivogravando os ips das máquinas quando acessam o banco, ou atémesmo gravando em uma tabela do banco. A função para pegaros Ips da máquina segue abaixo:

\\Declare a unit uses WinSock;

{$R *.dfm}

function GetIP:string; var WSAData: TWSAData; HostEnt: PHostEnt; Name:string; begin { no error checking...} WSAStartup(2, WSAData); SetLength(Name, 255); Gethostname(PChar(Name), 255); SetLength(Name, StrLen(PChar(Name))); HostEnt := gethostbyname(PChar(Name)); with HostEnt^ do Result := Format(‘%d.%d.%d.%d’,[ Byte(h_addr^[0]), Byte(h_addr^[1]), Byte(h_addr^[2]), Byte(h_addr^[3])]); WSACleanup; end;

Esta função retorna uma string. Com essa string o sistemapoderá gravar em

um arquivo/tabela quem está acessando, e quando sair dosistema basta retiraro ip do arquivo/tabela.

Dúvida enviada por Donizeti de P.Ribeiro, Anápolis - GO

Pergunta: Estou desenvolvendo um sistema e em umdeterminado campo do tipo INTEGER, eu preciso que o usuáriodigite no máximo 4 números ‘9999’, como faço para validar emum Dbgrid?

Resposta: O Senhor poderia adicionar uma máscara nocampo. Adicione o campo no componente (Exemplo: Table/Query)e na propriedade do campo EditMask, coloque o valor ‘9;0’.

Dúvida enviada por Joao Rodrigues dos Santos, Jaguariuna– SP.

Pergunta: Estou tentando utilizar o seguinte script:

‘SELECT CODIGO,NOME FROM CLIENTE UNION ALLSELECT CODIGO,NOME FROM FORNECE ORDER BYNOME ‘

Porém dá o erro: “Invalid command Invalid ORDER BYclause” Como poderei solucionar ?

Resposta: Analisei seu problema, pelo que vejo gostaria detrazer o código,nome do cliente e código,nome do fornecedor. Aselect ficaria assim:

select cliente.codigo, cliente.nome, fornecedor.codigo, fornecedor.nomefrom cliente,fornecedorORDER BY fornecedor.NOME,fornecedor.codigo

23

Perguntas & Respostas

Essa select traz ordenada pelo nome,codigo do fornecedor sedesejar fazer ordenando pelo cliente use a seguinte cláusula:

ORDER BY cliente.NOME,cliente.codigo

Dúvida enviada por Israel Vítor Vicente, Três Pontas – MG.

Pergunta: Gostaria de saber se vocês conhecem algumaferramenta pronta para fazermanutenção de banco de dados Firebird, tipo ibExpert, que possafuncionarvia WEB, ou seja,havendo uma base acessível em um servidorremoto, eu consiga modificá-la sem a necessidade de usarterminal server,vnc ou semelhante?

Resposta: No próprio Ibexpert é possível acessar umservidor remoto desde que tenha um IP fixo. Na conexão com oIbexpert coloque como Server: Remote, em ServerName o IP do servidor e em DataBase o caminho da base dedados no servidor.

Dúvida enviada por: Ricardo Ferreira da Silva, Santo André– SP.

Pergunta: Preciso de uma instrução via SQL que seuresultado do select seja retornardo num arquivo TXT, observem ainstrução abaixo feita no clipper:

USE CLIENTES.DBF NEWUSE CLIENTES.DBF NEWUSE CLIENTES.DBF NEWUSE CLIENTES.DBF NEWUSE CLIENTES.DBF NEWCOPY TO TESTE FOR ESTCLI = ‘PE’ SDFCOPY TO TESTE FOR ESTCLI = ‘PE’ SDFCOPY TO TESTE FOR ESTCLI = ‘PE’ SDFCOPY TO TESTE FOR ESTCLI = ‘PE’ SDFCOPY TO TESTE FOR ESTCLI = ‘PE’ SDF

Onde o resultado desta instrução acima retorna o arquivoTESTE.TXT com seu conteúdo preenchido de acordo com ascondições fornecidas.Como faço para obter este mesmo resultadousando a instrução SQL?

Resposta: Para salvar o resultado de uma query seránecessário jogar os resultados em um memo e depois salvar emtxt. Foi adicionado um botão e coloquei no seu evento OnClick oseguinte o código:

Query1.First; while not Query1.Eof do begin Memo1.Lines.add(Query1.FieldByName(‘name’).AsString);//jogas informações docampo NAME no memo,terá que adicionar campo por campo. Query1.Next; end; memo1.LineS.SaveToFile(‘resultado.txt’);//exporta o conteúdo do Memo para um txt

Dúvida enviada por Tatiane Peixoto, Recife – PE.

Pergunta: Encontrei um artigo falando sobre um driveespecífico para oFirebird chamado UIB. Inclusive disponibilizava a DLL eDBXDRIVERS.INI.Qual a opnião de vocês quanto a utilização domesmo?

Resposta: É altamente recomendável utilizar o Driverespecífico do Firebird, pois cadavez mais o Interbase se diferencia do Firebird econsequentemente o Driverdo Interbase cada vez mais ficará incompatível com o Firebird.

Dúvida enviada por: Anderson Miranda,Santo Antonio – RJ.

Pergunta: Em que situação devo utilizar o controleTRANSAÇÃO nos meus sistemas?Por que em relacionamento Master/Detalhe foi usado somenteApplyUpdates. Onde entraria entao o comando COMMIT?Quando utilizo o INTERBASE com a palheta INTERBASE euutilizava de alguns procedimentos em alguns eventos conformeabaixo. Gostaria de saber se com DBX x Firebird tenho queutilizar algo parecido. Se positivo como ficaria:

procedureTTCadCidade.QCidadeAfterCancel(DataSet:TDataSet);begin DM.IBTransacao.RollbackRetaining;end;

procedureTTCadCidade.QCidadeAfterDelete(DataSet:TDataSet);begin try DM.IBTransacao.CommitRetaining; //Commit na transacao except DM.IBTransacao.RollbackRetaining; //Desfaz em caso de erro ShowMessage(‘Houve Erro na Exclusão!’); end; end;

procedureTTCadCidade.QCidadeAfterEdit(DataSet:TDataSet);begin LockPessimistic(‘CIDADE’, ‘CODCIDADE’,DataSet);

24

Perguntas & Respostas

end;

procedureTTCadCidade.QCidadeAfterPost(DataSet:TDataSet);begin try DM.IBTransacao.CommitRetaining; //Commit na transacao except DM.IBTransacao.RollbackRetaining; //Desfaz em caso de erro ShowMessage(‘Houve Erro na Gravação!’); end; end;

Resposta: Quando trabalhamos com o componenteClientDataSet e efetuamos a chamada no método ApplyUpdates,o mesmo implicitamente abre e tentar “comitar” uma transação ecaso ocorra alguma inconsitência, o evento “OnReconcileError”do ClientDataSet será acionado e neste evento você poderá trataro retorno, dando possibilidade do usuário corrigir e tentarnovamente ou simplesmente abortar.

Contudo, quando o evento “OnReconcileError” não estáhabilitado, caso o ApplyUpdates venha a falhar, nenhumaexceção será levantada, motivo este que no fluxo de execução desua aplicação ele tenta executar o “Commit”. Outro meio deverificar se o ApplyUpdates foi bem sucedido e verificando seupróprio retorno, visto o mesmo retornar o número de errosdurante a atualização:

if cdsClientes.ApplyUpdates(0) > 0 then ShowMessage(‘Problemas ao aplicaratualizações!’);

Mesmo quando trabalhamos com relacionamentos Master/Detail em ClientDataSets, não é necessário fazer o controle detransações explícito, visto o método ApplyUpdates do MASTERefetuar implicitamente o controle.

A única situação que é necessário efetuar o controle detransação explícito é quando precisamos garantir a atualizaçãode vários ClientDataSets que não possuem relacionamentos umcom o outro e necessitamos atualizar “todos” ou “nenhum”, nestecaso a abordagem ficaria assim:

var TD: TTransactionDesc;begin Randomize; { Abre uma transação para controlar o

processamento todo } TD.TransactionID := Random(65635); TD.IsolationLevel := xilREADCOMMITTED; SQLConnection.StartTransaction(TD); try if PrimeiroClientDataSet.ApplyUpdates(0)> 0 then raise Exception.Create(‘Erro noprimeiro ClientDataSet’); if SegundoClientDataSet.ApplyUpdates(0) >0 then raise Exception.Create(‘Erro no SegundoClientDataSet’); if TerceiroClientDataSet.ApplyUpdates(0)> 0 then raise Exception.Create(‘Erro noTerceiro ClientDataSet’); SQLConnection.Commit(TD); { Em caso desucesso, confirma a transação } except on E: Exception do {Em caso de erro,aborta todo processamento } if SQLConnection.InTransaction then SQLConnection.Rollback(TD); End;end;

Observe que “levantamos” uma exceção caso o número deerros retornado pelo ClientDataSet for maior que zero, dessaforma o “Commit” não será executado e o fluxo de execução serádesviado para o bloco “Except”.

Dúvida enviada por: Anderson Miranda,Santo Antonio – RJ.

Pergunta: Tem como via programação adicionarprogramas/porta direto no FIREWALL DO XP ? porque têmprogramas que devem ser liberado pelo firewall para funcionar.

Resposta: Para adicioar portas via programação énecessário acessar o registro do Windows. Segue abaixo oscomandos:

implementation

//Declare a unit Registryuses Registry;

{$R *.dfm}

procedure TForm1.Button1Click(Sender:TObject);

25

Perguntas & Respostas

var Reg: TRegistry;beginReg := TRegistry.Create;Reg.RootKey:= HKEY_LOCAL_MACHINE;Reg.OpenKey(‘\SYSTEM\ControlSet001\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\GloballyOpenPorts\List’,False);Reg.WriteString(‘1876:TCP’,’1876:TCP:*:Enabled:TESTE’);Reg.Free;end;

Dúvida enviada por Silvio Pereira, São José do Rio Preto –SP.

Pergunta: Como que eu simulo a tecla BACKSPACE(barra de espaço)?

Resposta: Abaixo o código que irá simular o backspaceatravés do clique de um botão:

procedure TForm1.BitBtn1Click(Sender:TObject);begin // Simula o backspace edit1.SetFocus; edit1.Selstart := length(edit1.Text); Keybd_event(VK_BACK,0,0,0);end;

Dúvida enviada por Afonso Celso, Fartura - SP

Pergunta: Estou tendo dificuldades em mostrar umaassinatura gráfica em um relatório usando o Quick Report.Estouusando o seguinte código:

qriTecGrafAss.Picture.Assign(TPersistent(SqlVwT755AssGrafUsuariosGRAFASSELET.Value));

Pergunta: Tenho um formulário de consulta, onde precisoselecionar alguns registros para impressão e para isso criei umcampo do tipo InternalCalc do tipo Booleanno ClientDataSet da minha consulta para selecionar os registrosparaimpressão.Preciso que este campo ao abrir a minha consulta, jáesteja setada como True. Isto é possível?

Resposta: Para fazer isto entre no EventoOnCalcFields do ClientDataset e coloque o seguintecódigo:Ex:

ClientDataSet1campo.Value := true;

Dúvida enviada por Alessandro, Araras – SP.

Pergunta: Queria saber do suporte se existe algumcomponente gratuito para geração de boletos bancários?

Resposta: Existe um chamado GBboleto, estou te enviandoo link http://sourceforge.net/projects/gbboleto (Serve para váriosbancos)

Dúvida enviada por Wágner Ferreira, Salvador – BA.

Pergunta: Gostaria de saber o código para transferir umaimagem para um documento do word.

Resposta: Abaixo o código para inserir uma imagemno Word:

//Declare a unit Comobj

uses Comobj;

//Insira um botão no formulário e neste botãoo seguinte códigoprocedure TForm1.BitBtn1Click(Sender:TObject);var MSWord : variant;begin MSWord:= CreateOleObject(‘Word.Basic’); MSWord.Filenew;//inicia um novo documento MSWord.AppShow;//mostra o word MSWord.appmaximize;//Maximiza a janela doWord MSWord.insertpicture(‘C:\Figuras\theclub.jpg’);//Caminho da figura a serinserida no Wordend;

Dúvida enviada por: Maria Alice Massochim, Cascavel – PR.

Pergunta: Preciso de um código para salvar em TXTutilizando o Quick Report?

Resposta: Abaixo segue o código para exportar para TXT.

// Colocar o componente QRTextFilterprocedure TForm1.Button1Click(Sender:TObject);begin // Exportar para TXT QuickRep1.ExportToFilter(TQRAsciiExportFilter.Create(‘C:\REPORT.TXT’)); QuickRep1.ExportFilter.Free;end;

26

Perguntas & Respostas

Dúvida enviada por Altec - Soluções Informática Ltda,Araras – SP.

Pergunta: Caros colegas, existe alguma forma que não seconsiga movimentar ou arrastar o formulário?

Resposta: Sim existe. Verifique o código abaixo:

type Tform1 = class(TForm) private procedure WMNCHitTest(var M:TWMNCHitTest); message wm_NCHitTest; public { Public declarations } end;

var Form1: Tform1;

implementation

{$R *.DFM}

procedure Tform1.WMNCHitTest(var M:TWMNCHitTest);begin inherited; if M.Result = htCaption then M.Result := htClient;end;

Dúvida enviada por Softline Informatica Ltda, Recife – PE.

Pergunta: Como que eu posso pegar a Data/Hora doservidor Firebird?

Resposta: Para pegar a Data e Hora do Servidor Firebird,veja a instrução SQL abaixo:

select Cast(‘now’ as timestamp) as AGORA fromrdb$database

Dúvida enviada por João Francisco Martins Teixeira,Barretos – SP.

Pergunta: Tenho que capturar o nome da impressorapadrão.

Resposta: Abaixo a função que retorna a impressorapadrão. Segue abaixo o código:

implementation

uses Printers;

{$R *.dfm}

function GetDefaultPrinter: string;var ResStr: array[0..255] of Char;begin GetProfileString(‘Windows’, ‘device’, ‘’,ResStr, 255); Result := StrPas(ResStr);end;

procedure TForm1.Button1Click(Sender:TObject);begin Caption := GetDefaultPrinter;end;

Dúvida enviada por Eduardo Alves, São Paulo – SP.

Pergunta: Estou tendo dificuldades em mostrar umaassinatura gráfica em um relatório usando o Quick Report. Uso oDelphi7.Estou usando a seguinte instrução:

qriTecGrafAss.Picture.Assign(TPersistent(SqlVwT755AssGrafUsuariosGRAFASSELET.Value));

Resposta: Abaixo o código que faz isto.

procedureTForm1.DetailBand1BeforePrint(Sender:TQRCustomBand; var PrintBand: Boolean);Var BMP: TBitmap; stMem: TMemoryStream;begin BMP := TBitmap.Create; stMem := TMemoryStream.Create; Try IBTable1IMAGEM.SaveToStream( stMem ); stMem.Position := 0; BMP.LoadFromStream( stMem ); qrimage1.Picture.Assign( bmp ); Finally stMem.Free; bmp.Free;End;

Duvida enviada por Marcos Caetano, Belo Horizonte – MG.

27

Instalando a Biblioteca RxLib no Delphi 2007 forWin32

A codegear vem se preocupando muito com o fato dainstalação de componentes de terceiros. Nesta Dica estareimostrando que é possível instalar a Biblioteca RxLib do Delphi2006 no Delphi 2007. Vejam como é simples.

- Primeiramente abra o site http://sourceforge.net/projects/rxlib, clique em Download Rx Library for Delphi e em seguidabaixe o RxLib 2.7.6 for Delphi 6-2006.

- Em seguida abra o Delphi 2007, vá em tools/options. EmDelphi Options , library win32 escolha Library path e adicione apasta units.

- Clique em Open na pasta [seudiretório]/Package/Delphi2006/Rxlib.bdsgroup. Observe que será recriado todos osarquivos .res.

- Logo após acesse Project/Build all Projects, e à esquerdainstale os seguintes dcls. dclrx100, dclrxdb100 e dclrxbd100.

Como verificar o IP do computador através do site ‘http://www.meuip.com.br/’

Abra o Delphi coloque em seu formulário um Button, umEdit e um componente da palheta Indy Clients chamado Idhttp.No evento Onclick do Button insira o seguinte código:

Dicas e Truques

Pergunta: Como eu posso desabilitar a tecla printscreen?

Resposta: Poderá utilizar o código abaixo:

implementation

//declare a unituses Clipbrd;{$R *.dfm}

//No evento Onkeyup do Formulário//Deixe a propriedade Keypreview como true doformulárioprocedure TForm1.FormKeyUp(Sender: TObject;

var Key: Word; Shift: TShiftState);varClip: TClipBoard;begin if Key = VK_Snapshot then begin key:=VK_Clear; Clip := TClipBoard.Create; Clip.Clear; end;end;

Dúvida enviada por Satoshi Okada São Paulo – SP.

28

Dicas & Truques

procedure TForm1.BitBtn1Click(Sender:TObject);var S,str,str2: String; i:integer;begin try // Solicita ao site. S := Idhttp1.Get(‘http://www.meuip.com.br/’); str:= copy(S,(pos(‘?’,S)+3),20); for I := Length(str) downTo 1 do if (str[i] in [‘0’..’9',’.’]) then str2 := Copy(str, i, 1) + str2; Edit1.Text := str2; Except ShowMessage(‘A internet está fora do ar!’); end;end;

Para que servem OnGetEditMask, OnGetEditTexte OnSetEditText do TStringGrid

O evento OnGetEditMask ocorre quando entramos no modode edição. Neste momento podemos verificar em qual linha/coluna se encontra o cursor e então, se quiser, poderá especificaruma máscara de edição. Exemplo:

procedureTForm1.StringGrid1GetEditMask(Sender:TObject; ACol, ARow: Integer; var Value: String);begin if (ARow = 1) and (ACol = 1) then Value := ‘(999) 999-9999;1;_’; //Telefoneend;

O evento OnGetEditText ocorre também quando entramos no

modode edição. Neste momento podemos manipularmos o

texto dacélula atual (linha/coluna) e então podemos simular

algo talcomo uma tabela onde opções podem ser digitadas

atravésde números. Exemplo:

procedure

TForm1.StringGrid1GetEditText(Sender:TObject; ACol, ARow: Integer; var Value: String);begin if (ARow = 1) and (ACol = 2) then begin if StringGrid1.Cells[ACol, ARow] =‘Ótimo’ then Value := ‘1’ else if StringGrid1.Cells[ACol, ARow] =‘Regular’ then Value := ‘2’ else if StringGrid1.Cells[ACol, ARow] =‘Ruim’ then Value := ‘3’; end;end;

O evento evento OnSetEditText ocorre quando saímos domodo de edição. Neste momento podemos manipular a entrada etrocar por um texto equivalente. Normalmente usamos esteevento em conjunto com o evento OnGetEditText. Exemplo:

procedureTForm1.StringGrid1SetEditText(Sender:TObject; ACol, ARow: Integer; const Value: String);begin if (ARow = 1) and (ACol = 2) then begin if Value = ‘1’ then StringGrid1.Cells[ACol, ARow] :=‘Ótimo’ else if Value = ‘2’ then StringGrid1.Cells[ACol, ARow] :=‘Regular’ else if Value = ‘3’ then StringGrid1.Cells[ACol, ARow] := ‘Ruim’ end;end;

Trabalhando com Fontes no Windows

- Adicionar uma nova fonte no WindowsColoque o código abaixo no evento OnClick de um botão.

AddFontResource(PChar(GetCurrentDir+’\DIRTYEGO.TTF’));

- Saber se determinada Fonte está instalada no WindowsColoque este código no evento OnClick de um botão.

with Screen.Fonts do if IndexOf(‘Courier New’) >= 0 then ShowMessage(‘A fonte está instalada.’) else ShowMessage(‘A fonte não estáinstalada.’);

Obter o valor de uma variável de ambiente

Inclua na seção uses a unit Windows

//Esta função recebe o nome da variável deambiente que queremos acessar e retorna umastring com seu valor, ou uma string vazia sea variável não existir.

function tbGetEnvVar(const VarName: string):string;var I: integer;begin Result := ‘’;

{ Obtém o comprimento da variável } I := GetEnvironmentVariable(‘PATH’, nil,0);

if I > 0 then begin SetLength(Result, I); GetEnvironmentVariable(‘PATH’,PChar(Result), I); end;end;

//Para utilizá-la:

procedure TForm1.BitBtn1Click(Sender:TObject);begin Edit1.Text := tbGetEnvVar(‘PATH’);

end;

Criando uma tabela no Firebird pelo Delphi

Abra o Delphi e coloque um Sqlconnection, uma SqlQuery eum Botão. Configure o SqlConnection para uma base de dados eligue a SqlQuery no SqlConnection. No evento Onclick destebotão insira o seguinte código:

{A classe TStringList é utilizada para armazenar emanipular

uma lista de strings. Através do método Add da classe épossível

inserir uma nova string a lista}

//criando Stringlist na memória L := TStringList.Create; //pega o nome da tabela SQLConnection1.GetTableNames(L); //pega a posição do tbteste(começa no 0) if L.IndexOf(‘tbteste’) >= 0 then begin Showmessage(‘Esta tabela já existe noBD!’); Abort end else begin //Criamos uma tabela chamada tbteste comdois campos. SQLQuery1.Close; SQLQuery1.SQL.Clear; SQLQuery1.SQL.Add(‘create tabletbteste(‘); SQLQuery1.Sql.Add(‘cod_teste integer notnull primary key, ‘); SQLQuery1.Sql.Add(‘nome_testevarchar(40))’); SQLQuery1.ExecSQL; L.Free; ShowMessage(‘Tabela Criada comsucesso!’); end;end;

Utilizando a Função Decodetime para separarHora, Minuto, Segundo e Milisegundo

procedure TForm1.Button1Click(Sender:TObject);

Dicas & Truques

30

var Hora: TTime; Hour, Min, Seg, MSeg : Word; L:TStringList;begin //Hora Atual Hora:=now; //Criando uma lista de strings L := TStringList.Create(); //Utilizando a função para separar a H/M/S/M DecodeTime(Hora, Hour, Min, Seg, MSeg); L.Add(‘Hora Atual: ‘+timetostr(Hora)); L.Add(‘Horas: ‘+inttostr(Hour)); L.Add(‘Minutos: ‘+inttostr(Min)); L.Add(‘Segundos: ‘+inttostr(Seg)); L.Add(‘Milisegundos: ‘+inttostr(Mseg)); ShowMessage(L.Text);end;

Impedir que o form seja arrastado para fora dasmargens da tela

Na seção Private declare a procedure abaixo:

privateprivateprivateprivateprivate procedure procedure procedure procedure procedure WMMove(var Msg: TWMMove);message WM_MOVE;

Abaixo da palavra implementation escreva a procedureabaixo:

procedureprocedureprocedureprocedureprocedure TForm1.WMMove(var Msg: TWMMove);beginbeginbeginbeginbegin if if if if if Left < 0 thenthenthenthenthen Left := 0; if if if if if Top < 0 thenthenthenthenthen Top := 0; if if if if if Screen.Width - (Left + Width) < 0 thenthenthenthenthen Left := Screen.Width - Width; if if if if if Screen.Height - (Top + Height) < 0 thenthenthenthenthen Top := Screen.Height - Height;end;end;end;end;end;

Imprimir na Vertical no QuickReport

procedure ImprimirNaVertical(AQuick:TQuickRep; ABanda: TQrBand; ATexto: string);var lf: TLogFont;

tf: TFont; xQrImage: TQrImage;begin xQrImage := TQrImage.Create(AQuick); xQrImage.Parent := ABanda; xQrImage.Align := alLeft; xQrImage.Width := 10; xQrImage.BringToFront; with xQrImage.Canvas do begin Font.Name := ‘Arial’; Font.Size := 7; tf := TFont.Create; tf.Assign(Font); GetObject(tf.Handle, Sizeof(lf), @lf); lf.lfEscapement := 900; lf.lfOrientation := 450; tf.Handle := CreateFontIndirect(lf); Font.Assign(tf); tf.Free; TextOut(0, xQrImage.Height div 2,ATexto); end;end;

Função para ver se determinanda data cai em umfinal de semana

Function FimSemana(dData : TDateTime) :boolean;beginif (DayOfWeek(dData) = 1) or(DayOfWeek(dData) = 7) Thenbeginresult := true;endelsebeginresult := false;end;end;

Movimentando o ponteiro do mouse sem aintervenção do usuário

Para movimentar o ponteiro do mouse sem intervenção dousuário, deve-se usar um TTimer e colocar o seguinte código emseu evento OnTimer:

procedure TForm1.Timer1Timer(Sender:

Dicas & Truques

TObject);var pt:tpoint;begin getcursorpos(pt); pt.x := pt.x + 1; pt.y := pt.y + 1; SetCursorPos(pt.x,pt.y); if pt.x>=screen.width-1 thensetcursorpos(0,pt.y); if pt.y>=screen.height-1 thensetcursorpos(pt.x,0);end;

Obter nomes dos campos de uma tabela

Inclua na seção uses: dbTables, Classes, FormsA função abaixo obtém os nomes de todos os campos de uma

tabela do banco de dados.

procedureprocedureprocedureprocedureprocedure tbGetFieldNames(const DBName,TblName: string; List: TStringList);varvarvarvarvar I: integer;beginbeginbeginbeginbegin List.Clear; with with with with with TTable.Create(Application) do do do do do try try try try try DatabaseName := DBName; TableName := TblName; with FieldDefs do begin Update; forforforforfor I := 0 tototototo Count -1 do -1 do -1 do -1 do -1 do List.Add(Items[I].Name); end; end; end; end; end; finally finally finally finally finally Free; end; end; end; end; end;end;end;end;end;end;

Exemplo:

- Coloque um TMemo e um TButton no Form;- Coloque o código abaixo no evento OnClick do Button:

procedureprocedureprocedureprocedureprocedure TForm1.Button1Click(Sender:TObject);varvarvarvarvar List: TStringList;beginbeginbeginbeginbegin List := TStringList.Create;

try tbGetFieldNames(Edit1.Text, Edit2.Text,List); Memo1.Lines.Assign(List); finally finally finally finally finally List.Free; end; end; end; end; end;end;end;end;end;end;

Qual a diferença entre NOW eCURRENT_TIMESTAMP?

Now: retorna o tempo no momento em que for avaliado.Current_timestamp: retorna o mesmo valor de tempo durante

a duração do comando que está sendo executado.Por exemplo, se você executar um UPDATE para atualizar

vários registros de uma tabela com muitos registros, alterando ovalor de um campo para NOW, você terá vários registros comvalores diferentes de tempo. Se usar CURRENT_TIMESTAMP, ovalor do campo em questão, para todos os registros, será omesmo.

Desativando e Ativando todas as triggers doBanco Firebird

//desabilitar todas as triggers do bancoupdate RDB$TRIGGERS set RDB$TRIGGER_INACTIVE= 1where rdb$trigger_source is not null and((rdb$system_flag = 0) or(rdb$system_flag is null))

//habilita todas as triggers do bancoupdate RDB$TRIGGERS set RDB$TRIGGER_INACTIVE= 0where rdb$trigger_source is not null and((rdb$system_flag = 0) or(rdb$system_flag is null))

Como desativar os índices de ChavesPrimárias?

// Para desativar o índiceupdate rdb$indicesset rdb$index_inactive = 3where rdb$index_name = ‘NOME_DO_INDICE’

// Para reativar o índiceupdate rdb$indicesset rdb$index_inactive = 0where rdb$index_name = = ‘NOME_DO_INDICE’

Dicas & Truques