Implementación de expresiones SQL en vistas CDS

Objectives

After completing this lesson, you will be able to:
  • Motivar el uso de la inserción de código en las vistas CDS.
  • Utilice expresiones SQL en vistas CDS.

Pushdown de código en ABAP SQL y ABAP CDS

En una parte anterior de este recorrido de aprendizaje, aprendió que con las enormes capacidades de análisis de datos de SAP HANA, se recomienda realizar cálculos ya en la base de datos siempre que esto sea posible. También aprendió que ABAP SQL ofrece muchas expresiones y funciones integradas para este fin.

La mayoría de estas expresiones y funciones integradas también están disponibles en las definiciones de vista CDS. Esto le permite mover los cálculos complicados a una definición de vista CDS y, a continuación, recuperar los datos de la vista CDS.

Veamos un ejemplo. En este código ABAP, la sentencia ABAP SQL utiliza una expresión aritmética para calcular el número de asientos libres en un vuelo restando el número de asientos ocupados del número total de asientos.

En este siguiente ejemplo, la expresión aritmética se mueve a una definición de vista CDS. El resultado del cálculo es visible para los consumidores de la vista como elemento de vista seats_free. El código ABAP lee el elemento de vista seats_free como cualquier otro elemento de vista.

Nota

Para el consumidor de una vista CDS, no importa si un elemento de vista es simplemente una proyección de un campo de tabla de base de datos o el resultado de un cálculo complicado.

Mover la lógica SQL de ABAP SQL a una vista CDS tiene varias ventajas:

Encapsulación

Dado que la lógica SQL está oculta en la definición de vista CDS, las sentencias ABAP SQL son más fáciles de leer.

Reutilizar

Al leer de la misma vista CDS, puede reutilizar fácilmente la lógica SQL en otras aplicaciones. En particular, puede utilizar la lógica SQL en los frameworks que utilizan vistas CDS, por ejemplo, análisis integrados, extractores de datos basados en CDS para SAP BW, programación de aplicaciones ABAP RESTful y muchos más.

Semántica

Puede añadir semántica al resultado del cálculo asignando al elemento un nombre significativo y anotándolo con anotaciones de elemento.

Reglas de autorización

Puede restringir el acceso a los datos calculados creando un control de acceso CDS para la vista CDS.

Literales en ABAP CDS

Al comparar literales en ABAP SQL y literales en ABAP CDS, observará que ABAP CDS ofrece una mayor variedad de tipos.

Literales de caracteres

Mientras que ABAP SQL solo conoce literales de caracteres del tipo predefinido C (correspondiente al tipo de diccionario CHAR), ABAP CDS utiliza el tipo de diccionario predefinido NUMC, cuando el literal de caracteres solo consta de dígitos.

Literales numéricos

ABAP SQL solo conoce literales enteros positivos y negativos y utiliza el tipo ABAP I predefinido (tipo de diccionario INT4) para todos ellos.

Por otro lado, ABAP CDS también utiliza los tipos de diccionario INT4, INT2 e INT1, seleccionando el tipo más corto que puede contener el valor del literal. El valor literal 255, por ejemplo, sigue siendo del tipo INT1, mientras que 256 es demasiado grande para un byte y requiere el tipo INT2.

ABAP CDS también conoce literales no enteros. Contienen un punto decimal y tienen el tipo de diccionario predefinido FLTP.

Nota

No se admiten literales no enteros en ABAP SQL, sobre todo porque el signo de período (.) está reservado como delimitador de sentencia.

Conversiones de tipo

Al igual que ABAP SQL, puede utilizar la expresión CAST para implementar conversiones de tipo técnico.

El operando para la expresión cast no puede ser solo un literal, como en nuestro ejemplo. Todos los tipos de otras expresiones son posibles, por ejemplo, campos de la fuente de datos, expresiones aritméticas, distinciones CASE, funciones SQL, etc.

El tipo de destino se puede especificar como un tipo de diccionario predefinido. Esto es idéntico al uso de CAST en ABAP SQL. Sin embargo, tenga en cuenta que en CDS se requiere un prefijo abap..

Existen restricciones con respecto a la combinación del tipo de origen y de destino. Algunas combinaciones no son compatibles en absoluto. Otras solo funcionan con limitaciones. Por ejemplo, actualmente no es posible utilizar operandos de tipo FLTP como origen para la expresión CAST. Encontrará una matriz detallada en la documentación de idioma ABAP.

Es una especialidad de CAST en ABAP CDS que también puede utilizar un elemento de datos de diccionario como tipo de destino. Este tipo de casting no solo convierte el tipo técnico. También toma información semántica como las etiquetas de campo del elemento de datos.

Un cast con un elemento de datos como tipo de destino puede ser útil incluso si el tipo técnico del operando y el elemento de datos de destino son idénticos. En este caso, solo se modifica la información semántica del operando. Si un cast no modifica el tipo técnico, la verificación de sintaxis emite un mensaje de advertencia. Puede suprimir esta advertencia con el suplemento PRESERVING TYPE dentro de la expresión cast.

Distinciones CASE en ABAP CDS

ABAP CDS ofrece exactamente las mismas distinciones CASE que ABAP SQL. Las distinciones de caso simple y caso complejo siguen las mismas reglas de sintaxis y tienen la misma funcionalidad.

Esto se puede ilustrar con un ejemplo. La expresión CASE simple de la izquierda proviene de una sentencia ABAP SQL SELECT. La expresión CASE simple de la derecha forma parte de una definición de entidad de vista CDS. No hay diferencia - aparte de los diferentes formatos y colores en los dos editores.

Expresiones aritméticas en ABAP CDS

Al igual que ABAP SQL, las expresiones aritméticas se pueden utilizar en la lista de elementos de una definición de vista CDS. En ambos casos se aplican las mismas reglas y restricciones. Como en ABAP SQL, la restricción más importante es que el operador de división (/) solo está permitido en expresiones de punto flotante.

Consejo

Puede utilizar cualquier operando numérico en una expresión de punto flotante convirtiendo el tipo a FLTP mediante CAST( ).

Compare estos ejemplos de ABAP SQL y ABAP CDS. De nuevo, la diferencia es sobre todo formatear. Hay dos diferencias que no están realmente relacionadas con las expresiones aritméticas, sino más bien con el uso de literales y expresiones cast:

  • La expresión cast en ABAP CDS requiere el prefijo "abap." delante de los tipos de diccionario predefinidos.
  • Puede utilizar literales de punto flotante en ABAP CDS. Puede utilizar el literal 100.0 directamente en la expresión de punto flotante. No es necesario utilizar el literal entero 100 y convertirlo en el tipo predefinido FLTP.

Utilizar expresiones en una vista CDS

Desea ampliar su entidad de vista CDS con lógica SQL. En un primer paso, se etiquetan los empleados como jefes de departamento y asistentes y se calcula el salario mensual.

Modelo:

  • /LRN/C_EMPLOYEE_QRY (Definición de datos)

Solución:

  • /LRN/C_EMPLOYEE_EXP (Definición de datos)

Prerrequisitos

Para este ejercicio, necesita la entidad de vista CDS que ha creado en un ejercicio anterior (el nombre sugerido era: Z##_C_EmployeeQuery, donde ## es su número de grupo). Si no ha finalizado ese ejercicio, cree una copia de la definición de datos /LRN/C_EMPLOYEE_QRY.

Tarea 1: Utilizar distinción CASE

En su entidad de vista CDS para evaluar datos de empleado (el nombre sugerido era: Z##_C_EmployeeQuery, donde ## es su número de grupo), defina un nuevo elemento de vista (nombre de elemento sugerido: EmployeeRole). Defina el valor de retorno de elemento "H" si el empleado es el jefe de departamento, el valor " A" si el empleado es el asistente de departamento y " " para todos los demás empleados.

Pasos

  1. En la lista de elementos de su entidad de vista, antes de la asociación expuesta, añada una distinción CASE que compare el valor de EmployeeID con el valor del elemento HeadID en el destino de la asociación _Department. Si los valores son idénticos, devuelve el valor "H".

    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, _Department._Assistant.LastName as AssistantName, case EmployeeId when _Department.HeadId then 'H'
  2. Añada una segunda ramificación que compare el valor de EmployeeID con el valor del elemento AssistantID en el destino de la asociación _Department. Si los valores son idénticos, devuelve el valor "A".

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

      Code Snippet
      123456
      case EmployeeId when _Department.HeadId then 'H' when _Department.AssistantId then 'A'
  3. Añada otra rama para devolver el valor ' '.

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

      Code Snippet
      1234567
      case EmployeeId when _Department.HeadId then 'H' when _Department.AssistantId then 'A' else ' '
  4. Cierre la expresión CASE y especifique un nombre de elemento (nombre de elemento sugerido: EmployeeRole).

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

      Code Snippet
      12345678
      case EmployeeId when _Department.HeadId then 'H' when _Department.AssistantId then 'A' else ' ' end as EmployeeRole,
  5. Añada la anotación necesaria para definir una etiqueta para el campo calculado (valor sugerido: Rol de empleado).

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

      Code Snippet
      123456789
      @EndUserText.label: 'Employee Role' case EmployeeId when _Department.HeadId then 'H' when _Department.AssistantId then 'A' else ' ' end as EmployeeRole,

Tarea 2: Utilizar expresión aritmética

Con base en el salario anual del empleado, calcule el salario mensual (nombre de elemento sugerido: MonthlySalary).

Pasos

  1. Utilice una expresión aritmética con el operador / para dividir el contenido de AnnualSalary entre 12.

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

      Code Snippet
      1234567891011
      @EndUserText.label: 'Employee Role' case EmployeeId when _Department.HeadId then 'H' when _Department.AssistantId then 'A' else ' ' end as EmployeeRole, cast( AnnualSalary as abap.fltp ) / 12.0 as MonthlySalary,
  2. Añada la anotación necesaria para definir una etiqueta para el campo calculado (valor sugerido: Salario mensual).

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

      Code Snippet
      123456789101112
      @EndUserText.label: 'Employee Role' case EmployeeId when _Department.HeadId then 'H' when _Department.AssistantId then 'A' else ' ' end as EmployeeRole, @EndUserText.label: 'Monthly Salary' cast( AnnualSalary as abap.fltp ) / 12.0 as MonthlySalary,
  3. Añada el elemento CurrencyCode a la lista de elementos y utilice la anotación @Semantics.amount.currencyCode para vincularlo al elemento MonthlySalary.

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

      Code Snippet
      12345678
      @EndUserText.label: 'Monthly Salary' @Semantics.amount.currencyCode: 'CurrencyCode' cast( AnnualSalary as abap.fltp ) / 12.0 as MonthlySalary, CurrencyCode,
  4. Active la definición de datos CDS.

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

  5. Abra la Vista previa de datos y analice la salida.

    1. Pulse F8 para abrir la Vista previa de datos.