Usina BRAdvPL Guia
Entrar
← Todos os tópicos
FUNDAMENTOPublicado

Embedded SQL em AdvPL

BeginSql Alias cAlias ... EndSql

Escreva consultas SQL legíveis diretamente no fonte AdvPL, usando substituições do pré-compilador e conversão declarativa de tipos.

SQLEmbedded SQLDBAccessTopConnQueryBanco de dados
01 · VISÃO GERAL

Visão geral

Embedded SQL evita a concatenação manual de uma consulta em várias strings. O bloco entre BeginSql e EndSql é processado pelo pré-compilador AdvPL: trechos comuns seguem literalmente para a consulta e expressões delimitadas por porcentagens são transformadas em nomes físicos, filtros, valores e ordens compatíveis com o Protheus. A execução abre um cursor no alias informado e, por padrão, a consulta passa automaticamente por ChangeQuery().

02 · SINTAXE

Sintaxe

BeginSql Alias cAlias ... EndSql

Parâmetros

BeginSql Alias
ComandoObrigatório

Inicia o bloco e define o alias do cursor. O alias não pode estar aberto; prefira um valor obtido com GetNextAlias().

column ... as Date | Logical | Numeric
DeclaraçãoOpcional

Declara conversões de campos do resultado. O pré-compilador gera o tratamento equivalente a TcSetField().

%table:ALIAS%
SubstituiçãoOpcional

Resolve o nome físico da tabela por meio de RetSqlName().

%xfilial:ALIAS%
SubstituiçãoOpcional

Insere o valor de filial adequado à tabela informada.

%notDel%
SubstituiçãoOpcional

Gera o filtro de registro não excluído para D_E_L_E_T_. Deve estar associado ao alias SQL correto.

%exp:expressão%
SubstituiçãoOpcional

Avalia variável ou expressão AdvPL em tempo de execução e a converte para uso na consulta. Aceita valores caractere, data, numérico ou lógico.

%Order:ALIAS,nOrdem%
SubstituiçãoOpcional

Converte a expressão da ordem AdvPL em uma cláusula SQL por meio de SqlOrder().

%temp-table:cNome%
SubstituiçãoOpcional

Insere na consulta o nome de uma tabela temporária armazenado em variável.

%noparser%
ModificadorOpcional

Impede a passagem automática por ChangeQuery(). Use somente quando a perda de portabilidade for intencional e comprovada.

EndSql
ComandoObrigatório

Finaliza o bloco e dispara a abertura do cursor. Em ambientes antigos pode precisar estar alinhado à esquerda.

03 · EXEMPLO PRÁTICO

Consulta de clientes com conversões do Protheus

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

User Function ExEmbeddedSql()
    Local cAlias := GetNextAlias()
    Local cNome  := "CLIENTE TESTE"

BeginSql Alias cAlias
    SELECT A1_COD,
           A1_LOJA,
           A1_NOME
      FROM %table:SA1% SA1
     WHERE A1_FILIAL = %xfilial:SA1%
       AND A1_NOME = %exp:cNome%
       AND SA1.%notDel%
     ORDER BY %Order:SA1,1%
EndSql

    While !(cAlias)->(Eof())
        ConOut((cAlias)->A1_COD + " - " + (cAlias)->A1_NOME)
        (cAlias)->(DbSkip())
    EndDo

    (cAlias)->(DbCloseArea())
Return
Resultado esperado

O pré-compilador resolve tabela, filial, valor, exclusão lógica e ordem; o cursor é percorrido para frente e fechado explicitamente.

04 · EXEMPLO PRÁTICO

Conversão declarativa e diagnóstico

Local cAlias := GetNextAlias()
Local aInfo  := {}

BeginSql Alias cAlias
    column E2_EMISSAO as Date
    column E2_VALOR as Numeric(16, 2)
    SELECT E2_EMISSAO, E2_VALOR
      FROM %table:SE2% SE2
     WHERE E2_FILIAL = %xfilial:SE2%
       AND SE2.%notDel%
EndSql

aInfo := GetLastQuery()
ConOut("Tempo de abertura: " + cValToChar(aInfo[5]))
(cAlias)->(DbCloseArea())
Resultado esperado

Os campos chegam como data e número; GetLastQuery() informa a consulta efetivamente executada e o tempo de abertura do cursor.

BOAS PRÁTICAS
  • Mantenha uma cláusula WHERE, mesmo quando inicialmente for WHERE 1 = 1. O processamento de acesso por empresa, unidade e filial pode acrescentar filtros; sem WHERE, consultas com GROUP BY podem falhar.
  • Declare com column os campos de data, lógico e numérico que precisem chegar ao AdvPL com o tipo correto.
  • O suporte a campos memo depende de versões compatíveis da LIB e do DBAccess; a documentação registra suporte a partir das builds indicadas pela TOTVS.
  • Use GetLastQuery() após abrir o cursor para inspecionar alias, SQL executado, conversões, uso do parser e tempo de abertura.
  • Breakpoints dentro de BeginSql e EndSql não são considerados. Depure antes ou depois do bloco e consulte GetLastQuery() quando precisar examinar o SQL gerado.
  • O recurso exige RPO de ambiente DBAccess e LIB compatível. O erro NOFUNCW para __EXECSQL indica incompatibilidade ou ausência da função interna no ambiente.
ARMADILHAS COMUNS
  • Não chame uma função diretamente no meio do bloco quando ela precisar participar da montagem. Calcule antes, guarde em variável e use %exp:variável%.
  • Não coloque * como primeiro caractere de uma linha: o pré-compilador pode interpretá-lo como comentário AdvPL. Em SELECT *, mantenha o asterisco na mesma linha da instrução.
  • O caractere ? é reservado durante o processamento do Embedded SQL. Se a consulta ou os valores precisarem dele, avalie FWPreparedStatement ou FWExecStatement conforme a documentação oficial.
  • Um alias já aberto provoca Query Argument Error. Gere o alias dinamicamente e encerre o cursor com DbCloseArea().
  • %exp:% aceita apenas caractere, data, numérico ou lógico. Arrays e outros tipos provocam erro de argumento.
  • Evite %noparser% por conveniência: ele desativa ChangeQuery() e pode vincular o código a um único SGBD.

Conteúdos relacionados

REFERÊNCIAS
  1. TOTVS. Embedded SQL. TDN. Criado por Danilo Basilio Medeiros; última alteração indicada em 17 set. 2024.
  2. TOTVS. Desenvolvendo queries no Protheus. TDN.
  3. TOTVS. FWPreparedStatement. TDN.
  4. TOTVS. FWExecStatement. TDN.
  5. 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