Uso de asociaciones en expresiones de ruta

Objectives

After completing this lesson, you will be able to:
  • Utilice expresiones de vía de acceso en vistas CDS.
  • Utilice condiciones de filtro en expresiones de ruta.
  • Utilice expresiones de ruta en ABAP SQL.

Expresiones de vía de acceso en CDS

Cuando una entidad de vista CDS lee desde una entidad con asociaciones expuestas, existen dos posibilidades:

Propagación de la asociación

Al añadir el nombre de asociación a la lista de elementos, la asociación también es visible para los consumidores de esta vista. En el ejemplo, la asociación _Department se define y expone en la entidad de vista R_Employee. La entidad de vista C_Employee lee el R_Employee y propaga la asociación _Department.

Uso de la asociación

Al añadir un signo de período (.) y un nombre de elemento después del nombre de asociación, la asociación se utiliza para leer datos del destino de asociación. Este tipo de uso se denomina Expresión de ruta. En el ejemplo, el destino de la asociación _Department es la entidad de vista CDS C_Department. La entidad de vista CDS C_Employee utiliza una expresión de vía de acceso para leer el campo DepmentDesignation del destino de asociación y lo añade a su propia lista de elementos.

A nivel de base de datos, una expresión de ruta se traduce en un join del origen de asociación y el destino de asociación. Esto se hace visible en la función Mostrar sentencia SQL Create del editor.

En el ejemplo, la expresión de vía de acceso _Department.DepmentDesignation lleva a un join de las vistas SQL R_EMPLOYEE y R_DEPARTMENT en la base de datos. La condición ON para el join se deriva de la condición ON de la asociación.

Nota

El tipo de conexión LEFT OUTER MANY TO ONE JOIN es una especialidad de la base de datos de SAP HANA. También existe un tipo de join LEFT OUTER MANY TO MANY JOIN que se utiliza cuando la cardinalidad de asociación tiene un máximo superior a 1.

Es importante destacar que la combinación a nivel de base de datos solo se crea cuando la asociación se utiliza en una expresión de ruta. Definir, exponer y propagar una asociación no lleva a una unión. Esta función de las asociaciones a veces se conoce como Join on Demand.

Veamos un ejemplo de nuevo: aunque la entidad de vista CDS R_Employee define y expone la asociación _Department y la entidad de vista CDS C_Employee propaga esta asociación, la vista SQL correspondiente C_EMPLOYEE solo lee de la vista SQL R_EMPLOYEE.

Hasta ahora hemos discutido expresiones de ruta con una asociación, solo. Pero también puede crear expresiones de ruta más largas encadenando varias asociaciones.

Este es un ejemplo: la entidad de vista CDS R_Employee expone la asociación _Department, que tiene la entidad de vista CDS R_Department como destino. Este destino expone otra asociación _Head, señalando de nuevo a R_Employee, pero leyendo el empleado que es el jefe del departamento correspondiente. Expresión de ruta _Department._Head.LastName lee el apellido del jefe del departamento al que está asignado un empleado. La combinación larga y complicada de tres fuentes de datos se genera automáticamente.

La mayoría de las veces, cuando una entidad de vista CDS define una asociación, la expone a sus consumidores. Sin embargo, también puede utilizar la asociación, directamente, en lugar de o además de exponerla.

Lo llamamos un uso ad hoc de las asociaciones. En el ejemplo, la entidad de vista CDS R_Employee define la asociación _Department. En lugar de exponer la asociación, la utiliza directamente en una expresión de vía de acceso para recuperar la designación del departamento relacionado.

En el caso de una utilización ad hoc, la unión se crea inmediatamente en la vista SQL para esta entidad de vista CDS.

Cómo escribir expresiones de vía de acceso en CDS

Reproduzca el vídeo para ver cómo escribir expresiones de ruta en CDS.

La influencia de la cardinalidad en las expresiones de ruta

Cuando utiliza una asociación en una expresión de vía de acceso, la cardinalidad puede influir en la verificación de sintaxis. El editor muestra advertencias e incluso errores para el uso incorrecto de asociaciones "a muchos", es decir, asociaciones para las que la cardinalidad tiene un máximo superior a 1.

En las expresiones de ruta de la cláusula WHERE de la definición de vista, el uso de asociaciones "a muchos" no está permitido en absoluto y provoca un error de sintaxis.

En la lista de elementos, se permiten asociaciones "a muchos", pero el editor muestra una advertencia que indica que esta expresión de ruta puede modificar el número de conjuntos de resultados.

¿Qué significa esta advertencia? Imagine que sus tablas contienen solo 1 departamento con 5 empleados. Sin la expresión de vía de acceso, la vista CDS C_Department devuelve exactamente 1 conjunto de datos. A continuación, añada la expresión de vía de acceso con la asociación "a varios" _Empleado a la lista de elementos. A continuación, la misma vista devuelve 5 conjuntos de datos, uno para cada empleado. Esto puede ser engañoso para los consumidores de la vista C_Department porque esperan un conjunto de datos para cada departamento.

Consejo

Si está interesado en una combinación de datos de empleado y datos de departamento, debe empezar desde la vista R_Employee y utilizar la asociación "a uno" _Departamento para añadir los detalles del departamento.

Una forma de utilizar una asociación "a muchos" correctamente es colocar la expresión de ruta dentro de una agregación. La cláusula GROUP-BY, que es obligatoria para las agregaciones, garantiza que el número de conjuntos de datos permanezca igual. En el ejemplo, la entidad de vista CDS C_Department aún devuelve un conjunto de datos por departamento y no un conjunto de datos por empleado.

Nota

Otra forma de utilizar una asociación "a muchos" correctamente es la adición de una condición de filtro. Analizaremos los filtros en la siguiente sección.

Pruébelo: Uso incorrecto y correcto de asociaciones a muchos

  1. Cree una nueva definición de datos CDS con /DMO/I_Connection_R como objeto de datos referenciado.
  2. Elimine la lista de elementos, incluidos los corchetes de alrededor.
  3. Copie el siguiente fragmento de código e insértelo después de as select from /DMO/I_Connection_R:
    Code Snippet
    123456789101112131415161718192021
    { key AirlineID, key ConnectionID, // _Airline.CurrencyCode, // _Flight.PlaneType, DepartureAirport, DestinationAirport } where AirlineID = 'LH' // Only one connection and ConnectionID = '0400' // fulfills this filter // and _Airline.CurrencyCode = 'EUR' // and _Flight.PlaneType = '747-400'
  4. Active la definición de datos y visualice la vista previa de datos. Dado que la cláusula WHERE califica completamente la clave primaria de las conexiones de vuelo, solo verá un conjunto de datos.
  5. Elimine los marcadores de comentarios de las dos expresiones de ruta en la lista de elementos. Observe la advertencia de sintaxis porque _Flight tiene la cardinalidad 0..* y, por lo tanto, es una asociación "a muchos".
  6. Active la definición de datos a pesar de la advertencia y visualice la vista previa de datos. Ahora puede ver varios conjuntos de datos.
  7. Comente las condiciones adicionales en la cláusula WHERE. Observe el error de sintaxis para la expresión de ruta que incluye la asociación _Flight.
  8. Elimine la lista de elementos y la cláusula WHERE y sustitúyala por la siguiente sintaxis:
    Code Snippet
    1234567891011121314151617
    { key AirlineID, key ConnectionID, _Flight.OccupiedSeats // sum(_Flight.OccupiedSeats) as TotalOccupiedSeats } where AirlineID = 'LH' // Only one connection and ConnectionID = '0400' // fulfills this condition // group by // AirlineID, // ConnectionID
  9. Observe la advertencia de sintaxis para la expresión de ruta, incluida la asociación _Flight. Activar y visualizar la vista previa de datos.
  10. Comente la expresión de ruta y elimine los marcadores de coment de la función agregada sum( ) y la cláusula GROUP BY. Observe que la advertencia de sintaxis ha desaparecido y que la vista previa de datos muestra solo un conjunto de datos.

Filtros en expresiones de vía de acceso

Cuando utiliza una asociación en una expresión de ruta, puede añadir filtros para restringir los conjuntos de datos del destino de asociación. La condición del filtro se coloca entre corchetes ([ ]) inmediatamente después del nombre de la asociación. Como en una cláusula WHERE, puede utilizar operadores relacionales y operadores booleanos AND, OR, NOT. La parte izquierda de una condición debe ser un campo del destino de asociación. Para el lado derecho, hay más flexibilidad. Entre otras cosas, puede utilizar campos del destino de asociación, literales, funciones integradas, etc.

En el ejemplo, hay dos expresiones de ruta, una sin una condición de filtro y la otra con la condición de filtro OccupiedSeats > MaximumSeats. Mientras que la primera expresión de ruta busca el vuelo más temprano asociado a una conexión de vuelo, la segunda expresión de ruta restringe la búsqueda a vuelos sobrerreservados, es decir, vuelos en los que el número de asientos ocupados supera el número de asientos disponibles.

Técnicamente, la condición de filtro se añade a la condición ON del join generado a nivel de base de datos.

Veamos la sentencia SQL create para nuestro ejemplo: La primera combinación en nuestro ejemplo pertenece a la expresión de vía de acceso sin el filtro. La condición ON compara AIRLINEID, CONNECTIONID y el campo de cliente MANDT. La segunda combinación pertenece a la expresión de ruta con el filtro. ¿Se puede detectar la condición adicional de la expresión de ruta filtrada?

Cuando filtra una asociación que tiene una cardinalidad con un máximo de > 1, puede suceder que después de aplicar el filtro solo quede una entrada del destino de asociación. El filtro convierte la asociación "a varios" en una asociación "a uno". En una situación de este tipo, debe añadir "1: " delante de la condición de filtro para documentar la cardinalidad modificada de la asociación.

En este ejemplo, la entidad de vista CDS I_Currency define y expone la asociación _Text, que es una asociación "a muchos", que devuelve nombres de moneda en diferentes idiomas. Sin un filtro, la asociación leería el nombre de una moneda en todos los idiomas que se actualizan en el sistema. Sin embargo, las dos expresiones de ruta con un filtro solo leen un nombre de moneda cada una, ya sea en inglés o en alemán.

Como vimos anteriormente, la verificación de sintaxis emite advertencias y errores cuando utilizamos una asociación "para muchos" en una expresión de ruta que se encuentra fuera de una agregación. Pero, ¿qué sucede si un filtro se asegura de que solo haya un registro? ¿Aún emite la verificación de sintaxis las advertencias y los errores? Sí, lo hace, porque no puede saber que el filtro convierte la asociación "a muchos" en una asociación "a uno". Podemos documentar esto añadiendo "1:" dentro de los corchetes, antes de la condición del filtro. En el ejemplo, hay una advertencia de sintaxis para la expresión de ruta con el filtro Language = 'E'. Pero no hay ninguna advertencia de sintaxis para la expresión de ruta con el filtro 1: Language = 'D'.

Pruébelo: Asociaciones filtradas

  1. Cree una nueva definición de datos CDS con /DMO/I_Connection_R como objeto de datos referenciado.
  2. Elimine la lista de elementos, incluidos los corchetes de alrededor.
  3. Copie el siguiente fragmento de código e insértelo después de as select from /DMO/I_Connection_R:
    Code Snippet
    123456789101112131415
    { key AirlineID, key ConnectionID, //_Airline._Currency._Text.CurrencyName //_Airline._Currency._Text[ Language = 'E' ].CurrencyName //_Airline._Currency._Text[ 1: language = 'E' ].CurrencyName } where AirlineID = 'AA' and ConnectionID = '0017'
  4. Elimine los marcadores de comentarios de la primera expresión de vía de acceso y analice las advertencias de sintaxis (si las hubiera).
  5. Active la definición de datos y visualice la vista previa de datos y la sentencia SQL create para esta versión de la vista.
  6. Comente la primera expresión de ruta y elimine los marcadores de comentarios de la segunda expresión de ruta.
  7. Active y analice las advertencias de sintaxis, la vista previa de datos y la sentencia SQL create para la expresión de vía de acceso que incluye un filtro.
  8. Repita con la tercera expresión de ruta.

Expresiones de vía de acceso en ABAP SQL

Otra forma de utilizar las asociaciones expuestas son las expresiones de ruta en ABAP SQL. El concepto es exactamente el mismo que en CDS, pero la sintaxis es ligeramente diferente.

Las diferencias de sintaxis más importantes son las siguientes:

Prefijo de asociación

En las expresiones de ruta SQL ABAP, las asociaciones deben escaparse con una barra invertida (\).

Selector de elementos

En las expresiones de vía de acceso CDS, se utiliza un signo de punto (.) como separador entre el nombre de asociación y el nombre de elemento. En ABAP SQL, el signo de período no es adecuado porque finalizaría la sentencia. Por lo tanto, en ABAP SQL, se utiliza un guion como selector de elementos.

Veamos un ejemplo: Esta sentencia ABAP SQL SELECT lee de la entidad de vista CDS /DMO/I_Connection_R que expone una asociación _Airline. La última expresión de la lista FIELDS es una expresión de vía de acceso para leer el elemento Nombre del destino de asociación /DMO/I_Carrier.

Otra diferencia de sintaxis está relacionada con las asociaciones encadenadas. Cuando una expresión de ruta contiene una secuencia de asociaciones, no hay ningún separador dedicado. Donde en CDS las asociaciones están separadas por un signo de punto (.), se siguen directamente en ABAP SQL. Sin embargo, tenga en cuenta que cada nombre de asociación necesita una barra invertida (\) como prefijo.

En este ejemplo, el destino de la asociación _Airline expone una asociación _Currency que devuelve detalles para la moneda local de la aerolínea. La expresión \_Airline\_Currency-CurrencyISOCode lee el código ISO para la moneda local de la compañía aérea que opera la conexión de vuelo.

Nota

En CDS, la misma expresión de ruta lee _Airline._Currency.CurrencyISOCode.

En ABAP SQL, las condiciones de filtro se añaden entre corchetes, igual que en CDS. Sin embargo, para especificar una cardinalidad, se utiliza una sintaxis completamente diferente. En lugar de "1:", tiene que añadir palabras clave MUCHAS A UNO DÓNDE. Hay varias otras opciones como UNO A UNO DÓNDE Y MUCHAS A MUCHAS DÓNDE. Consulte la documentación de palabras clave ABAP para obtener más detalles.

Nota

Hay una sintaxis alternativa en la que se escribe [ (1) WHERE … ] en lugar de [ MANY TO ONE WHERE … ], pero no se recomienda esta sintaxis alternativa.

Pruébelo: Expresiones de ruta en ABAP SQL

  1. Cree una nueva clase global que implemente la interfaz IF_OO_ADT_CLASSRUN.
  2. Copie el siguiente fragmento de código en la parte de implementación del método if_oo_adt_classrun~main( ):
    Code Snippet
    1234567891011121314151617181920212223242526272829303132333435
    * Data selection ********************************************************************** SELECT FROM /dmo/i_connection_R FIELDS Airlineid, connectionid, * _Airline.Name, * \_Airline-Name, * _Airline-Name, * _Airline~Name, * \_Airline~Name, * * \_Airline-_Currency-CurrencyISOCode, * \_Airline-\_Currency-CurrencyISOCode, * \_Airline\_Currency-CurrencyISOCode, * \_Airline~\_Currency~CurrencyISOCode, * \_Airline\_Currency~CurrencyISOCode, * * \_Airline\_Currency\_Text[ Language = 'E' ]-CurrencyShortName AS CurrencyNameEN, * \_Airline\_Currency\_Text[ MANY TO ONE WHERE Language = 'D' ]-CurrencyShortName AS CurrencyNameDE, * \_Airline\_Currency\_Text[ Language = 'E' ]-CurrencyShortName AS CurrencyNameEN, * \_Airline-\_Currency-\_Text[ MANY TO ONE WHERE Language = 'D' ]-CurrencyShortName AS CurrencyNameDE, * \_Airline~\_Currency~\_Text[ 1: Language = 'E' ]-CurrencyShortName AS CurrencyNameEN, DepartureAirport, DestinationAirport INTO TABLE @DATA(result). * Output ********************************************************************** out->write( data = result name = 'Selection result').

    Esta codificación contiene una sentencia ABAP SQL SELECT con varias expresiones de vía de acceso.

  3. Elimine el comentario del primer bloque de expresiones de vía de acceso y utilice la verificación de sintaxis para encontrar la expresión de vía de acceso que sea sintácticamente correcta en ABAP SQL.
  4. Elimine las variantes sintácticamente incorrectas, active la clase, ejecútela como aplicación de consola y analice la salida de la consola.
  5. Repita esto con el segundo y tercer bloque de expresiones de ruta.

Utilizar asociaciones en expresiones de ruta

Ha definido entidades de vista CDS con asociaciones expuestas. Desea utilizar las asociaciones expuestas. Primero debe hacerlo en una vista CDS y, a continuación, en una sentencia SELECT en ABAP SQL.

Modelo:

  • /LRN/CL_S4D430_RLT_PATH_EXP (clase global)

Solución:

  • /LRN/C_EMPLOYEE_QRY (Definición de datos)
  • /LRN/CL_S4D430_RLS_PATH_EXP (clase global)

Tarea 1: Utilizar asociaciones expuestas en CDS

Defina una nueva entidad de vista CDS (nombre sugerido: Z##_C_EmployeeQuery). Como fuente de datos, utilice su entidad de vista para datos de empleado que expongan una asociación (el nombre sugerido era: Z##_R_Employee). En la lista de elementos, lea el ID y el nombre del empleado. A continuación, agregue expresiones de ruta para leer la descripción del departamento y el apellido del asistente del departamento.

Nota

Si no ha finalizado el ejercicio anterior, puede dejar que su nueva entidad de vista lea la entidad de vista /LRN/R_Employee_Rel.

Pasos

  1. En su propio paquete, cree una nueva definición de datos (nombre sugerido: Z##_C_EMPLOYEEQUERY, donde ## es su número de grupo). Especifique la entidad de vista CDS Z##_R_Employee como Objeto referenciado y seleccione el modelo Definir entidad de vista para generar la sentencia de definición, algunas anotaciones estándar y la lista de elementos.

    1. En la vista Explorador de proyectos, haga clic con el botón derecho en la definición de datos Z##_R_EMPLOYEE para abrir el menú contextual.

    2. En el menú contextual, seleccione Nueva definición de datos.

    3. Confirme que el campo Paquete contiene el nombre de su paquete y que el campo Objeto referenciado contiene el nombre de su definición de tabla de base de datos.

    4. En el campo Nombre, introduzca el nombre de la entidad de vista CDS (Z##_C_EmployeeQuery, donde ## es su número de grupo).

    5. Introduzca Empleado (consulta) en el campo Descripción y seleccione Siguiente.

    6. Confirme la orden de transporte y seleccione Siguiente.

      Atención

      Asegúrese de no seleccionar Finalizar todavía. Si lo hace, no podrá seleccionar la plantilla que desea utilizar.
    7. En la lista de plantillas, seleccione Definir entidad de vista y, a continuación, Finalizar.

  2. Aplicar formato de código fuente.

    1. En el menú Eclipse, seleccione Formato→de código fuente. Como alternativa, seleccione Mayús + F1.

  3. Edite la lista de elementos de la nueva definición de datos. Elimine todos los elementos excepto EmployeeID, FirstName, LastName, DepartmentID y la asociación expuesta _Department.

    1. Ajuste el código de la siguiente manera:

      Code Snippet
      1234567891011121314
      define view entity Z##_C_EmployeeQuery as select from Z##_R_Employee { key EmployeeId, FirstName, LastName, DepartmentID, /* Associations */ _Department }
  4. Después del elemento DepartmentID, añada una expresión de vía de acceso para leer la descripción del departamento al que está asignado el empleado (nombre de elemento sugerido: DepartmentDescription).

    1. Ajuste el código de la siguiente manera:

      Code Snippet
      12345678910111213141516
      define view entity Z##_C_EmployeeQuery as select from Z##_R_Employee { key EmployeeId, FirstName, LastName, DepartmentID, _Department.Description as DepartmentDescription, /* Associations */ _Department }
  5. Grabe la definición de datos y visualice la sentencia SQL CREATE.

    Nota

    Si no guarda la definición de datos, las modificaciones no aparecerán en la sentencia SQL CREATE.
    1. Pulse Ctrl + S para guardar el objeto de desarrollo.

    2. Haga clic con el botón derecho en cualquier lugar del código fuente de la definición de datos y seleccione Mostrar sentencia CREATE de SQL.

  6. Añada una expresión de vía de acceso para leer los apellidos del asistente de departamento (nombre de elemento sugerido: AssistantName).

    1. Ajuste el código de la siguiente manera:

      Code Snippet
      1234567891011121314151617
      define view entity Z##_C_EmployeeQuery as select from Z##_R_Employee { key EmployeeId, FirstName, LastName, DepartmentID, _Department.Description as DepartmentDescription, _Department._Assistant.LastName as AssistantName, /* Associations */ _Department }
  7. Active la definición de datos y visualice de nuevo la sentencia SQL CREATE.

    1. Pulse Ctrl + F3 para activar el objeto de desarrollo.

    2. Haga clic con el botón derecho en cualquier lugar del código fuente de la definición de datos y seleccione Mostrar sentencia CREATE de SQL.

  8. Visualice el resultado de la consulta en la herramienta Vista previa de datos.

    1. Coloque el cursor en cualquier lugar de la definición de datos y pulse F8 para llamar la herramienta Vista previa de datos.

Tarea 2: Utilizar asociaciones expuestas en ABAP SQL

Cree una copia de la clase ABAP /LRN/CL_S4D430_RLT_PATH_EXPR (nombre sugerido: ZCL_##_PATH_EXPR) y ajuste la sentencia SELECT. Lea todos los campos de la entidad de vista CDS que acaba de crear (el nombre sugerido era: Z##_C_EmployeeQuery). Además, implemente una expresión de ruta en ABAP SQL para leer el nombre del jefe de departamento.

Pasos

  1. Copie la clase /LRN/CL_S4D430_RLT_PATH_EXPR en una clase de su propio paquete (nombre sugerido: ZCL_##_PATH_EXPR, donde ## es para su número de grupo).

    1. En la vista Explorador de proyectos, haga clic con el botón derecho en la clase /LRN/CL_S4D430_RLT_PATH_EXP para abrir el menú contextual.

    2. En el menú contextual, seleccione Duplicar ....

    3. Introduzca el nombre del paquete en el campo Paquete. En el campo Nombre, introduzca el nombre ZCL_##_PATH_EXP, donde ## es su número de grupo.

    4. Ajuste la descripción y seleccione Siguiente.

    5. Confirme la orden de transporte y seleccione Finalizar.

  2. En el método IF_OO_ADT_CLASSRUN~MAIN, modifique la sentencia SELECT. Sustituya /LRN/C_Employee_Ann en la cláusula FROM por el nombre de la entidad de vista CDS que acaba de crear (Z##_C_EmployeeQuery).

    1. Ajuste el código de la siguiente manera:

      Code Snippet
      123456
      SELECT FROM Z##_C_EmployeeQuery FIELDS employeeid,
  3. Al final de la lista de campos, lea también los nuevos elementos de vista DepartmentDescription y AssistantName.

    1. Ajuste el código de la siguiente manera:

      Code Snippet
      1234567891011
      SELECT FROM Z##_C_EmployeeQuery FIELDS employeeid, firstname, lastname, departmentid, departmentdescription, assistantname INTO TABLE @DATA(result).
  4. Después del nombre del asistente de departamento, implemente una expresión de ruta que lea el apellido del jefe de departamento (nombre de campo sugerido: HEADNAME).

    Consejo

    Utilice la finalización de código siempre que sea posible. Recuerde que en ABAP SQL, los nombres de asociación requieren un signo de barra invertida (\) como prefijo y que se utiliza un signo de guion (-) entre el nombre de asociación y el nombre de elemento.
    1. Ajuste el código de la siguiente manera:

      Code Snippet
      123456789101112
      SELECT FROM Z##_C_EmployeeQuery FIELDS employeeid, firstname, lastname, departmentid, departmentdescription, assistantname, \_department\_head-lastname AS headname INTO TABLE @DATA(result).
  5. Active la clase global y ejecútela como una aplicación de consola.

    1. Pulse Ctrl + F3 para activar el objeto de desarrollo.

    2. Pulse F9 para ejecutar la clase global como una aplicación de consola.