Si ya hemos
-
Realizado la declaración de datos.
-
Generado nuestra pantalla de selección.
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.
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 :-)
Gracias por el aporte
ResponderEliminarMuy buen articulo. Gracias
ResponderEliminar