artigo SQL Magazine 11 - Novidades do Firebird 1.5

Artigo da Revista SQL Magazine -Edição 11.

Clique aqui para ler esse artigo em PDF.

Clique aqui para ler todos os artigos desta edição

 

Novidades do Firebird 1.5

 

Nos últimos meses o Firebird teve presença constante na mídia on-line: recentemente ficou em segundo lugar em uma pesquisa “Qual o seu banco de dados preferido?” realizada nos fóruns do site LinuxQuestions.org (http://www.linuxquestions.org/questions/showthread.php?s=&threadid=116360), com diferença de apenas 2 votos para o primeiro lugar, que acabou ficando com o MySQL. Os outros bancos que participaram da pesquisa foram o Postgres, Sybase, Berkeley DB, Oracle e DB2. A guerra de nomes promovida pelo Mozilla e pelo Firebird também contribuiu para colocar o banco de dados na mídia, e teve um final feliz com a mudança do nome do browser Mozilla Firebird para Mozilla FireFox, deixando o uso do nome Firebird livre para o banco de dados. O site da O’reilly, famosa editora de livros da área de informática, promoveu uma pesquisa sobre qual seria o banco de dados preferido dos seus visitantes e o Firebird/InterBase ficou em primeiro lugar. Tudo isso mostra que o Firebird está ampliando rapidamente seu espaço no disputado mundo dos SGDBs!

O lançamento da versão 1.5 promete manter o FB sob os olhares da mídia especializada por mais algum tempo. Essa versão é um marco na história do Firebird, pois é a primeira versão em que o banco dá sinais claros de independência do seu progenitor, o InterBase. Apesar da versão 1.0 ter apresentado várias características que já o diferenciavam do InterBase,  ela ainda mantinha uma vínculo muito forte com o IB, usando inclusive os mesmos nomes de arquivos, chaves de registro no Windows, etc.

O Firebird 1.5 começou a ser desenvolvido há vários meses atrás e deveria ser apenas uma versão de consolidação, apresentando pela primeira vez a base de código convertida de C para C++. No entanto, foram tantas as novidades incorporadas nessa versão que a tornam praticamente uma “major version”.

Nesse artigo estarei apresentando as principais novidades disponíveis no FB 1.5. A listagem completa de todos os recursos, alterações e correções de bugs pode ser encontrada no release notes do Firebird. O link para download do Release Notes em português do Brasil pode ser obtido em http://www.sqlmagazine.com.br/apostilas/Firebird1.5_RNBR.zip. As novidades apresentadas aqui são específicas do Firebird e não podem ser encontradas em nenhuma das versões do InterBase disponíveis no momento.

 

Nota - História

O Firebird é um banco gratuito e Open Source que teve sua origem no código do Borland InterBase 6.0. Após a liberação do código do IB 6.0 como um produto Open Source, a Borland decidiu lançar as versões posteriores do IB sob o modelo comercial (software fechado e pago). Inconformados com essa atitude, muitos usuários e pessoas envolvidas com o InterBase se juntaram e criaram o Firebird, com a determinação de dar continuidade à um banco de dados que fosse gratuito e com código aberto.

 

Novidades

Mudanças nos nomes dos arquivos

O Firebird 1.0 utilizava os mesmos nomes de arquivos que o seu progenitor, o InterBase. O Firebird 1.5 trouxe novos nomes para esses arquivos, marcando sua identidade nos mesmos. A tabela 1 mostra os principais arquivos renomeados. A lista completa está no release notes do FB 1.5.

 

Nome no FB 1.0

Nome no FB 1.5

Descrição

isc4.gdb

security.fdb

Banco de dados de segurança

ibserver.exe

fbserver.exe

Servidor Firebird

interbase.msg

firebird.msg

Mensagens de erro, etc.

interbase.log

firebird.log

Log do servidor e cliente

isc_config

firebird.conf

Arquivo de configurações do servidor no Linux

Ibconfig

firebird.conf

Arquivo de configurações do servidor no Windows

gds32.dll

fbclient.dll

Biblioteca cliente do Firebird no Windows

libgds.so

libfbclient.so / libfbembed.so

Biblioteca cliente do Firebird no Linux

Tabela 1. Arquivos renomeados no Firebird 1.5

Comandos CASE, COALESCE e NULLIF

O comando CASE permite retornar um valor baseado nas condições definidas. A introdução desse comando permitiu a implementação de duas outras funções: COALESCE e NULLIF. COALESCE retorna o primeiro valor não nulo de uma seqüência de valores passados como parâmetros. NULLIF recebe dois parâmetros de entrada e retorna NULL caso os valores dos 2 parâmetros sejam iguais; caso os valores sejam diferentes, o valor do primeiro parâmetro é retornado. Internamente COALESCE e NULLIF são convertidos em um CASE.

A listagem 1 mostra a utilização do CASE em um select para substituir o código utilizado no campo método_pagto (que representa o tipo de pagamento realizado em uma venda) pela sua respectiva descrição.

Na listagem 2 usamos a função coalesce para obter, em ordem de preferência, o nome fantasia de uma empresa, ou a razão social ou, caso nenhum desses esteja disponível, o string ‘Sem Nome’. A função nullif utilizada no update faz com que o campo estoque da tabela produtos fique nulo caso o valor atual dele seja 0.

 

SELECT v.Nota_Fiscal, v.total,

 CASE v.metodo_pagto

  WHEN 'V' THEN 'A vista'

  WHEN 'P' THEN 'Parcelado'

  WHEN 'C' THEN 'Cartão de crédito'

  WHEN 'D' THEN 'Cheque Pré-datado'

  ELSE 'Tipo desconhecido ''' || v.metodo_pagto || ''''

 END

FROM Vendas< v;

Listagem 1. Uso do CASE em select

 

select coalesce (c.nome_fantasia, c.razao_social, 'Sem Nome')

from clientes c;

 

update produtos set estoque = nullif(estoque,0);

Listagem 2. Exemplos de uso do coalesce e nullif.

SQL dinâmicos

Um recurso poderoso que permite montar e executar dinamicamente comandos SQL dentro de Stored Procedures e Triggers através dos comandos Execute Statement e sua variação For Execute Statement. O primeiro deve ser utilizado para a execução de comandos que não retornam resultados (updates, inserts, etc.) ou retornam no máximo 1 linha de dados. O segundo é específico para comandos que retornam várias linhas de resultado (selects tradicionais).

Como a engine do banco de dados não pode validar previamente o comando SQL que será montado em tempo de execução, é necessário tomar cuidado na sua construção pois um comando inválido provocará uma exceção/erro ao ser executado. Devemos lembrar também que não é possível utilizar parâmetros nos comandos montados dinamicamente.

O código da listagem 3 mostra um exemplo simples de utilização desse recurso. A procedure SOMA recebe o nome de um campo e de uma tabela e realiza uma operação de somatória (SUM) nesse campo, retornando o valor obtido. A procedure selecionável GET_ULT_COMPRA recebe como parâmetro o nome de uma tabela e uma sequência de códigos de clientes separados por vírgula e devolve o nome de cada cliente e a data da sua última compra.

 

CREATE PROCEDURE Soma (Campo VARCHAR(30), Tabela VARCHAR(50))

RETURNS (Resultado NUMERIC (18,2))

AS

BEGIN

  EXECUTE STATEMENT ‘SELECT SUM(‘ || Campo || ‘) FROM ’ || Tabela INTO

  :Resultado;

END

 

CREATE PROCEDURE GET_ULT_COMPRA (

    VARTABELA VARCHAR(32),

    VARCODIGOS VARCHAR(512))

AS

  DECLARE VARIABLE VARNOME VARCHAR(50);

  DECLARE VARIABLE VARULTCOMPRA DATE;

begin

  for execute statement

    'select nome, ultcompra from ' || :VarTabela ||

    'where codigo in (' || :VarCodigos || ')'

    into :VarNome, :VarUltCompra

  do

  begin

    /* Processa as informações */

    suspend;

  end

end

 

Listagem 3. Utilização do Execute Statement e For Execute Statement

Versão Classic do servidor para Windows

Muitos desconhecem o fato de que o Firebird se apresenta em duas versões: Classic e SuperServer. A diferença principal entre as duas é que a Classic dispara um processo do servidor para cada conexão requisitada e não compartilha o cachê de dados entre elas, significando que se houver 10 conexões a um mesmo banco de dados existirão 10 processos do Firebird rodando e cada um deles terá sua própria área de memória não compartilhada. A versão SuperServer trabalha com um único processo do servidor, criando threads para cada conexão e compartilhando o cachê entre elas. A figura 1 mostra a tela de instalação indicando qual a versão que se deseja instalar.

A versão Classic sempre existiu no Linux mas durante quase 8 anos parou de ser produzida para o Windows. Seu retorno se deve ao fato de trabalhar melhor com computadores SMP (Symmetric Multiple Processor) rodando sistema operacional Windows, do que a versão SuperServer. Dependendo do número de conexões simultâneas e do tamanho definido para o cachê dos bancos de dados, a versão Classic necessita de grande quantidade de memória RAM no servidor.

 

Figura 1. Tela de instalação do servidor Firebird Classic ou SuperServer

Múltiplos servidores rodando simultaneamente

A partir da versão 1.5, o Firebird permite que vários servidores estejam rodando simultaneamente na mesma máquina. Cada instância do servidor deve usar uma porta TCP/IP distinta, lembrando que a porta padrão é a 3050 (a mesma do InterBase).

Apesar de já ser possível rodar vários servidores ao mesmo tempo, o processo de instalação ainda não está preparado totalmente para essa situação, sendo necessário fazer algumas configurações manuais para completar o processo. A revista ClubeDelphi nº50 contém um artigo de minha autoria que mostra como fazer a instalação e configuração de múltiplos servidores Firebird no Windows.

Através desse recurso pode-se até mesmo rodar um servidor Firebird em conjunto com o InterBase, o que pode facilitar a vida dos desenvolvedores que possuem sistemas trabalhando com os 2 bancos de dados ou estão migrando de um para outro.

 

ando simultaneamente com o InterBase 6.0

Nomeação de índices automáticos

Esses índices são criados automaticamente pelo servidor Firebird durante a criação de uma constraint que dependa de índices, como por exemplo chaves primárias ou estrangeiras. Até a versão 1.0, esses índices recebiam nomes padrões no formato RDB$??? (ver figura 2). É fácil observar que esses nomes não dizem muita coisa ao desenvolvedor, por exemplo: para saber quais campos estão sendo indexados é necessário consultar a metadata do banco.

Outro problema gerado pela nomeação automática de índices é que durante um backup/restore do banco de dados, o índice pode voltar com um nome diferente, o que quebraria qualquer PLANO definido pelo usuário que utilizasse esse índice.

A versão 1.5 permite nomear o índice que será gerado pela constraint através da cláusula USING. O exemplo abaixo cria uma chave primária na tabela TESTE e nomeia o índice associado como ind_teste_pk_ID. Pelo nome podemos identificar facilmente a tabela a quem ele pertence (teste), que se trata de uma chave primária (pk), e qual é o campo indexado (ID).

 

alter table teste add constraint pk_teste primary key (id) using desc index ind_teste_pk_ID;

 

Figura 2. Nomeação de índices automáticos no FB 1.0

Triggers universais

Até a versão 1.0, um trigger só poderia estar associado a um único evento (after/before - insert,update,delete). Agora podemos associar um único trigger a vários eventos! Para identificar o tipo de ação que disparou o trigger foram criadas 3 variáveis : Inserting, Updating e Deleting, que podem ser checadas no código do trigger e, através de Ifs, condicionar os comandos a serem executados, como mostrado na Listagem 4:

 

CREATE TRIGGER TABELA_BIU FOR TABELA

ACTIVE BEFORE INSERT OR UPDATE POSITION 0

AS

begin

  if (inserting) then

    begin

      /* Executa alguma operação quando for inserção */

    end

  else

    if (updating) then

      begin

        /* Executa alguma operação quando for edição */

      end

end

Listagem 4. Uso de triggers universais

Nota

Não é possível criar triggers universais do tipo AFTER e BEFORE ao mesmo tempo.

 

NULLs em constraints e índices únicos

De acordo com o padrão SQL 99, índices e constraints únicas podem aceitar valores nulos desde que a coluna indexada não esteja definida como NOT NULL. O Firebird 1.5 implementa essa funcionalidade, lembrando que a única exceção é o caso de índices criados por chaves primárias que, por definição, devem ter suas colunas definidas como NOT NULL.

Travamento pessimista

O bom uso da arquitetura MGA (Multi Gerational Architecture, também conhecida como versioning) do Firebird torna praticamente desnecessária a utilização de travamentos pessimistas nas aplicações. No entanto, há situações onde esse tipo de bloqueio é bem vindo. O Firebird 1.5 implementa duas novas cláusulas no select para trabalhar com travamentos pessimistas. As cláusulas “WITH LOCK” e “FOR UPDATE” tem a função de travar os registros selecionados, evitando que outras transações possam alterá-los enquanto permanecerem bloqueados.

Devemos tomar cuidado para não extrapolar o uso desse recurso sob a pena de gerarmos deadlocks generalizados ou termos queda de performance.

O servidor gerencia o resultado de um select enviando as linhas resultantes em pacotes para o cliente. O número de linhas enviadas em cada pacote varia de acordo com alguns parâmetros, como a configuração da rede, protocolo, e o tamanho de cada linha. Sendo assim, quando utilizamos a clausula WITH LOCK estamos na verdade travando uma quantidade incerta de registros a cada fetch e por isso é recomendado utilizá-la em selects que retornem apenas uma única linha de resultado.

A cláusula FOR UPDATE age de uma maneira diferente. Ela faz com que os registros recuperados sejam enviados um a um a cada “fetch” realizado pelo cliente, o que nos permite determinar exatamente qual foi a quantidade de registros bloqueados. Obviamente há uma queda de performance na recuperação de muitos registros quando o FOR UPDATE é utilizado.

 

NOTA

Se você não tem a preocupação de saber exatamente quantos registros foram travados, o with lock sozinho tem mais performance pois trava mais registros de uma única vez.

 

Em ambas as situações devemos levar em conta que, em selects que retornam vários registros, não há garantia que todos eles sejam travados no momento inicial da execução do comando! Como vimos, os registros são bloqueados quando são requisitados através de um fetch. Isso quer dizer que se uma aplicação está recuperando os dados em blocos, os registros que ainda não foram requisitados não estarão protegidos. Nesse meio tempo, uma outra transação pode acessar esses registros e bloqueá-los, causando uma exceção (erro) quando a primeira transação tentar travá-los. Se houver necessidade de travar todos os registros no momento da abertura de uma query, podemos fazer uso de um FetchAll, mas geralmente isso não é desejado por questões de performance.

No exemplo abaixo, o primeiro select bloqueará um único registro selecionado pelo campo código (chave primária). O segundo select travará os registros da tabela de clientes onde o campo cidade seja igual a ‘São Paulo’, lembrando que os registros serão bloqueados um a um, a cada fetch realizado.

 

Select * from clientes where codigo = :x with lock;

Select * from clientes where cidade = ‘São Paulo’ for update with lock;

 

Mais recursos nas funções de agregação

A versão 1.0 do Firebird permitia a utilização do group by somente com colunas nomeadas no select ou com funções definidas pelo usuário (udf). A versão 1.5 estendeu a utilização do group by aceitando agora o grau (posição) da coluna no select (ex: group by 1, 2), funções numéricas (ex: group by extract (month from data)), funções alfanuméricas (ex: group by substring (fone from 1 for 2)) e até mesmo o uso da cláusula CASE (veja listagem 5 e figura 3)!

 

select count(c.*)

from clientes c

group by

 case

  WHEN (c.estado in ('RS', 'SC', 'PR')) then 'Sul'

  WHEN (c.estado in ('SP','RJ', 'ES', 'MG')) then 'Sudeste'

  WHEN (c.estado in ('MG','MS','GO','DF')) then 'Centro-Oeste'

  WHEN (c.estado in ('AC','RO','AM','RR','AP','PA')) then 'Norte'

  WHEN (c.estado in ('MA','PI','CE','RN','PB','PE','AL','SE','BA')) then 'Nordeste'

  ELSE 'Região desconhecida'

 END

 

Ou ainda mais interessante:

 

select

 case

   WHEN (c.estado in ('RS', 'SC', 'PR')) then 'Sul'

   WHEN (c.estado in ('SP','RJ', 'ES', 'MG')) then 'Sudeste'

   WHEN (c.estado in ('MG','MS','GO','DF')) then 'Centro-Oeste'

   WHEN (c.estado in ('AC','RO','AM','RR','AP','PA')) then 'Norte'

   WHEN (c.estado in ('MA','PI','CE','RN','PB','PE','AL','SE','BA')) then 'Nordeste'

   ELSE 'Região desconhecida'

  END as REGIAO,

 count(c.*) as NUM_CLIENTES

from clientes c

group by 1

 

Listagem 5. Exemplos do uso de CASE com Group By

 

Figura 3. Resultado do select com case e group by

 

Nota: A cláusula HAVING agora só permite a utilização de colunas ou expressões que estejam presentes no group by. Nas versões anteriores essa restrição não existia, mas os resultados obtidos eram incorretos.

Order by com expressões e posicionamento de nulls

Agora é possível utilizar o order by com expressões, bem como determinar se os valores nulos irão aparecer no começo ou no final (padrão) da ordenação. Fique atento com o uso do nulls first pois ele impede o uso de índices para otimizar a ordenação, o que pode gerar problemas de performance em selects que retornam grande quantidade de linhas.

A ordenação de colunas retornadas por UNIONs em selects também é possível através do uso do grau (posição) das colunas na cláusula order by. O exemplo da listagem 6 junta informações de notas fiscais de 2 tabelas (filiais) através do union e ordena o resultado por data decrescente, sub-ordenando pelo campo processada, deixando as notas que ainda não foram processadas por último (assumindo-se que o estado NULL no campo processada determina que a nota não foi processada).

 

Select data, nota_fiscal, valor, processada

 From notas_filial_1

Union

Select data, nota_fiscal, valor, processada

 From notas_filial_2

Order by 1 desc, 4 nulls last;

Listagem 6. Exemplo de utilização de nulls last com uma union

Gerenciamento de exceções

O Firebird 1.5 permite a definição dinâmica das mensagens exibidas por uma exceção no momento em que ela é gerada, permitindo que poucas exceções estejam definidas previamente e que a mensagem apresentada ao usuário mude de acordo com o problema encontrado. Também é possível re-gerar uma exceção (re-raise) dentro de um bloco de tratamento de exceções WHEN...DO, bem como obter o valor numérico do código do erro da exceção nas variáveis GDSCODE e SQLCODE. A listagem 7 mostra exemplos do uso de exceções dinâmicas e re-raise de exceções:

 

If (new.valor < 0) then

  Exception valor_negativo 'O valor ' || cast (new.valor as varchar(15)) ||

                           ' não é válido!';

 

...

begin

  update produtos set estoque = (estoque – new.qtde)

    where codprod = new.codprod;

 

  when any do

  begin

    insert into log (coderro, descricao)

      values (sqlcode,’Erro ao atualizar estoque do produto :’ || new.codprod);

    exception; -- Re-raise

  end

end

...

Listagem 7. Exemplos de uso e tratamento de exceções

Comando LEAVE/BREAK

Permite interromper o processamento de loops gerados pelos comandos WHILE, FOR SELECT e FOR EXECUTE, desviando o processamento para o próximo comando logo após o END final do loop. O padrão SQL-99 aconselha a utilização do LEAVE ao invés do BREAK, mas ambos tem a mesma finalidade. Os comandos Leave, Break e Exit podem ser usados tanto em triggers como em stored procedures. A listagem 8 mostra um exemplo de utilização do leave para interromper um loop baseado em uma condição.

 

conta = 1;

while (:conta < 100) do

begin

  -- Realiza algum processamento, como cálculos com as variáveis x e y

  if (:x = :y) then leave; -- Se o valor da variável x for igual ao de y, sai do loop.

  conta = conta + 1;

end

Listagem 8. Utilização do Leave para interromper o loop.

Apelidos (alias) de banco de dados

Até hoje o string de conexão com um banco de dados Firebird obrigatoriamente continha o caminho (path) completo para o banco de dados, o que poderia facilitar a ação de hackers que facilmente descobririam a localização física do arquivo no servidor. A versão 1.5 introduziu o arquivo aliases.conf, localizado no diretório de instalação do FB. Ele permite que “apelidos” sejam atribuídos aos bancos de dados e que esses apelidos sejam utilizados nos strings de conexão. O arquivo aliases.conf pode ser editado com um editor de textos puro, como o bloco de notas. Cada linha do arquivo deve estar no formato apelido = caminho, por exemplo:

 

Banco1 = c:\bancos\meu_banco.fdb

 

No exemplo, o string de conexão para o banco de dados meu_banco.fdb rodando em um suposto servidor chamado my_server pode ser especificado como my_server:Banco1 ao invés de my_server:c:\bancos\meu_banco.fdb.

 

Novo padrão para a extensão dos arquivos de Bancos de dados

A extensão padrão dos arquivos de bancos de dados Firebird mudou de .gdb para .fdb. É recomendável que você adote a nova nomenclatura especialmente se estiver rodando o servidor no Windows XP ou ME com a opção de “Recuperação de sistema” ativada. Nessa situação, o Windows realiza backups automáticos de todos os arquivos com extensão .gdb quando são acessados pela primeira vez, deixando a performance da primeira conexão com o banco terrivelmente lenta. 

Opções de configuração do servidor

Um novo arquivo chamado firebird.conf contém vários parâmetros de configuração global do servidor Firebird. Esse arquivo substitui o antigo isc_config (Linux) ou ibconfig (Windows). Dezenas de parâmetros foram adicionados, oferecendo muito mais funcionalidade e flexibilidade na configuração do servidor. O arquivo firebird.conf está extensivamente comentado com explicações sobre cada parâmetro disponível, e pode ser editado/visualizado com qualquer editor de texto puro (ver figura 4).

 

Figura 4. Firebird.conf sendo editado no bloco de notas

Ordenação em memória

O servidor passou a utilizar a memória RAM disponível ao invés de arquivos temporários para fazer as ordenações (sorts) necessárias durante a execução de comandos SQL. O acesso à memória RAM é muito mais rápido do que o acesso ao disco, e portanto há um alto ganho de performance nessas situações. Caso não haja memória RAM livre suficiente, o método antigo de ordenação é utilizado.

Otimizador mais inteligente

Foram realizadas grandes melhorias no otimizador de queries promovendo ganhos de performance entre 30% e 60%! O otimizador agora é menos suscetível a falhas na escolha dos índices e ganhou poderes para utilizá-los em situações onde anteriormente não era possível. Selects extensos envolvendo diversas tabelas ou que utilizam junções do tipo “left join” produzem agora PLANos mais inteligentes de acesso.

Mensagens de erro mais específicas

Houve uma preocupação com a melhoria das mensagens de erros apresentadas pelo servidor, fazendo com que elas sejam mais explícitas e específicas à situação de erro ocorrido, facilitando muito o processo de debug do código de stored procedures e triggers.

Servidor Embedded

A utilização de bancos de dados relacionais sempre dificultou a geração de softwares de demonstração ou catálogos em CDROM, pois o usuário teria a incômoda tarefa de instalar o servidor de banco de dados na sua máquina para poder acessá-los. O servidor Embedded resolve definitivamente esse problema trazendo um servidor Firebird completo (com todas as funcionalidades do servidor comum) em uma única DLL que pode ser distribuída junto com a aplicação. É isso mesmo! Você só precisa distribuir o seu executável juntamente com a DLL do servidor embedded e terá um servidor Firebird totalmente funcional! Note que o servidor embedded permite apenas uma conexão local de uma única aplicação por vez. Um artigo mostrando a utilização do servidor embedded, escrito por este autor, pode ser encontrado na revista ClubeDelphi 51. 

Vale lembrar que para acessar bancos de dados em mídias read-only como CDROMs é preciso anteriormente ter configurado o arquivo do banco de dados para modo “somente leitura” através do utilitário gfix e o parâmetro –mode read_only (ex: gfix –mode read_only –user SYSDBA –pas masterkey meubanco.fdb).

 

ROW_COUNT

É possível saber quantas linhas foram afetadas pela execução de um comando de DML (Data Manipulation Language) checando a variável ROW_COUNT logo após a execução do comando. Essa variável pode ser checada dentro de triggers e stored procedures.

 

NOTA

ROW_COUNT não é atualizada pela execução dos comandos (FOR) EXECUTE STATEMENT.

 

 Exemplo:

 

Update produtos set estoque = estoque + :qtde where codprod = :MeuProduto;

If (row_count = 0) then

  Exception exc_notfound ‘Não foi possível atualizar o estoque para o produto ’ || :MeuProduto;

SavePoints

SavePoints funcionam como marcas inseridas em determinados pontos durante a execução de múltiplos comandos SQL. Através dele é possível fazer um rollback parcial das operações realizadas voltando o estado do banco de dados para um determinado SavePoint. Entre os recursos listados nesse artigo, esse é o único que também está disponível no InterBase 7.x.

Os comandos disponíveis para criação e manipulação de SavePoints são:

 

·        SAVEPOINT ‘identificador’ – cria um SavePoint com o nome determinado por ‘identificador’

·        ROLLBACK TO ‘identificador’ – Desfaz as operações realizadas após a criação do savepoint determinado por ‘identificador’

·        RELEASE SAVEPOINT [ONLY] ‘identificador’ – Apaga o SavePoint especificado e todos os SavePoints criados depois dele caso ONLY não seja utilizado.

 

Para não quebrar a atomicidade dos comandos executados, os SavePoints no Firebird não estão disponíveis em Stored Procedures e Triggers, pois elas possuem um mecanismo interno onde todos os comandos (ou bloco de comandos – begin...end) executados são associados automaticamente a savepoints internos.

Através de blocos de tratamento de exceções (when...do), pode-se controlar quais operações serão desfeitas dentro de uma Stored Procedure ou Trigger. Na Listagem 9 vemos um exemplo de utilização de SavePoints durante a execução de um script SQL:

 

Insert into tabela1 (campoA) values (1);

Commit;

Insert into tabela1 (campoA) values (2);

SavePoint ‘SP1’;

Insert into tabela1 (campoA) values (3);

SavePoint ‘SP2’;

Select count(*) from tabela1 -- Retornará 3

Delete from tabela1;

 

Select count(*) from tabela1 -- Retornará 0

 

RollBack to ‘SP2’; -- Desfaz o DELETE

Select count(*) from tabela1 -- Retornará 3

 

RollBack to ‘SP1’; -- Desfaz a inserção do valor 3

Select count(*) from tabela1 -- Retornará 2

 

RollBack; -- Desfaz a inserção do valor 2;

Select count(*) from tabela1 -- Retornará 1

Listagem 9. Utilização de SavePoints

Outros aprimoramentos

·        Cachê de conexão com o BD de segurança – Agora o Firebird SuperServer estabelece a conexão com o banco de dados de segurança (security.fdb) durante a primeira conexão com o servidor e a mantém aberta enquanto houver uma conexão ativa, agilizando o processo de abertura de novas conexões clientes.

·        Aumento do número máximo de índices por tabela – O limite passou de 64 para 256 índices por tabela.

·        Tráfego de VARCHARs “magros” – Com o uso da fbclient.dll do Firebird 1.5, as informações de campos do tipo VARCHAR trafegam pela rede sem preenchimento desnecessário. Até a versão 1.0 a requisição de um campo definido como VARCHAR(100) trafegaria pelo menos 100 bytes pela rede, mesmo que o valor armazenado no campo não ocupasse todo o espaço definido.

·        API de serviços parcialmente disponível na versão Classic para Linux – A API de serviços para backup, restores e validação do banco de dados está disponível na versão CS para Linux. Os serviços de estatísticas e log do servidor ainda não estão disponíveis nessa versão.

·        BIGINT – Novo tipo de dado que representa um Inteiro de 64 bits.

·        Recreate View – Permite criar ou recriar uma view caso ela já exista.

·        Create or Alter [stored procedure/trigger] – Cria ou altera uma stored procedure ou trigger caso já exista, mantendo as dependências e permissões existentes.

·        Definição de comentários – Comentários de final de linha podem ser definidos utilizando-se -- ao invés de /* ... */.

·        Inicialização de variáveis – Agora é possível inicializar variáveis durante a sua declaração (ex: declare variable contador = 0;).

·        Blocos vazios – Blocos Begin...End que não possuem comandos em seu corpo agora podem ser compilados sem gerar erro.

·        Current_Connection e Current_Transaction – Retornam os identificadores (valor do tipo inteiro) da conexão e transação atual.

O que podemos esperar para o futuro

Por incrível que pareça, enquanto os últimos ajustes estavam sendo feitos para o lançamento da versão 1.5, alguns desenvolvedores já trabalhavam na versão 2.0 do Firebird!

Dois fatores contribuirão para que a versão 2.0 esteja ainda mais recheada de novidades:

 

1)      Jim Starkey – o criador do InterBase – foi contratado pela IBPhoenix para desenvolver uma versão derivada do Firebird (atualmente chamada de Vulcan) para rodar em processadores 64bits com suporte total à multi-thread. A boa notícia é que o Vulcan também é Open Source e terá muitas das suas mudanças incorporadas ao código fonte do Firebird!

2)      Junção do código do Yaffil – O Yaffil era um banco de dados comercial derivado do Firebird 1.0 e desenvolvido por russos. Há alguns meses foi anunciada a junção do código do Yaffil ao Firebird, ou seja, os novos recursos implementados no Yaffil serão portados para o Firebird. Antes que me perguntem: Sim! O Firebird continuará gratuito e Open Source!

 

Aliado a esses dois fatores, podemos esperar novidades muito interessantes para a próxima versão:

·        Funções SQL;

·        Select from Select;

·        Backups incrementais;

·        Monitoramento de queries e conexões;

·        Novo sistema de segurança e gerenciamento de usuários;

·        Novo algoritmo para árvore de índices (otimizando pesquisas e garbage collection);

·        Novo protocolo local de conexão (XNET);

·        Suporte completo a multi-thread e SMP;

·        Suporte explícito a cursores SQL dentro de Stored Procedures e Triggers;

 

Conclusão

Nesse artigo foi demonstrado as inovações mais importantes acrescentadas ao Firebird 1.5. É importante que todos leiam o Release Notes que acompanha o FB para ficarem cientes de todos os detalhes dessas implementações, bem como características de instalação, etc.

Aos que ainda não utilizam o Firebird como servidor de dados, espero que eu tenha conseguido despertar sua curiosidade a ponto de fazê-lo baixar e testar o servidor! O download pode ser feito no site oficial do firebird (www.firebirdsql.org). Lembre-se, é de graça! e garanto que ficará muito satisfeito com o que vai encontrar pela frente.

 

Referências:

·        Release Notes do Firebird 1.5

·        How to lock a record in InterBase/Firebird (http://www.interbase-world.com/en/articles/detail.php?ID=805&phrase_id=10765)

·        Lista de discussão Firebird-Devel (www.firebirdsql.com)

·        Firefox - A New Brand of Browser (http://www.firebirdsql.org/index.php?action=view_item&topic=1076405361)

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados