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).