Define um filtro de visualização do alias corrente.
Sintaxe
DBSetFilter( < bCond >, < cCond > )
Parâmetros
Nome | Tipo | Descrição | Obrigatório | Referência |
---|---|---|---|---|
bCond | bloco de código | Bloco de código AdvPL avaliado para determinar a visibilidade dos registros. | X | |
cCond | caractere | Condição de filtro expressada no bloco de código como string. | X |
Retorno
Nome | Tipo | Descrição |
---|---|---|
uRet | nil | Retorno sempre é nulo. |
Observações
A expressão de filtro fornecida para a função deve retornar verdadeiro (.T.) caso o registro atual da tabela atenda à condição de filtro, caso contrário deve retornar falso (.F.). A expressão de filtro deve ser um bloco de código (bCondicao), e a equivalente condição em string (cCondicao), e ambas sendo fornecidas, elas devem expressar a mesma condição.
A função DBSetFilter() é chamada internamente a partir do comando SET FILTER TO <cExp>. A utilização deste comando recebe a expressão AdvPL de filtro, e na pré-compilação do código-fonte AdvPL, realiza a chamada explícita da função DBSetFilter() com o bloco de código montado a partir da condição informada. A utilização do comando SET FILTER TO torna a codificação mais simples e legível, mesmo que internamente o resultado seja o mesmo.
Ao aplicar um filtro em uma tabela aberta, esta passa a se comportar como se contivesse apenas os registros que atendem a condição de filtro especificada. A maior parte das funções que movem o ponteiro de registro atual respeita o filtro atualmente setado, exceto os comandos que trabalham com o número físico do registro (RECNO). Isto inclui a instrução DBGoTo() e comandos onde é especificada a cláusula RECORD.
Observações e Comportamento
- Ao executar a instrução DBSetFilter(), o ponteiro de registro atual não é reposicionado. Isto significa que o filtro não se torna ativo a menos que o ponteiro de registro seja movido em alguma direção. Normalmente utilizamos DBGoTop() para ativar o filtro, onde o ponteiro de registro será posicionado no primeiro registro logicamente válido dentro da expressão de filtro atual na ordem em uso.
- A expressão de filtro não é obrigatoriamente executada em um momento especifico e/ou em um ou vários registros. Sua execução é dinâmica, quando da determinação de visibilidade lógica de registros nas operações de posicionamento da RDD.
- O contexto de execução (EVAL) da expressão de filtro está atrelado ao alias filtrado, que será implicitamente setado como alias corrente durante a avaliação da condição de filtro.
- Caso a expressão de filtro utilize informações externas ao alias atual, como campos de outras tabelas, os efeitos são imprevisíveis.
- Caso a expressão de filtro realize alguma alteração de status no alias atual, como por exemplo trocar o conteúdo de algum campo, os efeitos são imprevisíveis.
Performance e tráfego de registros
O contexto de execução de filtros AdvPL em sua origem é independente de RDD, e por se tratar de um comportamento da linguagem, a expressão de filtro é avaliada pelo servidor de aplicação (TOTVS | Application Server), na execução das instruções de movimentação de ponteiro de registro. Quando utilizada uma arquitetura client/server de banco de dados (como por exemplo ADS Server, c-tree Server , TOPConnect, TOTVS | DBAccess), isto torna necessária a leitura dos registros no banco de dados e o tráfego dos registros para a avaliação da expressão de filtro no TOTVS | Application Server, onde está sendo executado o programa AdvPL que definiu o filtro.
A linguagem AdvPL possui otimizações para atender a determinadas condições de filtro, onde o filtro é aplicado total ou parcialmente diretamente na aplicação servidora de banco de dados, sendo mais eficiente, performático e eliminando o overhead de rede gerado pelo tráfego de registros. Em linhas gerais, tabelas utilizando uma RDD com componentes client/server (ADS Server, c-tree Server e/ou TOTVS | DBAccess) executam a expressão de filtro na íntegra diretamente na aplicação servidora de banco, desde que o filtro não faça uso de nenhuma função da linguagem AdvPL, mesmo que função básica e/ou nativa da linguagem, e utilize apenas os operadores binários > (maior), >= (maior ou igual), < (menor), <= (menor ou igual), <> ou != (diferente) e = (igual), e expressões lógicas com os operadores .AND., .OR. e/ou .NOT., e devem preferencialmente utilizar na condição de filtro campos da tabela que façam parte da ordem de índice em uso no momento.
As características e pré-requisitos do comportamento de filtros executados diretamente na aplicação servidora de bancos de dados, e suporte a operadores e funções nativas para execução de filtro diretamente no banco são abortadas dentro dos tópicos de comportamentos específicos de acordo com a RDD e aplicação servidora de banco utilizada.
Filtros em tabelas utilizando ADS Server e/ou c-tree Server
Ambos os engines suportam o uso de funções básicas da linguagem AdvPL na montagem da expressão de filtro, e executam de modo nativo o filtro na aplicação servidora. Funções como AllTrim(), DToS(), Left(), Right(), operador $ (contido em), Str(), StrZero() e afins são tratadas diretamente pelo ADS Server e/ou c-tree Server. Englobam os acessos realizados através das seguintes RDDs sob as seguintes condições:
- RDD DBFCDX - em ambiente configurado com LocalFiles=CTREE, utilizando um c-tree Server para controle dos dicionários.
- RDD DBFCDXAX - em ambiente configurado para base de dados principal com ADS Server e repositório ADS (RpoDb=ADS).
- RDD CTREECDX - em ambiente configurado para base de dados principal com c-tree Server e repositório c-tree (RPODB=CTREE).
Filtros em tabelas utilizando TOTVS | DBAccess
Através do TOTVS | DBAccess, criamos e acessamos tabelas em bancos de dados relacionais usando a RDD TOPCONN, em diversos bancos de dados homologados. As funcionalidades estendidas de filtro, como suporte a algumas funções básicas da linguagem AdvPL foram implementadas no TOTVS | DBAccess de forma diferenciada para cada banco de dados, de acordo com os recursos disponíveis nos bancos, capazes de prover ou emular o comportamento original de um filtro AdvPL.
Quando setada uma expressão de filtro em uma tabela acessada pela RDD TOPCONN, através de um programa AdvPL, caso existam comparações suportadas e não suportadas na mesma expressão, o TOTVS | DBAccess faz uma redução do filtro, tentando aproveitar todas as partes da expressão suportadas, para filtrar o que for possível através das queries de busca de dados do TOTVS | DBAccess, e minimizar tráfego de rede e recuperação desnecessária de registros. Qualquer condição não suportada pelo TOTVS | DBAccess e enviada a ele resultará em uma comparação sempre verdadeira considerando o primeiro campo da tabela (no ERP, em geral é o campo _FILIAL).
Observe, a seguir, o suporte para funções AdvPL em filtro implementado no TOTVS | DBAccess:
Funções AdvPL/Banco | Microsoft SQL | Oracle</div> | IBM DB2</div> | Informix</div> | Sybase</div> | PostgreSQL</div> | MySQL</div> |
---|---|---|---|---|---|---|---|
$ (operador) | SIM | SIM | SIM | SIM | SIM | SIM | SIM |
AllTrim() | SIM | SIM | SIM | SIM | NÃO | NÃO | NÃO |
ASC() | SIM | SIM | SIM | NÃO | NÃO | NÃO | NÃO |
CHR() | SIM | SIM | NÃO | NÃO | NÃO | NÃO | NÃO |
DToS (cpo) | SIM | SIM | SIM | SIM | SIM | SIM | SIM |
Empty() | SIM | SIM | SIM | SIM | NÃO | SIM | NÃO |
Left() | SIM | SIM | SIM | NÃO | NÃO | NÃO | NÃO |
Len() | NÃO | SIM | SIM | SIM | NÃO | NÃO | NÃO |
Lower() | SIM | SIM | SIM | SIM | NÃO | SIM | NÃO |
Right() | SIM | NÃO | SIM | NÃO | NÃO | NÃO | NÃO |
Space() | SIM | SIM | SIM | NÃO | NÃO | NÃO | NÃO |
StrTran() | SIM | SIM | SIM | SIM | NÃO | SIM | NÃO |
SubStr(s,n,n) | SIM | SIM | SIM | SIM | SIM | SIM | SIM |
Upper() | SIM | SIM | SIM | SIM | NÃO | SIM | NÃO |
As únicas funcionalidades suportadas de modo nativo ao aplicar um filtro AdvPL em todos os bancos de dados são: DToS (campo) -> Onde a expressão é removida, pois o TOTVS | DBAccess grava um campo “D” Data do AdvPL no banco como string, no formato “AAAAMMDD”, SubStr(campo ,nStart ,nLen) , e o operador $ (contido em expressão string). Quaisquer outras funções utilizadas em uma condição de filtro serão avaliadas no servidor de aplicação (TOTVS | Application Server).
Exemplos
function insert() Local cT1 := "T1" Local idx := 0 Local name := "" Local tp := "" Local age := "2" DBUseArea(.F., 'TOPCONN', cT1, (cT1), .F., .F.) WHILE (idx <= 5) name += "BA" tp += "T" age += "2" (cT1)->( DBAppend( .F. ) ) (cT1)->FIELD_NAME := name (cT1)->FIELD_TYPE := tp (cT1)->FIELD_AGE := age (cT1)->( DBCommit() ) idx++ ENDDO DBCloseArea() return function example() local cT1 := "T1" TCLink() DBCreate("T1", {{"FIELD_NAME", "C", 10, 0}, ; {"FIELD_TYPE", "C", 10, 0}, ; {"FIELD_AGE", "C", 10, 0}, ; {"FIELD_NICK", "C", 10, 0}, ; {"FIELD_COL", "C", 10, 0}}, "TOPCONN") U_insert() DBUseArea(.F., 'TOPCONN', cT1, (cT1), .F., .T.) (cT1)->(DbSetFilter( { || Left( FIELD_NAME, 4 ) = "BABA" }, 'Left(FIELD_NAME, 4) = "BABA"' ) ) (cT1)->(DBGoTop()) IF ((cT1)->FIELD_AGE == "222 ") conout("Found!") ENDIF DBCloseArea() TCUnlink() return