Usina BRAdvPL Guia
Entrar
← Todos os tópicos
FUNDAMENTOPublicado

Desenvolvendo queries no Protheus

cQuery → ChangeQuery() → TCQUERY / TCGenQry() → WorkArea → DbCloseArea()

Estruture consultas SQL portáveis e eficientes no Protheus com DBAccess, aliases dinâmicos e tratamento correto do result set.

SQLDBAccessTopConnQueryPerformanceBanco de dados
01 · VISÃO GERAL

Visão geral

O DBAccess conecta o Protheus aos bancos SQL homologados e permite acesso ISAM ou SQL nativo. Para conjuntos de dados, uma query bem construída normalmente reduz varreduras, processamento no cliente e tráfego de rede. No Protheus, a consulta pode ser montada como string ou escrita em Embedded SQL; os dois modelos chegam ao DBAccess. O desenvolvimento deve considerar nomes físicos, filial, exclusão lógica, portabilidade, tipos retornados e encerramento da área de trabalho.

02 · SINTAXE

Sintaxe

cQuery → ChangeQuery() → TCQUERY / TCGenQry() → WorkArea → DbCloseArea()

Parâmetros

GetNextAlias()
FunçãoObrigatório

Gera um alias temporário para o result set e evita colisões, inclusive em chamadas recursivas.

RetSqlName()
FunçãoObrigatório

Converte o alias lógico do Protheus no nome físico da tabela usado no FROM ou JOIN.

ChangeQuery()
FunçãoObrigatório

Adapta a sintaxe SQL aos bancos homologados. A referência recomenda seu uso, salvo casos especiais devidamente controlados.

TcSetField()
FunçãoOpcional

Ajusta campos não caractere do result set aos tipos AdvPL esperados, quando necessário.

SqlOrder()
FunçãoOpcional

Converte uma expressão de chave AdvPL em expressão SQL para ORDER BY.

xFilial()
FunçãoOpcional

Fornece a filial correta da tabela para o filtro SQL.

DToS()
FunçãoOpcional

Produz AAAAMMDD para comparações de datas conforme o armazenamento adotado pelo Protheus.

03 · EXEMPLO PRÁTICO

Consulta básica portável

#Include "TOTVS.ch"
#Include "TopConn.ch"

User Function ExQueryClientes()
    Local cAlias := GetNextAlias()
    Local cQuery := ""

    cQuery := "SELECT A1_COD, A1_LOJA, A1_NOME "
    cQuery += "FROM " + RetSqlName("SA1") + " SA1 "
    cQuery += "WHERE SA1.A1_FILIAL = '" + xFilial("SA1") + "' "
    cQuery += "AND SA1.D_E_L_E_T_ = ' ' "
    cQuery += "ORDER BY A1_COD, A1_LOJA"
    cQuery := ChangeQuery(cQuery)

    TCQUERY (cQuery) ALIAS (cAlias) NEW
    While !(cAlias)->(Eof())
        ConOut((cAlias)->A1_COD + " - " + (cAlias)->A1_NOME)
        (cAlias)->(DbSkip())
    EndDo
    (cAlias)->(DbCloseArea())
Return
Resultado esperado

A consulta usa nome físico, filial da própria tabela, filtro de exclusão lógica, compatibilidade entre bancos, alias dinâmico e fechamento explícito.

04 · EXEMPLO PRÁTICO

Query de Recno para posicionar a tabela real

cQuery := "SELECT R_E_C_N_O_ RECNO "
cQuery += "FROM " + RetSqlName("SA1") + " SA1 "
cQuery += "WHERE A1_FILIAL = '" + xFilial("SA1") + "' "
cQuery += "AND D_E_L_E_T_ = ' '"
cQuery := ChangeQuery(cQuery)

TCQUERY (cQuery) ALIAS (cAlias) NEW
While !(cAlias)->(Eof())
    SA1->(DbGoTo((cAlias)->RECNO))
    // Leia ou trate o registro real já posicionado.
    (cAlias)->(DbSkip())
EndDo
(cAlias)->(DbCloseArea())
Resultado esperado

O result set identifica rapidamente os registros e DbGoTo() posiciona a tabela física pela chave primária R_E_C_N_O_.

BOAS PRÁTICAS
  • Selecione apenas as colunas necessárias; evite SELECT * para reduzir tráfego e acoplamento.
  • Use GetNextAlias() em vez de um alias fixo.
  • Obtenha os nomes físicos com RetSqlName() e passe a consulta por ChangeQuery().
  • Filtre cada campo de filial com xFilial() da própria tabela; não compare indiscriminadamente filiais de tabelas diferentes.
  • Exclua registros apagados logicamente com D_E_L_E_T_ = espaço em cada tabela participante.
  • Prefira JOIN em sintaxe ANSI e aplique os filtros da tabela associada no local coerente com o tipo de JOIN.
  • Use agregações como COUNT, SUM, MAX e MIN para reduzir linhas retornadas quando o resultado desejado for consolidado.
  • Feche obrigatoriamente a WorkArea com DbCloseArea() ao terminar.
  • O desempenho de uma query depende do conjunto formado pelo código AdvPL, DBAccess, SGBD, infraestrutura e volume de dados. Meça consultas lentas e consumo de recursos antes de alterar índices ou ampliar hardware.
  • Planos de execução, índices, estatísticas, fragmentação e Page Split ajudam a explicar gargalos no SQL Server. Essas análises pertencem à administração do banco e devem ser feitas com evidências do ambiente.
  • Índices personalizados precisam ser documentados e novamente verificados após atualizações do Protheus, pois mudanças estruturais podem removê-los ou torná-los inadequados.
  • Arquivamento e expurgo podem reduzir o volume operacional, mas dependem de regras de negócio, obrigações legais, política de retenção, cópia de segurança e possibilidade de recuperação.
  • A compressão de dados pode reduzir armazenamento e leitura de páginas, porém consome CPU e depende dos recursos da versão e edição do SQL Server. Avalie por teste e monitore o resultado.
  • A tabela física pode variar conforme o grupo de empresas e o compartilhamento configurado. Por isso, use RetSqlName() para obter seu nome e xFilial() para aplicar o contexto correto, sem deduzir sufixos manualmente.
  • A estrutura persistida é governada pelo dicionário de dados do Protheus. Campos, tabelas e índices criados diretamente no SGBD podem causar divergências em atualizações ou na abertura de rotinas; alterações estruturais devem seguir os mecanismos suportados pela TOTVS.
  • Campos de controle como R_E_C_N_O_ e D_E_L_E_T_ fazem parte da persistência administrada pelo DBAccess. Consultas precisam respeitar a exclusão lógica, mas não devem assumir que toda característica física histórica continua idêntica em qualquer release.
  • Em estruturas tradicionais, datas do dicionário são frequentemente armazenadas como caracteres AAAAMMDD e valores vazios podem ser representados por espaços ou zero em vez de NULL. Confirme o tipo real e converta o result set com TcSetField() quando necessário.
  • Índices personalizados devem considerar todos os jogos físicos de tabelas aplicáveis ao ambiente, ser documentados e alinhados com o dicionário e com a equipe responsável pelas atualizações.
ARMADILHAS COMUNS
  • R_E_C_N_O_, D_E_L_E_T_ e R_E_C_D_E_L_ são campos de controle do DBAccess; não trate exclusão lógica como exclusão física.
  • Um result set de query normalmente avança para frente; não presuma a mesma navegação de uma tabela ISAM.
  • SQL específico de SQL Server, Oracle ou outro SGBD pode falhar nos demais bancos homologados.
  • Em funções de agregação, campos não agregados precisam ser compatíveis com a cláusula GROUP BY.
  • A query de Recno é útil quando é necessário posicionar a tabela real para alterar ou excluir, mas adiciona uma etapa e não deve ser usada sem necessidade.
  • Não concatene entrada não confiável diretamente no SQL. Valide rigorosamente os valores e use mecanismos seguros disponíveis.
  • Não desabilite nem remova índices padrão do Protheus sem orientação formal da TOTVS, análise de um DBA, homologação e plano de reversão.
  • Não aplique FILLFACTOR, reconstrução de índices ou alterações de estatísticas de forma global. Uma configuração útil para uma tabela pode prejudicar outra.
  • As recomendações do artigo são baseadas em experiência prática com SQL Server e em um contexto histórico do Protheus; não são documentação oficial da TOTVS nem se transferem automaticamente para outros bancos ou versões.
  • Não derive o nome físico de uma tabela pela empresa ou filial. Regras de compartilhamento mudam a estrutura disponível; RetSqlName() e xFilial() evitam pressupostos frágeis.
  • Não crie campos, tabelas, constraints ou índices diretamente no banco sem avaliar o dicionário, o configurador, a compatibilidade com o DBAccess e o processo oficial de atualização.
  • Particionamento, compressão, replicação, cluster e recursos In-Memory dependem do SGBD, da versão do Protheus/DBAccess e da homologação vigente. As limitações descritas em 2012 não devem ser tratadas como estado atual do produto.

Conteúdos relacionados

REFERÊNCIAS
  1. TOTVS. Desenvolvendo queries no Protheus. TDN. Criado por Sergio Luis de Alcantara Silveira; última alteração indicada em 17 fev. 2017.
  2. TOTVS. Embedded SQL. TDN; última alteração indicada em 17 set. 2024.
  3. TOTVS. Comando TCQUERY. TDN.
  4. LIMA, Fabrício. 5 motivos para quem utiliza o Protheus (TOTVS) contratar um DBA SQL Server. Blog, publicado em 14 dez. 2013, com atualizações posteriores. Referência complementar de experiência prática; não é documentação oficial da TOTVS.
  5. INOWE, Marcel. Dicas sobre o banco de dados do Protheus (TOTVS). 4SQLServer, 12 set. 2012. Referência histórica e prática sobre SQL Server; os comentários da própria publicação registram correções e mudanças de versões posteriores.
  6. MICROSIGA. Manual de Programação. Documento colaborativo, arquivo datado de 11 jul. 2001. Referência histórica.
Situação
Publicado
Página criada em
Última revisão em
Idioma original
Português
Revisão
Usina.BR