Em cozinhas de código, normalmente passo algum tempo com as configurações da base de dados, especialmente com as configurações de Compatibilidade. Muitas vezes certas definições não seguem as melhores práticas e durante as discussões com o desenvolvedor da aplicação, ouço “oh, nunca as mudei” ou “não tenho a certeza sobre o impacto, por isso é melhor não as tocar”.
Uma vez que poderiam ter um impacto drástico no desempenho ou comportamento das suas aplicações, iniciámos uma série de posts em blogues para discutir algumas destas configurações “secretas“.
Parte 1 de definições de compatibilidade – QUERY BY FORMULA
Estes ajustes forçam o 4D a comportar-se como na versão 2004, reduzindo o conjunto de características e o desempenho. E é tão fácil de alterar, mas os clientes têm medo de efeitos secundários desconhecidos.
QUERY BY FORMULA foi bastante lento em v2004 (porque todos os registos foram transferidos para o cliente), sem muito valor acrescentado. Como resultado, a maioria dos programadores ignoraram-no. As regras foram alteradas com a v11.
O comando QBF (apenas para o manter curto neste post do blogue) permite utilizar cálculos como a procura de tamanho de imagem ou comprimento de texto. Os benefícios desta funcionalidade são bastante óbvios. Contudo, cálculos como este não podem utilizar um índice, pelo que são mais lentos do que uma consulta indexada.
Mas o comando QBF pode fazer muito mais! Pode combinar grupos de consulta com parênteses: ((campo1=1) e (campo2=”A”)) OU ((campo1=50) e (campo2=”B”)).
Não usar o comando QBF significa executar duas consultas e usar conjuntos, resultando em muito mais tráfego na rede, mais dependência do desempenho da rede, e mais carga para o Servidor 4D. O optimizador de consultas do Servidor 4D detecta automaticamente a melhor (mais rápida) forma de lidar com tais condições em campos da mesma tabela – ou mesmo tabelas relacionadas.
E o melhor de tudo, ele pode construir relações por si só (também conhecido como joinins), mesmo que nenhuma ligação seja desenhada em modo de estrutura. Sim, pode construir relações de forma dinâmica para executar consultas (se a opção “QUERY BY FORMULA Uses SQL Joins” estiver activada).
A opção “QUERY BY BY FORMULA Uses SQL Joins” pode ser confusa porque não está de todo relacionada com SQL, deve pensar nela mais como “QBF suporta relações dinâmicas”.
Vamos usar uma estrutura simples como exemplo:
Ambos QUERY e QUERY BY FORMULA poderia ser usado para pesquisar usando uma relação, como por exemplo:
QUERY BY FORMULA([Table_2];[Table_1]Field_2="1")
Mas apenas QBF permite definir explicitamente a relação (permitindo a utilização de qualquer relação possível), em vez de exigir que já exista uma relação definida. Agora imaginemos que existe uma segunda ligação lógica entre estas duas tabelas, mas que não existe já como relação 4D … Campo3 com Campo2. QBY permite especificar a relação em tempo real:
QUERY BY FORMULA([Table_2]; ([Table_1]ID=$var)& \
([Table_1]Field_2=[Table_2]Field_3))
Nota: Ao utilizar uniões dinâmicas, deve comparar dois campos de tabelas diferentes. Se parte de uma consulta, esta é automaticamente tratada como uma união, para definir uma relação.
Se quiser pesquisar um valor noutra tabela, deve primeiro atribuí-lo a uma variável local. Isto define claramente que pretende utilizá-la como constante.
A activação da opção “QUERY BY FORMULA UTILIZAÇÕES SQL” é obrigatória para permitir que o “novo” editor de consultas(ou seja, o editor de consultas introduzido com a v14) utilize relações. A razão é simples, utiliza o editor de consultas QUERY BY FORMULA comandar internamente.
Resumo:
- QUERY BY FORMULA permite utilizar parênteses para expressar condições de consulta complexas, enquanto QUERY só permite múltiplas OU ou múltiplas E condições, mas não uma combinação de ambas.
- QUERY BY FORMULA suportes de adesão e consultas dinâmicas.
- QUERY BY FORMULA permite a utilização de fórmulas, tais como o tamanho da imagem.
- QUERY BY FORMULA é executado no servidor (semelhante a um normal QUERY), proporcionando a mesma ou até melhor velocidade porque gera menos tráfego na rede em comparação com uma combinação de QUERY e definir operações.
Nota: tudo o que foi dito acima é verdade para a linguagem clássica 4D. O código baseado em ORDAé sempre executado no servidor.
Trabalho de migração necessário para permitir a compatibilidade
As configurações acima só são visíveis no diálogo de Compatibilidade para estruturas criadas com 4D v2004 ou mais antigas. Se não vir estas configurações, a sua estrutura é mais recente e comporta-se sempre no modo v11, por isso está pronto a partir!
Use a opção Procurar no modo de desenho para procurar por QUERY BY FORMULA. Uma vez que a sua estrutura está no modo “lento” v2004, a lista deve ser curta. Faça duplo clique em cada resultado e verifique o código.
Desde que a fórmula utilize constantes, como por exemplo:
QUERY BY FORMULA([Table_2];[Table_1]Field_2="1")
Ou
QUERY BY FORMULA([Table_2];[Table_1]Field_2=$var)
// similar for var or <>var
Tudo está bem, não há nada a fazer. 4D Remote interpretará a variável e enviará o seu conteúdo para o servidor (semelhante a uma constante). O valor do cliente é sempre utilizado, mesmo que a consulta seja executada pelo servidor.
Se a fórmula for um método, como por exemplo:
QUERY BY FORMULA([Table_2];RunQuery)
É necessário abrir e verificar o conteúdo do método. Se os parâmetros forem passados para o método, há grandes probabilidades de que o método seja genérico (mas ainda assim deve verificar). Se nenhum parâmetro for passado, há grandes probabilidades de que falhe.
Imagine que o RunQuery contém:
$0:= ([Table_2]=myvar)
O conteúdo de myvar será diferente no Servidor 4D Remoto e 4D Servidor, pelo que a execução deste método no Servidor 4D falhará. Retornará resultados diferentes.
Há duas maneiras de resolver esta questão. Para consultas simples como as acima mencionadas, poderia simplesmente reescrevê-lo como RunQuery(myvar) e dentro do método usar $1. Problema resolvido.
Mas poderá encontrar um método realmente complexo. Milhares de linhas de código, sem documentação, escritas há 20 anos. E usado apenas uma vez por ano. É muito trabalho e risco de erros, para um impacto mínimo. Para resolver o problema, pode optar por executar este código apenas no modo v2004, mantendo tudo o resto no modo moderno:
SET DATABASE PARAMETER(Query by formula on server;1)
QUERY BY FORMULA ([Table_2];RunQuery )
SET DATABASE PARAMETER (
Query by formula on server;0)
SET DATABASE PARAMETER permite mudar o modo na mosca, evitando a necessidade de passar horas em código raramente utilizado.
Finalmente, deve verificar se os campos são utilizados de uma forma que prejudique a funcionalidade de junção. Com v2004 uma fórmula como [Table_1]Field_2=[Table_2]Field_3 é interpretada como pesquisa de conteúdo estático/fixo, utilizando o conteúdo de Field_3. Depois de activar a opção “QUERY BY FORMULA Uses SQL Joins”, esta é interpretada como um join.
Portanto, é necessário verificar cada QBF para ver se utiliza um nome de campo no lado direito de um operador “=”. Se sim, atribua-o a uma variável local e utilize a variável local na consulta.
Depois de ter verificado todas as ocorrências de QUERY BY FORMULAestá pronto para activar ambas as opções.
Desfrute de uma pesquisa rápida…