Para recuperar o leer la base de datos de SAP se utiliza la sentencia SELECT, su sintaxis varia mucho en comparación al SQL estándar. Por lo que cubriremos varios ejemplos y explicaremos las diferencias.

Uno de las principales diferencias es que al ejecutar la sentencia SELECT se debe definir en que variable de ABAP se depositan los datos leídos, estas variables se deben de declarar con un tipo de datos compatibles con el tipo de datos del campo a leer.

Lectura de una sola fila

La clausula SINGLE es requerida y equivale a limit 1 en mysql o top 1 en MS SQL Server, luego la instrucción INTO se usa para indicar que en la siguiente variable se deposite el valor de la tabla.

"Declaramos la variable
data: material type matnr. 

SELECT SINGLE matnr 
INTO material 
FROM mara 
WHERE matnr = 'AAAA'.

Para leer un solo registro pero más de un campo a la vez debemos separar la lista de campos por espacios en blanco después de SELECT SINGLE y colocar entre paréntesis y separadas por comas la lista de variables en las que se cargaran los valores recuperados.

data: material type matnr, 
      tipo type mtart. 

SELECT SINGLE matnr mtart 
INTO (material, tipo) 
FROM mara 
WHERE matnr = 'AAAA'.

Es importante no dejar espacios en blanco entre los paréntesis y la primera variable, de lo contrario se generaría un error al activar el programa.

SELECT SINGLE matnr mtart 
INTO ( material, tipo) "Genera un error por el espacio entre "(" y "material," 
FROM mara 
WHERE matnr = 'AAAA'.

Después de ejecutar una sentencia SELECT, la variable de sistema SY-SUBRC tendrá un 0 (Cero) si al menos una fila fue recuperada y tendrá un 4 (Cuatro) si no se encontró ningún dato con el criterio definido en la clausula WHERE. Podemos utilizar esta variable para controlar si nuestra lectura fue exitosa.

La variable de sistema SY-DBCNT almacena la cantidad de registros recuperados.

DATA: material TYPE matnr.
SELECT SINGLE matnr
INTO material
FROM mara
WHERE matnr = 'AAAA'.

IF SY-SUBRC = 0.
  WRITE: / 'Se encontraron ', sy-dbcnt, ' registros'.
ELSE.
  WRITE: / 'No se encontraron datos'.
ENDIF.

Leer varias filas de una vez

Para leer más de un registro de la base de datos es necesario definir antes una tabla interna para almacenar los datos recuperados.

"Declarar una tabla interna, con header line
DATA: it_mara LIKE STANDARD TABLE OF mara WITH HEADER LINE.
"Leer los datos y depositarlos en la tabla temporal
SELECT matnr mtart
INTO CORRESPONDING FIELDS OF TABLE it_mara
FROM mara
WHERE matnr = '00001'.

Leer datos uniendo dos o más tablas

Existen dos formas para hacer esto, la primera es con la clausula INNER JOIN y la segunda es con FOR ALL ENTRIES. Primero vamos a ver como se hace utilizando FOR ALL ENTRIES.

"Declarar una estructura para leer la primera tabla
DATA: BEGIN OF it_mara OCCURS 0,
 matnr TYPE matnr,
 labst TYPE labst,
END OF it_mara.

"Declarar una tabla interna para leer la segunda tabla (tambien pudo ser una estructura con header line)
DATA: IT_EXISTENCIAS LIKE TABLE OF IT_MARA WITH HEADER LINE.
DATA: CANT_LINEAS TYPE I.

"Leer la primera tabla
SELECT MATNR
INTO CORRESPONDING FIELDS OF TABLE IT_MARA
FROM MARA
WHERE MTART = '0001'.

"Verificar si la tabla interna tiene registros
DESCRIBE TABLE IT_MARA LINES CANT_LINEAS.
IF CANT_LINEAS > 0.
  "Leer los registros de la segunda tabla, siempre y cuando coincidan con la primera tabla, esto se logra
  "utilizando FORM ALL ENTRIES y la clausula WHERE que compara cada valor en la tabla interna
  SELECT MATNR LABST
  INTO TABLE IT_EXISTENCIAS
  FROM MARD
  FOR ALL ENTRIES IN IT_MARA
  WHERE MATNR = IT_MARA-MATNR.
ENDIF.

ADVERTENCIA: Si se utiliza FOR ALL ENTRIES con una tabla interna vacía, SAP recupera la segunda tabla con todos los registros existentes, para el ejemplo anterior si no revisamos que la tabla interna IT_MARA contenga lineas y si la tabla MARD tiene 1,000,000 de registros, SAP leerá 1,000,000 de registros ignorando por completo la clausula WHERE, lo que puede llevar a problemas de rendimiento en nuestro programa Z.

Para leer datos de más de una tabla utilizando INNER JOIN:

"Declaramos una estructura con header line
DATA: BEGIN OF it_mara OCCURS 0, 
 matnr TYPE matnr, 
 labst TYPE labst, 
END OF it_mara. 

SELECT m~matnr e~labst 
INTO TABLE it_mara 
FROM mara AS m INNER JOIN mard AS e ON m~matnr = e~matnr 
WHERE e~MTART = '0001'.

Como se puede apreciar en el código, al utilizar más de una tabla debemos referirnos a los campos de la forma TABLA~CAMPO, donde tabla es el nombre de la tabla o el alias asignado y el símbolo ~ se usa para separar el nombre de la tabla y el nombre del campo. Después de la clausula ON se define la relación para unir las tablas.

ADVERTENCIA: Los datos no se guardan siempre de la forma que se visualizan, en este caso, SAP nos muestra que el código del cliente es “1”, pero al dar doble clic sobre la línea en la transacción se16n vemos que el código del cliente se guarda como “00000001”, al hacer una lectura debemos utilizar el código tal como se guarda (00000001) en lugar de como lo vemos (1).

exit-conversion