Tutorial ABAP básico (IV): recuperar datos

lunes, 14 de enero de 2013

Tutorial ABAP básico (IV): recuperar datos

Si ya hemos
El siguiente paso es recuperar los datos que vamos a mostrar en nuestro listado y guardarlos en el tiempo que dure la ejecución de nuestro programa. Para ello será muy importante tener claros dos conceptos, el de tablas internas y el funcionamiento de la sentencia SELECT.

Tablas internas

Ya habíamos comentado que las tablas internas sirven para almacenar información extraída de la base de datos. En este ejemplo voy a utilizar una tabla interna que ya habíamos declarado previamente.
* Tabla de vuelos DATA: BEGIN OF i_vuelos OCCURS 0, carrid LIKE sflight-carrid, "Código de aerolínea connid LIKE sflight-connid, "Número de vuelo fldate LIKE sflight-fldate, "Fecha de vuelo planetype LIKE sflight-planetype, "Tipo de avión END OF i_vuelos.

La sentencia select...endselect

Esta sentencia realiza una lectura lineal de los datos de las tablas de la base de datos y los asigna directamente a los campos de nuestra tabla interna. Pero atención, para que queden almacenados sobre la tabla interna para cada registro seleccionado debemos utilizar la sentencia APPEND. Así, haremos añadiremos los registros a nuestra tabla interna.
SELECT * FROM sflight WHERE carrid IN s_carrid. i_vuelos-carrid = sflight-carrid. i_vuelos-connid = sflight-connid. i_vuelos-fldate = sflight-fldate. i_vuelos-planetype = sflight-planetype. APPEND i_vuelos. CLEAR i_vuelos. ENDSELECT.
  • El símbolo (*) le indica a SAP que debe guardar en memoria absolutamente todos los valores de todos los campos de cada registro de la tabla SAP.
  • La cláusula WHERE nos permite indicar el filtro de selección. En este caso utilizamos como filtro el rango de códigos de aerolíneas. De la tabla sflight sólo recuperaremos aquellos registros que cumplan con la condición indicada en el WHERE.
  • Seguidamente asignamos a cada campo de la tabla interna el valor del campo de la tabla SAP, dejándolo a nivel de la cabecera de la tabla interna.
  • Finalmente, guardamos el registro en nuesta tabla interna mediante la sentencia APPEND.
    Con la sentencia CLEAR limpiamos la cabecera y la dejamos lista para el siguiente registro.

La sentencia SELECT...ENDSELECT irá pasando uno a uno por cada uno de los registros que cumplan la condición de la cláusula WHERE y los irá almacenando gracias a la sentencia APPEND dentro de nuestra tabla interna.

El mayor inconveniente de trabajar con la forma SELECT...ENDSELECT es que la lectura se hace linealmente, es decir, SAP debe pasar por cada uno de los registros individualmente hasta llegar al final. Esto hace que la búsqueda de datos sea muy ineficiente en términos de rendimiento y alarga innecesariamente el tiempo de ejecución del programa.

Una forma de mejorar el rendimiento sería no utilizar la cláusula (*) sino indicar específicamente los campos que necesitamos llenar.
SELECT carrid connid fldate planetype FROM sflight INTO (i_vuelos-carrid, i_vuelos-connid, i_vuelos-fldate, i_vuelos-planetype) WHERE carrid IN s_carrid. APPEND i_vuelos. CLEAR i_vuelos. ENDSELECT.
Al no usar todos los campos mejoramos el rendimiento y con la cláusulo INTO asignamos directamente el valor al campo de la tabla interna.

Otra forma de sentencia select.

Existe otra forma de la sentencia SELECT mucho más eficiente nos permite almacenar los datos en la tabla interna sin necesidad de utilizar la sentencia APPEND. El mismo efecto que en el caso anterior lo obtendríamos usando...
SELECT * FROM sflight INTO CORRESPONDING FIELDS OF TABLE i_vuelos WHERE carrid IN s_carrid.
  • Seguimos utilizando el valor (*) para leer todos los campos.
  • La claúsula INTO CORRESPONDING FIELDS OF TABLE compara el nombre del campo de la tabla de SAP con cada nombre de la tabla interna. Si encuentra coincidencia le asigna su valor correspondiente. Por eso, es tan importante que el nombre de los campos de una tabla interna sean iguales al nombre de los campos de una tabla SAP. De lo contrario, esta forma no se puede utilizar.
    Se mantiene la cláusula WHERE.
  • Se elimina la sentencia APPEND ya que la lectura deja de ser secuencial sino en bloques. Es decir, SAP ya no tiene que recorrer uno a uno todos los registros, sino que toma el bloque de registros que coinciden con la condición determinada a través de la cláusula WHERE y lo asigna en bloque a la tabla interna.

Y aún, otra variación que podemos utilizar sería:
SELECT carrid connid fldate planetype FROM sflight INTO TABLE i_vuelos WHERE carrid IN s_carrid.
Esta forma es todavía más eficiente ya que:
  • Evita el uso de (*) y en su lugar sólo toma el valor de los campos que nos interesa (carrid, connid, fldate y planetype).
  • La cláusula INTO TABLE asigna estos cuatro campos a los cuatro primeros campos de la tabla interna. Así que, cuidado, el orden en que se hayan declarado estos campos en la tabla interna es importante. Aquí no hay asignación por nombre de campo, sino por posición, el valor del campo carrid de la tabla sflight se asignará al primer campo de la tabla interna, el valor del campo connid de la tabla sflight se asignará al segundo campo de la tabla interna, y así sucesivamente. Aquí ya no es tan importante el nombre de los campos de la tabla interna, pero sí la longitud y el tipo de esos campos. Si no lo tenemos cuenta nuestro programa acabar abruptamente con dump breve.

La sentencia select para recuperar registros individualmente.

Finalmente, otra forma que se utiliza mucho, es la sentencia SELECT SINGLE.
SELECT SINGLE * FROM sflight WHERE connid = p_connid.
Se utiliza si lo que nos interesa es únicamente un registro de nuestra tabla de base de datos. En en el ejemplo, me interesa un número de vuelo en concreto y utilizo la sentencia SELECT con la cláusula SINGLE. Es muy habitual que después de escribir esta sentencia se escriba una condición del tipo IF sy-subrc ... ENDIF.
SELECT SINGLE * FROM sflight WHERE connid = p_connid. IF sy-subrc = 0. i_vuelos-connid = sflight-connid. APPEND i_vuelos. CLEAR i_vuelos. ENDIF.
El campo sy-subrc es un campo de sistema y si el resultado es 0 significa que la sentencia que se ha ejecutado anteriormente lo ha hecho de forma satisfactoria. Si el valor, en cambio, fuese 4 o cualquier otro, entonces hemos de suponer que dentro de la tabla sflight no existe ningún registro que confirme la condición dada en la cláusula WHERE.

Por supuesto, podemos hacer esta sentencia un poco más eficiente de la siguiente forma:
SELECT SINGLE connid FROM sflight INTO i_vuelos-connid WHERE connid = p_connid. APPEND i_vuelos. CLEAR i_vuelos.

Haciendo joining de tablas

Ésta es ya una forma más avanzada de búsqueda de información en dos o más tablas de una base de datos que nos permite guardar los datos en una sola tabla interna con criterios de selección complejos. Como esto no es más que una introducción al lenguaje ABAP sólo la voy a mencionar. Si queréis obtener información de su manejo podéis acudir a la sentencia ABAPHELP y pedir ayuda por el keyword inner join.

Por cierto, todo lo que se explica en este artículo se refiere a ABAP SQL. Ya sabéis que SAP admite también SQL nativo, aunque no lo recomienda, ni yo lo explico en este artículo.

En el próximo artículo, el último de esta serie, hablaremos de cómo presentar los datos por pantalla.

Imagen inicial | CEThompson


Si crees que este artículo es útil ayúdame a compartirlo a través de alguno de los botones sociales :-)

2 comentarios: