Quando uma transação no banco de dados exigir uma avaliação de registros já existentes no banco para decidir se o que precisa fazer é um UPDATE ou um INSERT em geral exige no mínimo duas chamadas para o banco de dados… uma para fazer o SELECT (toma decisão sobre o comando a aplicar) e então envia outra chamada com um UPDATE ou com um INSERT;

Para otimizar estes passos é possível utilizar “MERGE” ou “UPDATE OR INSERT”. Quando o desejo é passar os dados de uma tabela para outro o MERGE pode ser o mais adequado para a operação, mas se deseja atualizar os dados com entradas de parâmetros, sem vincular a uma tabela, o mais adequado será usar o comando “UPDATE OR INSERT”.

 

  1. Usando MERGE para fazer INSERT OR UPDATE com um único comando com base em uma tabela

O comando MERGE permite submeter uma única chamada para o banco de dados, quando as condições “where” coinciderem executa um UPDATE se não coincidirem executa um INSERT;

Exemplo da documentação:

[code language=”sql”]
MERGE INTO customers c 
USING    (SELECT * FROM customers_delta WHERE id > 10) cd    
ON (c.id = cd.id) 
WHEN MATCHED THEN   
UPDATE SET name = cd.name 
WHEN NOT MATCHED THEN   
INSERT (id, name)    VALUES (cd.id, cd.name)
[/code]
No Firebird3, é possível utilizar DELETE também – ou seja, agora é possível utilizar UPDATE,INSERT ou DELETE;

No exemplo, para que funcione, há uma premissa básica que faz parte do MERGE… é obrigatório que “customers_delta” tenha pelo menos 1 linha… Se o resultado de “customers_delta” for nenhuma linha, NADA será feito (nem UPDATE nem INSERT)…
De outro lado, existindo pelo menos 1 linha em customers_delta, ocorrerá a comparação ON (c.id = cd.id)…  em encontrando o mesmo código “WHEN MATCHED” será executado o UPDATE… caso não encontre o código será efetuado o INSERT (WHEN NOT MATCHED)…

 

Avançando um pouco mais… digamos que queremos avaliar uma única tabela… assim:   procurar se no cadastro de produto existe um determinado código…. caso exista UPDATE, caso não exista INSERT…

Para que funcione, lembra da premissa básica – o SELECT de USING, é obrigatório retornar pelo menos 1 linha. Quando o código procurado existir, o UPDATE será executado com sucesso, mas…..   se não existir o código, o USING SELECT  quebra a premissa básica (não existe a linha) – com isto o INSERT não funciona.

Vamos fazer uma adaptação para que o MERGE funcione usando RDB$DATABASE (o que o deixa igual ao UPDATE OR INSERT)

Exemplo:
[code language=”sql”]
MERGE INTO fb_prod c
USING
(SELECT ‘999999’ codigo, ‘nome do produto’ nome FROM rdb$database) cd
ON (c.codigo = cd.codigo)
WHEN MATCHED THEN
UPDATE SET nome = cd.nome
WHEN NOT MATCHED THEN
INSERT (codigo, nome,id) VALUES (cd.codigo, cd.nome,1)
[/code]

2. Usando UPDATE OR INSERT :

Ao usar UPDATE OR INSERT não é necessário vincular o comando a uma tabela associada o que torna o comando mais flexível em relação ao MERGE… veja um exemplo de como fazer:
[code language=”sql”]
UPDATE OR INSERT INTO fb_prod (codigo, nome, id)
values (‘999998’, ‘nome usando update or insert’, 2)
MATCHING (codigo)

[/code]

Em resumo, cada situação há várias formas de fazer a mesma coisa… escolha a que for mais eficiente

No Firebird 3 passou a ser possível criar exception com parâmetros que adicionam texto à mensagem retornada para o usuário.

create exception e_invalid_val ‘Valor invalido @1  para a coluna @2’;


if (val < 1000) then
thing = val;
else

exception e_invalid_val using (val, ‘thing’);
end

 

Este recurso na prática não adiciona nenhum ganho, já que no 2.5 era possível adicionar um texto à exceção..

Exception erro ‘Valor invalido ‘||val||’ para a coluna xxxx’;

 

 

Quando um arquivo é gravado no disco, mesmo tendo 1 único byte, o disco aloca um espaço mínimo de 1 cluster ( o mais comum é 1 cluster = 4096 bytes);

Existem HDs que gravam número de bytes diferente para 1 cluster, dependendo do modelo e fabricante; Para saber qual o tamanho de 1 cluster no disco basta escrever uma arquivo TXT com 1 byte de conteúdo, ir na propriedade do arquivo (via explorer) e checar qual o tamanho em disco……

O que fazer com esta informação ?

O banco de dados firebird usa gravar os dados em páginas; Cada página tem uma quantidade de bytes que é gravado juntamento com o FDB conhecido como “Page size”. Se uma pagina for de 8192, por exemplo, e 1 cluster no HD for de 4096, significa que para cada página que o banco for gravar ele vai precisar de 2 clusters físicos no disco.  Mesmo quando 1 página tiver um número muito pequeno de bytes a serem gravados, mesmo assim, o HD vai utilizar 2 cluster.

Não é difícil imaginar que o FDB vai ficar bem grande, com muitos buracos vazios. Para adequar este comportamento, o tamanho do “Page Size” deve ser o mesmo tamanho de 1 cluster no HD, destar forma o comportamento do banco de dados será o mesmo que aquele que o HD que esta instalado.

Para alterar o “Page size” é necessário alterar o parâmetro durante o RESTORE do banco de dados incluindo a opção: F:4096 ( quando o HD usar cluster de 4096 );

Exemplo:

gbak -rep -F 4096 meubackup.fbk meubanco.fdb -user sysdba -pass masterkey

 

 

Depois de fazer uma leitura rápida da documentação do novo RC – partindo para instalação.

Instalei a versão WIN64 em uma máquina que já tinha tanto 3.0 RC1 quanto 2.5 rodando na 3051 (3) e o outro na 3050 (2.5).

No primeiro passo o instalador reclamou que já tinha uma instalação. Parei o serviço, apaguei a pasta do 3.0 para fazer uma instalação limpa. Ele reclama que já existe a pasta do 2.5, mas não há risco em continuar pois instala em uma sub-pasta diferente do 2.5

Durante o processo ele deixa escolher como vai rodar – se serviço ou app, bem como o tipo de instalação – escolhi SuperClassic (novo modo de funcionamento); No passo seguinte pergunta qual será o usuário administrador e senha – importante neste ponto, já que ao contrário do 2.5 ele não vem com o admin configurado e precisa fazer isto na instalação – neste momento informei o admin que todos já conhecem, em produção seria interessante definir um outro admin para fugir do padão conhecido por todos.

Concluído a instalação com tranquilidade, abri o “firebird.conf” para configurar a porta, já que vou continuar usando o 2.5 junto com o 3.0 – editei e alterei:  RemoteServicePort = 3051

No passo seguinte subi o serviço e vamos abrir um banco que já tinha rodando com 3.0 – primeiro instante não consegui logar, depois de alguns testes notei que agora o nome do usuário é sensível a maiúsculo e minúsculo, depois disto… foi… (revisão: o comportamento ocorreu usando o IBExpert (2016.12) – só aceitou maiúsculo – configurando direto no aplicativo delphi, funcionou tanto minúsculo como maúsculo – mensagem enviada pelo Cantú pelo facebook/firebird)

Caso escolha rodar como aplicativo (não serviço) 
é possível iniciar usando o comando:
<strong>       firebird -m -a</strong>

Como passar o 2.5 para 3.0:

Nas compilações anteriores foi preciso fazer backup do banco de produção usando o 2.5 e depois restaurar com o 3.0; Esta ação esta ligado a mudança de estrutura do banco assumindo nova versão no 3.0, creio que não será possível copiar direto;

Antes não era possível fazer backup usando o 3.0 de um banco do 2.5, não refiz o teste para verificar se esta restrição continua. Então naquela ocasião foi obrigatório fazer o backup do banco no 2.5  antes de instalar o 3.0;

Vamos para o IBExpert:

Aqui passei pelo necessidade de reconfigurar a FBClient.dll que no 3.0 não é compatível com a do 2.5, ou seja, precisei indicar para o IBExpert qual a DLL iria utilizar – usei a que vem na pasta WOW64 – não funcionou, ainda não chequei porque… peguei a FBClient.dll que já tinha da RC1 – foi… (revisando: fiz novos teste e a FBClient que esta no disco de instalação do RC2, funcionou)

Na RC1 não era possível usar a FBClient.dll da 3.0 para acessar a 2.5 – o contrário também não era possível… (revisão: novos testes mostraram que a FBClient que vem no disco da RC2 agora é compatível com 2.5 também, ou seja, pode utilizar a mesma DLL tanto para acesso ao 3.0 quanto para o 2.5)

 

Entramos, agora RC2 rodando.

 

O Firebird 3 mudou algumas coisas em relação a forma de funcionamento do servidor;

Agora temos as seguintes possibilidades de instalação:

  1. Server – funciona com um único processo e compartilha “page cache” interno ao processo. (instalação padrão);
  2. SuperClassic – funciona em thread por conexão rodando com um único processo. As threads são iniciadas no processo principal e cada thread tem seu próprio “page cache”;
  3. Classic – MultiProcess, cada conexão é executada em um processo separado. Cada processo seu próprio controle “page cache”;

O modo Classic e Server possuem características paralelo ao que já tínhamos no 2.5x,  a novidade é o SuperClassic que mescla os dois outros processos, ou seja, funcionam em Thread compartilhadas e cada um mantem o seu “page cache” isolado;

Ná prática este novo modelo poderá se mostrar mais eficiente para isolamento e otimização de hardware, vamos aos teste para ver o resultado.