Ayuda SAP

Consulta ABAP mejor practica para obtener datos

En los pequeños cursos que tuvimos la obtención de datos era en base a estructuras y se guardaban en workareas.
a mi en lo particular me llamaron la atención cuando vieron que estaba haciendo uso de “join”.

Leyendo en la web, el join tiene el inconveniente del manejador de base de datos y la compatibilidad de la transformación vaya lo que entienda ABAP al transformar al manejador.

Entonces mi pregunta es: 100% de acuerdo en no usar join y que opción a la convencional existe.

Gracias.

3 Me gusta

Me auto contesto con la lectura de estos temas:

1.- Aprendí que no se puede hacer join en tablas cluster

2.- En el tema

Encuentro este post:

Continuando la discusión desde ALV Grid - Consulta sobre tabla CDPOS:

Y siguendo en el tema otros apoyan el join… ya me confundi jajajaaj.

seguire leyendo :smile:

2 Me gusta

Me declaro fanático del inner join, el único riesgo que le veo es que no se haga utilizando las llaves de las tablas, de otra forma puede haber problemas de performance. Yo siempre lo utilizo y me resuelve muchos problemas, además de que el código me parece más elegante que con un FOR ALL ENTRIES, y no se diga, evitar a toda costa un SELECT dentro de un LOOP. Es la muerte :dizzy_face:

2 Me gusta

Los @abapers son un grupo con amplios conocimientos en la materia, capaz ellos puedan darte tips sobre JOINS., mi manejo de JOINS es muy básico (en SQL).

Seguiré el tema de cerca, buen tema @Neto !
Saludos!

Hola @Neto lamento la confusion, miralo asi, el inner join es mejor para grandes extracciones de datas, pero si deseas manejar primero una parte de la data antes de pasarla a la siguiente extracion, el for all entrie resuelve, al final del dia dependera de lo que requieras hacer. Los join va a resolver la mayoria de los ambitos, asi qu epierde cuidado, y con los for all entres se debe tener precaucion de no mandar una tabla a verificar vacia, por eso siempre antes de hacer un for all entrie, debes usar la clausula check it_table[[.

Saludos @Neto,

Para la extracción de datos en SAP se utiliza un protocolo de comunicación muy parecido al SQL standard el cuál se conoce como Open Sql .

La pregunta tuya, aunque la haces en una comunidad de SAP es algo que aplica para todos los sistemas basados en datos.

##¿Cuál es la mejor forma para extraer datos?

Personalmente le imploro a todos los @abapers o aficionados a desarrollar en SAP o en cualquier plataforma, que visualicen la imagen de manera un poco más global y que lean algún tutorial de como realizar consultas SQL de manera optimizada. Cuando conoces cómo funcionan los gestores de base de datos, podrás hacer reportes en cualquier sistema sin sobrecargar ningún servidor.

@Neto, para obtener datos, no usas el join, lo que en realidad estás usando es el SQL con todas sus variantes, hay ocasiones en las cuales no necesitarás la sentencia JOIN ni la LEFT JOIN y apuesto a que pocos utilizan el GROUP BY.

@Neto acá te dejo unos cuantos TIPS básicos a seguir para mejorar la extracción de datos pero en la internet hay innumerables referencias :smile:

( Tips a la hora de realizar consultas )

En hora buena :muscle:

3 Me gusta

Gracias chicos por sus experiencias y conocimientos.

Me quede un poquito corto o fui muy escueto en la explicacion.

Vengo de SQ, MySQL y limitado de Oracle y Mongo, conozco the best practice al respecto tanto asi que tuvimos presencia de expertos en la materia por Microsoft cuando nos trono el servidor SQL2000 y migramos a SQL2008. Hace unos años.

Pero con este nuevo sistema SAP la programación que nos “están explicando” esta muy código lineal, todo con for all entries, select a una sola tabla y de ahi almacenar en estructuas/workareas/tablas transparentes/vaciado en variables tipo DATA.

Lo que no se es que es la mejor practica en ABAP.

La información que se maneja aqui siempre es de gran volumen, son obtener relaciones entre bp y sus objetos contratos los cuales pueden ser de 1 a N, donde cada 1 tiene N pagos, obligaciones de pago, etc.

Mi sección es la de ingresos, donde tenemos que calcular por un concepto ligas de pagos y calculos, los cuales provienen de tablas extensas por los calculos y procesos necesarios para dar la informacion final.

Sumado a esto la mayoria del tiempo nos piden reportes a quema ropa los cuales no van a poder estar en BI, extracciones de informacion maciba, etc, etc… toda una chulada estar aqui :stuck_out_tongue_closed_eyes:

Regresando al tema_____
Les mostrare pedazos de codigo

*&---------------------------------------------------------------------*
*&  Include           ZURS07_PRG5_TOP
*&---------------------------------------------------------------------*

*&---------------------------------------------------------------------*
*& Inclusion de Tablas BASE
*&---------------------------------------------------------------------*
tables:
    dfkkko,
    ZCCTT_CONCEPTOS2.

*&---------------------------------------------------------------------*
*& PARAMETROS DE ENTRADA
*&---------------------------------------------------------------------*
PARAMETERS:
  p_Test As CHECKBOX DEFAULT 'x',
  p_opbel type dfkkop-opbel.

SELECT-OPTIONS: psl_obel for dfkkko-opbel.

*&---------------------------------------------------------------------*
*& Variables Globales
*&---------------------------------------------------------------------*
data:
  gv_subrc type sy-subrc.

*&---------------------------------------------------------------------*
*& Tipos
*&---------------------------------------------------------------------*
TYPES:
  BEGIN OF ty_conceptos2,
    HVORG type ZCCTT_CONCEPTOS2-HVORG,
    TVORG type ZCCTT_CONCEPTOS2-TVORG,
    CCOBRO type ZCCTT_CONCEPTOS2-CCOBRO,
    XXXX type ZCCTT_CONCEPTOS2-XXXX,
    DESCON type ZCCTT_CONCEPTOS2-DESCON,
    DESLAR type ZCCTT_CONCEPTOS2-DESLAR,
  END OF ty_conceptos2,
    "ty_tl_conceptos2 type STANDARD TABLE OF ty_conceptos2,
  BEGIN OF ty_dfkkop,
    opbel type dfkkop-opbel,
    opupk type dfkkop-opupk,
    HVORG type dfkkop-HVORG,
    TVORG type dfkkop-TVORG,
  END OF ty_dfkkop,
  BEGIN OF ty_salida,
    opbel type dfkkop-opbel,
    opupk type dfkkop-opupk,
    HVORG type ZCCTT_CONCEPTOS2-HVORG,
    TVORG type ZCCTT_CONCEPTOS2-TVORG,
    CCOBRO type ZCCTT_CONCEPTOS2-CCOBRO,
    XXXX type ZCCTT_CONCEPTOS2-XXXX,
    DESCON type ZCCTT_CONCEPTOS2-DESCON,
    DESLAR type ZCCTT_CONCEPTOS2-DESLAR,
  END OF ty_Salida.


*&---------------------------------------------------------------------*
*& work areas o estructuras
*&---------------------------------------------------------------------*

data:
  ls_salida     type ty_salida,
  ls_conceptos2 type ty_conceptos2.

*&---------------------------------------------------------------------*
*& Tablas
*&---------------------------------------------------------------------*
data:
      lt_conceptos2 TYPE STANDARD TABLE OF ty_conceptos2 WITH UNIQUE SORTED KEY Operaciones COMPONENTS HVORG TVORG,
      lt_dfkkop type STANDARD TABLE OF ty_dfkkop,
      lt_salida type STANDARD TABLE OF ty_salida with NON-UNIQUE SORTED KEY vbarias COMPONENTS opbel opupk.


FORM f_zconceptos2
    TABLES
        p_lt_dfkkop like lt_dfkkop
        p_lt_conceptos2 like lt_conceptos2
        p_lt_salida like lt_salida
    CHANGING p_gv_subrc.

      **  loop AT p_lt_dfkkop into ls_salida.**
            **loop at p_lt_conceptos2 into ls_conceptos2 WHERE hvorg = ls_salida-hvorg AND tvorg = ls_salida-tvorg.**
          "READ TABLE p_lt_conceptos2
          "into ls_conceptos2
          "WITH KEY hvorg = p_lt_conceptos2-hvorg tvorg = p_lt_conceptos2-tvorg.

            if ls_conceptos2 is INITIAL.
              ls_salida-XXXX = 'sin relacion de datos'.
            else.
              "MOVE-CORRESPONDING p_lt_dfkkop to ls_salida.
              **MOVE-CORRESPONDING ls_conceptos2 to ls_salida.**
              APPEND ls_salida to lt_salida.
            endif.

        endloop.
        if ls_conceptos2 is INITIAL.
              ls_salida-descon = 'sin relacion de datos'.
              APPEND ls_salida to lt_salida.
        ENDIF.
        "p_gv_subrc = sy-subrc.
    ENDLOOP.
ENDFORM.      

No se si con eso me explico, este caso es pequeño, entiendo el uso de una consulta de un elemento a la perfección. se inserta en una variable de un dato, pero cuando necesitamos registros de todo un mes, año o de toda la relación de datos almacenados en donde se me hace injusto que quiera que usemos un loop y almacenar con move-CORRESPONDING, se me hace que es demasiado peso y proceso.

_____________________________Editado:
Agrego otro ejemplo balazo:
que las consultas son en varias tablas al mismo tiempo ocupamos 3 columnas de una tabla, de la otra ocupamos 20, de la otra 8 por ejemplo y con eso se saca una consulta final… tipo sql

me salto muchas practicas para ser rapido conste :see_no_evil:
select
a.dato1,a.dato2, b.dato1, b.bato…N, c.dato1, c.dato5
from a
join b on b.datox = a.datox
join c on c.datox = b.datox and c.datox2 = a.datox2
where not exists ( select xx.dato from xx where xx.datox = b.datoxx)

si hago lo mismo en ABAP pues lo hice todo bien claro y rapido (el comentario de saber usar las llaves es correcto si no uso una llabe que ya me lo tope la consulta se cuelga. Ademas que los ABAPER’s de aqui dicen que NUNCA DE LOS NUNCA debe usar una consulta asi…

_____________________________Fin Edición.

Saludos.

2 Me gusta

Hola @Neto , usar un join no esta mal si dentro del join utilicen los campos clave para linkear ambas tablas y además de eso en el where se usa de forma optima algún índice de la tabla principal, ya que lo costoso de un Select es cuando la búsqueda no usa índices. Por otro lado el código que colocas es valido, pero todo dependerá de lo que quieras obtener y mostrar, hay técnicas en ABAP para evitar los LOOP anidados por ejemplo, o hacer una tabla interna de tipo hash para acelerar la búsqueda dentro de una tabla interna, pero todo ese conocimiento lo iras ganando en la cancha.

1 me gusta

Lo que no veo en el codigo donde haces la extracion de datos. De todos modos, los loops at, son pan de cada dia para los abap :smile:

haha aca esta la importacion lo tengo en un F, son ejemplos de las pruebitas o curso que emos tenido :see_no_evil:
no esperen mucho ni es nada comparado a lo que se realiza realmente, pero ahi va.

*&---------------------------------------------------------------------*
*&  Include           ZURS07_PRG5_F01
*&---------------------------------------------------------------------*

*&---------------------------------------------------------------------*
*&      Form  F_CATALOGO_CONCEPTOS2
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_LT_CONCEPTOS2  text
*----------------------------------------------------------------------*
FORM f_catalogo_conceptos2
  TABLES
      p_lt_conceptos2 like lt_conceptos2.

  select
    HVORG
    TVORG
    CCOBRO
    XXX
    DESCON
    DESLAR
  into table lt_conceptos2
  from
      ZCCTT_CONCEPTOS2.

ENDFORM.                    " F_CATALOGO_CONCEPTOS2
*&---------------------------------------------------------------------*
*&      Form  F_DFKKOP
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_LT_DFKKOP  text
*      -->P_P_OPBEL  text
*      <--P_GV_SUBRC  text
*----------------------------------------------------------------------*
FORM f_dfkkop
  TABLES
      p_lt_dfkkop like lt_dfkkop
  USING
        p_p_opbel
  CHANGING
      p_gv_subrc.

  TRANSLATE p_test to upper case.
  IF p_test = 'X'.

    select
      opbel
      opupk
      HVORG
      TVORG
    from dfkkop
    into table lt_dfkkop
    where opbel = p_p_opbel.

    p_gv_subrc = sy-subrc.

  else.

    if psl_obel[] is not INITIAL.

      select
        opbel
        opupk
        HVORG
        TVORG
      from dfkkop
      into table lt_dfkkop
      where opbel in psl_obel.

      p_gv_subrc = sy-subrc.

    else.

      gv_subrc = 4.

    endif.
  endif.
ENDFORM.                    " F_DFKKOP
*&---------------------------------------------------------------------*
*&      Form  F_ZCONCEPTOS2
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_LT_DFKKOP  text
*      -->P_LT_CONCEPTOS2  text
*      <--P_GV_SUBRC  text
*----------------------------------------------------------------------*
FORM f_zconceptos2
    TABLES
        p_lt_dfkkop like lt_dfkkop
        p_lt_conceptos2 like lt_conceptos2
        p_lt_salida like lt_salida
    CHANGING p_gv_subrc.

    loop AT p_lt_dfkkop into ls_salida.
        loop at p_lt_conceptos2 into ls_conceptos2 WHERE hvorg = ls_salida-hvorg AND tvorg = ls_salida-tvorg.
          "READ TABLE p_lt_conceptos2
          "into ls_conceptos2
          "WITH KEY hvorg = p_lt_conceptos2-hvorg tvorg = p_lt_conceptos2-tvorg.

            if ls_conceptos2 is INITIAL.
              ls_salida-XXX= 'sin relacion de datos'.
            else.
              "MOVE-CORRESPONDING p_lt_dfkkop to ls_salida.
              MOVE-CORRESPONDING ls_conceptos2 to ls_salida.
              APPEND ls_salida to lt_salida.
            endif.

        endloop.
        if ls_conceptos2 is INITIAL.
              ls_salida-descon = 'sin relacion de datos'.
              APPEND ls_salida to lt_salida.
        ENDIF.
        "p_gv_subrc = sy-subrc.
    ENDLOOP.
ENDFORM.                    " F_ZCONCEPTOS2
*&---------------------------------------------------------------------*
*&      Form  F_IMPRESIONDATOS
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_LT_SALIDA  text
*----------------------------------------------------------------------*
FORM f_impresiondatos
    TABLES p_lt_salida like lt_salida.
                                  "Insertar nombre correcto para <...>.
    loop at p_lt_salida into ls_salida.
      write: /
        ls_salida-opbel,
        ls_salida-opupk,
        ls_salida-hvorg,
        ls_salida-tvorg,
        ls_salida-CCOBRO,
        ls_salida-XXX,
        ls_salida-DESCON.

      "write:/ ls_salida.
    ENDLOOP.
*select
*          opbel
*          opupk
*          lt_conceptos2-HVORG
*          lt_conceptos2-TVORG
*          CCOBRO
*          XXX
*          DESCON
*          DESLAR
*        into table p_lt_salida
*        from p_lt_dfkkop
*        for all entries in p_lt_conceptos2
*        where
*            hvorg = lt_conceptos2-hvorg
*            and tvorg = lt_conceptos2-tvorg
*        order by opupk.
*
*        p_gv_subrc = sy-subrc.
ENDFORM.                    " F_IMPRESIONDATOS
*&---------------------------------------------------------------------*
*&      Form  F_IMPRESIONVACIO
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM f_impresionvacio .
     write: / 'SIN DATOS'.
ENDFORM.

No, pero esta buenisimo el ejemplo, eso es abap, ya te acostumbraras, mira lo que estan es pasando datos de una tabla a otra y condicionan o limintan los datos agregados.
Esta bueno el codigo.

1 me gusta

Pues primero dios, sera lo que estaremos viendo y haciendo.

Muy posiblemente empiece a pasar código, pedir código de referencia y ayudar mutuamente, no se cuantos ABAP’s existan aquí. Así que esperamos unas ayudaditas de vez en cuando XD.

Gracias.

1 me gusta

Un post fue trasladado al siguiente tema: Cuantos abapers hay en la comunidad

Saludos @Neto,

Cabe resaltar que mi intensión no fue bajo ninguna circunstancia faltarte el respeto u denigrar tus conocimientos. La comunidad es de todos y todos estamos para crecer. Si por un instante te falté me disculpo.

Y sí, a lo mejor tu consulta estuvo muy ambigua.

Personalmente, bajo la única razón que utilizo el FOR ALL ENTRIES es si necesito consultar datos de una tabla cluster relacionados a otra. Después de ahí siempre trato de crear la menor cantidad de llamadas al servidor de base de datos posible.

Y trato dentro de lo posible de hacer la menos cantidad de consultas dentro de iteraciones o LOOPS posibles.

2 Me gusta

que paso @romaldyminaya ??? no se de que hablas XD…
Nunca me has faltado al respeto ni yo me e sentido ofendido, ni nada por el estilo… :grinning:

Al contrario me sirven mucho tus comentarios.
Perdón por la tardanza a contestar, ya que e andado algo ajetreado en estos últimos 4 días :sweat:
Gracias :+1:

2 Me gusta

Hola Neto,

Particularmente no le veo el inconveniente a usar el INNER JOIN, siempre y cuando se logre usar las claves primarias para unir las dos tablas.
Respecto a lo que tú dices sobre usar JOIN en tablas clúster es verdad no se puede, aunque si se permiten select directos, en este caso se podría realizar un FOR ALL ENTRIES, se consulta la primera tabla y se almacenan los datos en una tabla interna, luego se orden la tabla interna y se eliminan los duplicados, posteriormente se realiza la consulta a la segunda tabla usando el suplemento FOR ALL ENTRIES (antes de usarlo se debe validar que la tabla interna no este vacía).

2 Me gusta