
SENTENCIA SELECT...ENDSELE
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.
Clausula FOR ALL ENTRIES; Nos permite obtener todos los registros de una tabla de BBDD, cargandola en una tabla
interna.
NOTA: Con la Instrucción FOR ALL ENTRIES hay que tener sumo cuidado en la manera en que se va a usar, primero se debe asegurar que la tabla driver con la se va a comparar no se encuentre vacia, pues si es así, traería toda la data que esté en la base de datos, perjudicando el performance del programa, y segundo, si la tabla interna tiene muchos registros, el select a la Base de Datos sería mucha mas lento pues si utilizaría mucha memoria.