Desarrollo de lógica personalizada mediante SQL

Trabajar con SQLScript

Objective

After completing this lesson, you will be able to describa las funciones adicionales que proporciona SQLScript en comparación con SQL estándar.

Capacidades SQLScript

SQLScript es un lenguaje de base de datos desarrollado por SAP. Se basa en SQL estándar, pero añade capacidades adicionales para explotar las funciones avanzadas de SAP HANA Cloud.

Estas son algunas de las características clave de SQL Script:

  • SQLScript amplía ANSI-92 SQL. Al igual que otros proveedores de bases de datos amplían SQL en sus bases de datos, SAP HANA amplía SQL utilizando SQLScript.
  • SQLScript le permite acceder a funciones específicas de SAP HANA, como tablas de columnas, vistas de información parametrizadas, memorias intermedias delta, trabajar con varios conjuntos de resultados en paralelo, conversiones de moneda integradas a nivel de base de datos, búsqueda de texto inexacta, tipos de datos espaciales y bibliotecas de análisis predictivo.
  • SQLScript permite a los desarrolladores introducir una lógica intensiva de datos en la base de datos.
  • SQLScript anima a los desarrolladores a mantener algoritmos utilizando un paradigma orientado a conjuntos, en lugar de un paradigma de registro individual.
  • Sin embargo, SQLScript permite realizar bucles a través de los resultados y utilizar la lógica if-then-else
  • SQLScript le permite dividir consultas complejas en varias sentencias más pequeñas, simplificando así su codificación SQL y mejorando el paralelismo mediante el optimizador.

Nota

La versión estándar de SQL en la que se basa SQLScript es la popular versión ANSI-92 que es compatible con casi todas las bases de datos.

Las funciones adicionales de SQLScript incluyen trabajar con tablas de columnas de SAP HANA Cloud, pasar parámetros entre vistas de cálculo y SQLScript, trabajar con tipos de datos espaciales y bibliotecas de análisis predictivos.

Desarrollo de lógica empresarial con SQLScript

En los enfoques cliente-servidor tradicionales, la lógica empresarial se define y ejecuta en el servidor de aplicación utilizando lenguajes de programación de aplicaciones como ABAP o C++. Con SAP HANA Cloud, gran parte de esta lógica ahora se puede definir mediante SQLScript, lo que permite al desarrollador definir y ejecutar todas las tareas de procesamiento de datos en la base de datos para lograr un rendimiento mejorado.

SQLScript le permite utilizar variables para dividir una sentencia SQL compleja grande en sentencias más pequeñas y simples. Esto hace que el código sea mucho más fácil de entender. También ayuda con el rendimiento de SQL HANA Cloud porque muchas de estas sentencias más pequeñas se pueden ejecutar en paralelo.

Vea este vídeo para ver un ejemplo:

En el ejemplo estudiado, queremos averiguar qué editor tiene más libros:

Code Snippet
12
books_per_publisher = SELECT publisher, COUNT (*) AS num_books FROM BOOKS GROUP BY publisher; publisher_with_most_books = SELECT * FROM :books_per_publisher WHERE num_books >= (SELECT MAX (num_books) FROM :books_per_publisher);

El compilador y optimizador SQLScript determinan cómo ejecutar mejor estas sentencias, ya sea utilizando una expresión de subconsulta común con sugerencias de base de datos o combinándola en una única consulta compleja. El código se vuelve más fácil de escribir y comprender, más mantenible y aumenta la productividad del desarrollador.

Al dividir SQLScript en sentencias más pequeñas y rellenar variables de tabla, también refleja la forma en que ha aprendido a crear sus vistas de cálculo. Al igual que cuando comienza a crear vistas de cálculo en capas, empezando de abajo hacia arriba, hace lo mismo con el código SQLScript. Tenga en cuenta que la secuencia precisa de sus pasos SQLScript no es necesariamente el orden de tiempo de ejecución, porque el optimizador siempre decidirá el mejor plan de ejecución. Sin embargo, el optimizador nunca alterará el resultado deseado. Esto también es válido para las vistas de cálculo.

El uso de variables

ANSI-92 SQL no especifica el uso de variables en sentencias SQL. En SAP HANA Cloud, SQLScript implementa el concepto de variable como una extensión de ANSI-92 SQL.

Las variables se pueden declarar, asignar y reutilizar dentro de un script.

Uso de variables en SQLScript

  • Declarar una variable

    DECLARE <variable_name> <type> [NOT NULL] [= <value>]

    Ejemplo 1: DECLARE a int;

    Ejemplo 2: DECLARE b int = 0; (el valor se asigna al crear la variable)

  • Asignar una variable (definir el valor de una variable)

    <variable_name> = <value> or <expression>

    Ejemplo 1: a = 3;

    Ejemplo 2: b = select count(*) from baseTable;

  • Utilizar una variable en una expresión

    :<variable_name> (con dos puntos) devuelve el valor actual de la variable

    Ejemplo: b = :a + 5; (asigna el valor de a + 5 a b)

Tipos de datos SQLScript

SQLScript también añade tipos de datos adicionales para ayudar a abordar las funciones que faltan de SQL estándar, por ejemplo, tipos de datos espaciales y tipos de datos de texto.

Tipos de datos ANSI-92 y SQLScript

ClasificaciónTipos de datos ANSI-92 estándarTipos de datos específicos de SQLScript
Fecha/HoraDATE, TIME, TIMESTAMPSECONDDATE
NuméricoDECIMAL, INTEGER, SMALLINT, FLOAT, REAL, DOBLETINYINT, BIGINT, SMALLDECIMAL
Cadena de caracteresCHAR, NCHAR, VARCHAR, NVARCHARALFANO, TEXTO CORTO
BinarioBINARIA, VARBINARIA 
Objeto grande BLOB, CLOB, NCLOB, TEXT, BINTEXT
Booleano BOOLEANO
Espacial ST_POINT, ST_GEOMETRY

Parámetros de entrada de procesamiento definidos en vistas de cálculo con SQLScript

Cuando utiliza una sentencia SELECT en SQLScript para consultar una vista de cálculo que tiene parámetros de entrada, utilice la palabra clave PLACEHOLDER con el nombre del parámetro de entrada envuelto en símbolos $$ y el valor que desea transferir al parámetro de entrada, por ejemplo:

Pasar parámetros de entrada a la vista de cálculo

Utilice la palabra clave PLACEHOLDER para transferir parámetros de entrada a la vista de cálculo en una sentencia SELECT:

Code Snippet
1234
SELECT "PRODUCT", sum("TAXED_AMOUNT") FROM "_SYS_BIC"."MyPackage/SalesResults" ('PLACEHOLDER' = ('$$Tax Amount$$', '17.5')) GROUP BY "PRODUCT"
Referencia al parámetro de entrada en el script SQL

Dentro de SQLScript, consulte el parámetro de entrada utilizando dos puntos:;

Code Snippet
1
Sales with tax = Sales Revenue * :Tax_Amount

También es posible pasar parámetros de salida generados desde un SQLScript a una vista de cálculo utilizando la función de asignación de parámetros.

Loops y lógica condicional

En general, el código SQL se escribe de forma declarativa. Esto significa que indica la intención de la acción y no dicta cómo se deben llevar a cabo los pasos de procesamiento de datos en un orden determinado. Lo hacemos para que permita que el optimizador SQL determine el mejor plan de ejecución basado en muchos factores dinámicos en el tiempo de ejecución.

Sin embargo, a veces necesita controlar la lógica de proceso de SQL para que los pasos se realicen en un orden determinado. Por ejemplo, cuando necesita realizar un paso solo si se cumple una determinada condición o si necesita realizar un bucle un número de veces. En estos casos, utilizará la lógica imperativa.

Esto (en su mayoría) no está disponible en ANSI SQL y, por lo tanto, SAP HANA proporciona lenguaje lógico declarativo como parte de SQLScript para proporcionar control de flujo.

La falta de lenguaje lógico imperativo es lo que a menudo provoca que el desarrollador mueva el procesamiento de datos a la capa de aplicación. Cuando una aplicación se ejecuta en HANA, debería enviar tanto procesamiento de datos como sea posible a la base de datos. La lógica imperativa SQLScript de SAP HANA lo permite, por lo que se debe realizar menos tratamiento de datos en las capas de aplicación y se puede hacer más en la base de datos.

Consejo

Recuerde que la lógica imperativa no puede tener el mismo rendimiento que la lógica declarativa. Esto se debe a que el optimizador SQL no es libre de decidir la secuencia de pasos y debe tener cuidado de seguir su lógica, lo que podría destruir optimizaciones. Si necesita el mejor rendimiento, intente evitar la lógica imperativa.

Lógica condicional

La sentencia IF
Code Snippet
12345678910
IF <bool-expr1> THEN {then-stmts1} {ELSEIF <bool-expr2> THEN {then-stmts2}} {ELSE {else-stmts3}} END IF
Ejemplo de una sentencia IF que utiliza una cláusula ELSE.

La figura anterior muestra un ejemplo de la sentencia IF, que consta de una expresión booleana, :found is NULL. Si la expresión se evalúa como verdadera, se ejecuta la sentencia CALL ins_msg_proc('result of count(*) cannot be NULL'); en el bloque obligatorio THEN. La sentencia IF termina con END IF. Las partes restantes son opcionales.

Si la expresión booleana :found is NULL no se evalúa como verdadera, entonces se evalúa la rama ELSE. En la mayoría de los casos, esta ramificación empieza por ELSE. La sentencia CALL ins_msg_proc('result of count(*) not NULL- as expected'); se ejecuta sin más verificaciones. Después de otra ramificación, no se permiten más ELSE ramificación o ELSEIF ramificación.

Como alternativa, cuando se utiliza ELSEIF en lugar de ELSE, se puede evaluar otra expresión booleana. Si se evalúa como verdadero, se ejecuta la siguiente sentencia. Puede agregar un número arbitrario de cláusulas ELSEIF de esta manera.

Esta sentencia se puede utilizar para simular la sentencia switch case conocida de muchos lenguajes de programación.

WHILE y FOR loops

El bucle WHILE
Code Snippet
123
WHILE <bool-stmt> DO {stmts} END WHILE
El bucle WHILE ejecuta la sentencia stmts en el cuerpo del bucle siempre que la expresión booleana al principio bool-stmt del bucle se evalúe como verdadera.
El loop FOR
Code Snippet
123
FOR <loop-var> IN {REVERSE} <start>..<end> DO {stmts} END FOR
El bucle FOR itera un rango de valores numéricos (indicados por inicio y fin en la sintaxis) y vincula el valor actual a una variable (loop-var) en orden ascendente. La iteración comienza con el inicio del valor y se incrementa en uno hasta que el loop-var es mayor que el final.

Por lo tanto, si el inicio es mayor que el final, el bucle del cuerpo no se evaluará. Para cada valor enumerado de la variable de bucle se evalúan las sentencias en el cuerpo del bucle. La palabra clave opcional REVERSE especifica iterar el rango en orden descendente.