
El acceso a la base de datos es el factor número uno que define si un programa ABAP vuela o se arrastra. Como programador experto, tu objetivo principal siempre debe ser delegar el trabajo pesado al motor de la base de datos y minimizar el tráfico de red entre este y el servidor de aplicaciones.
En el mundo moderno de SAP (especialmente con bases de datos in-memory como HANA), el paradigma es "Code-to-Data": envía la lógica a los datos, no los datos a la lógica.
A continuación, desglosamos las prácticas que debes erradicar y las que debes adoptar en tu día a día.
Las Peores Prácticas (Anti-patrones de Rendimiento)
1. El pecado capital: SELECT dentro de un LOOP
Esta es la forma más rápida de destruir el rendimiento de un sistema SAP. Si tu tabla interna tiene 10,000 registros, ejecutarás 10,000 consultas individuales a la base de datos, saturando la red (conocido como el problema N+1).
ABAP
" TERRIBLE PRÁCTICA (¡Nunca hagas esto!)
LOOP AT lt_pedidos INTO DATA(ls_pedido).
" Un viaje a la base de datos por cada iteración del bucle
SELECT SINGLE name1
FROM kna1
INTO @DATA(lv_nombre)
WHERE kunnr = @ls_pedido-kunnr.
ENDLOOP.
2. Traer datos de más con SELECT *
Tablas estándar como MARA o VBAK tienen cientos de columnas. Si usas * cuando solo necesitas un par de campos, estás desperdiciando ancho de banda de red y llenando la memoria RAM del servidor de aplicaciones con basura.
ABAP
" MALA PRÁCTICA
SELECT *
FROM vbak
INTO TABLE @DATA(lt_pedidos_completos)
WHERE erdat = @sy-datum.
3. Filtrar datos en el servidor de aplicaciones
Extraer miles de registros de la base de datos para luego descartarlos manualmente con sentencias IF o CHECK dentro de la memoria de ABAP.
ABAP
" MALA PRÁCTICA (SELECT ... ENDSELECT es obsoleto y lento)
SELECT matnr, mtart, ersda
FROM mara
INTO @DATA(ls_mara).
" Filtrando en el lado del servidor ABAP en lugar de usar el WHERE
CHECK ls_mara-ersda > '20240101'.
APPEND ls_mara TO lt_materiales.
ENDSELECT.
Las Mejores Prácticas (El Enfoque Senior)
1. Lectura en bloque (Array Fetch) y restricción de columnas
Pide única y exclusivamente los campos que vas a procesar. Además, extrae los datos de un solo golpe directamente a una tabla interna usando INTO TABLE, evitando bucles de comunicación.
ABAP
" BUENA PRÁCTICA
SELECT matnr, mtart
FROM mara
INTO TABLE @DATA(lt_materiales)
WHERE mtart = 'FERT'
AND ersda > '20240101'. " El filtro se hace en la base de datos
2. Cruce de datos masivos (FOR ALL ENTRIES vs JOIN)
Cuando necesitas cruzar datos que ya tienes en una tabla interna con otra tabla de la base de datos, debes usar extracciones en bloque.
Opción A: Usando FOR ALL ENTRIES (Útil cuando los datos de origen no vienen de la base de datos).
ABAP
" BUENA PRÁCTICA
" 1. REGLA DE ORO: ¡Siempre verifica que la tabla no esté vacía primero!
IF lt_pedidos IS NOT INITIAL.
" Extraemos todos los clientes asociados de un solo golpe
SELECT kunnr, name1
FROM kna1
INTO TABLE @DATA(lt_clientes)
FOR ALL ENTRIES IN @lt_pedidos
WHERE kunnr = @lt_pedidos-kunnr.
ENDIF.
Opción B: Usando JOIN (El preferido si todo viene de la base de datos).
ABAP
" EXCELENTE PRÁCTICA
" Cruza las tablas directamente en el motor de base de datos
SELECT v~vbeln, v~kunnr, k~name1
FROM vbak AS v
INNER JOIN kna1 AS k
ON v~kunnr = k~kunnr
INTO TABLE @DATA(lt_pedidos_clientes)
WHERE v~vkorg = '1000'.
3. Delegar cálculos matemáticos a la Base de Datos
Si necesitas sumar, contar, encontrar el máximo o calcular promedios, no bajes los registros a una tabla interna para iterarlos. Usa funciones de agregación (SUM, COUNT, MAX, MIN, AVG).
ABAP
" EXCELENTE PRÁCTICA
" Que la base de datos sume y agrupe; nosotros solo recibimos el resultado final
SELECT vkorg, SUM( netwr ) AS total_ventas
FROM vbak
INTO TABLE @DATA(lt_resumen_ventas)
WHERE erdat = @sy-datum
GROUP BY vkorg.