Usina BRGuía AdvPL
Ingresar
← Todos los temas
FUNDAMENTOPublicado

Embedded SQL en AdvPL

BeginSql Alias <cAlias> ... EndSql

Escribe consultas SQL legibles directamente en el código AdvPL usando sustituciones del precompilador, filtros de sucursal y eliminación lógica y conversión declarativa de tipos.

SQLEmbedded SQLDBAccessTopConnQueryBase de datosBeginSqlEndSql
01 · DESCRIPCIÓN GENERAL

Descripción general

Embedded SQL permite escribir el SELECT directamente entre BeginSql y EndSql. Durante la compilación y ejecución, expresiones especiales delimitadas por % se transforman para integrar la consulta con Protheus y DBAccess. Entre los recursos documentados están %table, %xfilial, %exp, %notDel, %Order, column ... as Date/Logic/Numeric y %noparser%. De forma predeterminada la consulta pasa por ChangeQuery(); el alias abierto debe cerrarse al finalizar el procesamiento.

02 · SINTAXIS

Sintaxis

BeginSql Alias <cAlias> ... EndSql

Parámetros

%table:ALIAS%
SustituciónOpcional

Resuelve el nombre físico de la tabla Protheus correspondiente al alias indicado.

%xfilial:ALIAS%
SustituciónOpcional

Resuelve la sucursal actual adecuada para la tabla indicada.

%exp:expresión%
ExpresiónOpcional

Inserta en la consulta el valor de una variable o expresión AdvPL compatible.

%notDel%
SustituciónOpcional

Genera la condición de eliminación lógica basada en D_E_L_E_T_.

%Order:ALIAS%
SustituciónOpcional

Convierte una expresión de índice AdvPL a sintaxis SQL de ordenación.

column <campo> as <tipo>
ConversiónOpcional

Declara campos Date, Logic o Numeric del resultado para convertirlos a tipos AdvPL.

%noparser%
ControlOpcional

Impide que la consulta pase por ChangeQuery() antes de enviarse a la base de datos. Úsalo solo cuando exista un motivo técnico claro.

Retorno

Abre el cursor de la consulta en el alias indicado en BeginSql. El result set debe recorrerse como una WorkArea de consulta y cerrarse con DbCloseArea() cuando ya no sea necesario.

03 · EJEMPLO PRÁCTICO

Consulta básica con tabla, sucursal y eliminación lógica

#Include "TOTVS.ch"

User Function ExEmbedded()
    Local cAlias  := GetNextAlias()
    Local cCodigo := "000001"

    // Embedded SQL evita concatenar fragmentos de texto para construir el SELECT.
    // A1_COD significa “Código”, A1_NOME significa “Nombre” y A1_FILIAL significa “Sucursal”.
    BeginSql Alias cAlias
        SELECT A1_COD, A1_NOME
          FROM %table:SA1% SA1
         WHERE A1_FILIAL = %xfilial:SA1%
           AND A1_COD    = %exp:cCodigo%
           AND SA1.%notDel%
    EndSql

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

    // El cursor abierto por BeginSql debe cerrarse al finalizar el proceso.
    (cAlias)->(DbCloseArea())
Return
Resultado esperado

La consulta resuelve la tabla física, la sucursal, el valor del código y la eliminación lógica sin construir manualmente una cadena SQL.

04 · EJEMPLO PRÁCTICO

Conversión declarativa de campo de fecha

#Include "TOTVS.ch"

User Function ExEmbeddedFecha()
    Local cAlias   := GetNextAlias()
    Local cPrefijo := "NF"

    // E2_EMISSAO significa “Fecha de emisión”, E2_PREFIXO significa “Prefijo”,
    // E2_NUM significa “Número” y E2_FILIAL significa “Sucursal”.
    BeginSql Alias cAlias
        column E2_EMISSAO as Date
        SELECT E2_PREFIXO, E2_NUM, E2_EMISSAO
          FROM %table:SE2% SE2
         WHERE E2_FILIAL  = %xfilial:SE2%
           AND E2_PREFIXO = %exp:cPrefijo%
           AND SE2.%notDel%
    EndSql

    While !(cAlias)->(Eof())
        // E2_EMISSAO ya se expone como un valor de fecha AdvPL.
        ConOut((cAlias)->E2_PREFIXO + " - " + DToC((cAlias)->E2_EMISSAO))
        (cAlias)->(DbSkip())
    EndDo

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

La declaración column sustituye el tratamiento manual posterior del tipo de campo retornado.

05 · EJEMPLO PRÁCTICO

Inspección de la consulta ejecutada con GetLastQuery()

#Include "TOTVS.ch"

User Function ExLastQuery()
    Local cAlias := GetNextAlias()
    Local aInfo  := {}

    // A1_COD significa “Código”, A1_NOME significa “Nombre” y A1_FILIAL significa “Sucursal”.
    BeginSql Alias cAlias
        SELECT A1_COD, A1_NOME
          FROM %table:SA1% SA1
         WHERE A1_FILIAL = %xfilial:SA1%
           AND SA1.%notDel%
    EndSql

    // GetLastQuery() proporciona información sobre la consulta que realmente se abrió.
    aInfo := GetLastQuery()
    ConOut(aInfo[2]) // SQL ejecutado

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

GetLastQuery()[2] permite observar la cadena SQL ejecutada; el retorno completo también incluye alias, conversiones, indicador del parser y tiempo de apertura del cursor.

BUENAS PRÁCTICAS
  • Usa %table:ALIAS% en lugar de fijar el nombre físico de la tabla en el SQL.
  • Usa %xfilial:ALIAS% y %notDel% cuando la consulta requiera filtros de sucursal actual y eliminación lógica.
  • Usa %exp:variable% para insertar valores AdvPL en Embedded SQL y evita concatenar cadenas cuando la sintaxis embedded ya cubra el caso.
  • Declara con column los campos del resultado que deban convertirse a Date, Logic o Numeric.
  • Cierra siempre el alias abierto por BeginSql al finalizar el procesamiento.
  • Usa GetLastQuery() después de abrir el cursor cuando necesites inspeccionar la consulta ejecutada y el tiempo de apertura.
  • Cuando la consulta o los valores de sustitución deban contener el carácter ?, evalúa FWPreparedStatement/FWExecStatement según la recomendación oficial.
ERRORES COMUNES
  • No coloques funciones directamente dentro del bloque Embedded SQL cuando la sintaxis requiera una expresión calculada previamente; guarda el valor en una variable antes de BeginSql.
  • El carácter ? está reservado por el procesamiento de Embedded SQL y puede causar comportamientos no conformes si aparece en la consulta o en los valores sustituidos.
  • No uses %noparser% únicamente por conveniencia; desactiva el procesamiento estándar de ChangeQuery().
  • Los breakpoints dentro del bloque BeginSql/EndSql no se comportan como puntos de parada AdvPL comunes; colócalos antes o después del bloque.
  • Si la compilación informa un error en EndSql, revisa también la indentación, espacios y tabulaciones anteriores a la instrucción según la documentación del entorno utilizado.
  • Usar un alias que ya está abierto puede provocar un error de ejecución.

Contenido relacionado

REFERENCIAS
  1. TOTVS. Embedded SQL — Framework. TDN.
  2. TOTVS. Desarrollo de queries en Protheus — Framework. TDN.
  3. TOTVS. FWPreparedStatement — Framework. TDN.
  4. TOTVS. FWExecStatement — Framework. TDN.
Estado
Publicado
Página creada el
Última revisión el
Idioma original
Portugués
Revisión
Usina.BR
0 comentario(s) aprobado(s)

Comentarios

Todavía no hay comentarios aprobados.

Inicia sesión con Google o Microsoft para comentar.

Desarrollado con Usina Docs · Alpha