Desenvolver lógica personalizada usando SQL

Trabalhando com SQLScript

Objective

After completing this lesson, you will be able to descreva os recursos adicionais fornecidos pelo SQLScript em comparação com o SQL padrão.

Recursos SQLScript

SQLScript é uma linguagem de banco de dados desenvolvida pela SAP. Ele é baseado no SQL padrão, mas adiciona recursos adicionais para explorar os recursos avançados do SAP HANA Cloud.

Aqui estão alguns dos principais recursos do SQL Script:

  • SQLScript estende o SQL ANSI-92. Assim como outros fornecedores de banco de dados ampliam o SQL em seus bancos de dados, o SAP HANA estende o SQL usando SQLScript.
  • O SQLScript permite que você acesse recursos específicos do SAP HANA, como tabelas de colunas, visões de informações parametrizadas, buffers delta, trabalho com vários conjuntos de resultados em paralelo, conversões de moeda integradas no nível do banco de dados, pesquisa de texto fuzzy, tipos de dados espaciais e bibliotecas de análise preditiva.
  • SQLScript permite que os desenvolvedores enviem lógica intensiva de dados para o banco de dados.
  • SQLScript incentiva os desenvolvedores a manter algoritmos usando um paradigma orientado a conjuntos, em vez de um registro em um paradigma de tempo.
  • SQLScript, no entanto, permite looping através de resultados e usando a lógica if-then-else
  • O SQLScript permite que você divida consultas complexas em várias instruções menores, simplificando assim sua codificação SQL e aprimorando o paralelismo por meio do otimizador.

Nota

A versão do SQL padrão em que o SQLScript é baseado é a versão popular ANSI-92, que é suportada por quase todos os bancos de dados.

Recursos adicionais do SQLScript incluem trabalhar com tabelas de colunas do SAP HANA Cloud, transferir parâmetros entre visões de cálculo e SQLScript, trabalhar com tipos de dados espaciais e bibliotecas de análise preditiva.

Desenvolver lógica empresarial com SQLScript

Nas abordagens cliente-servidor tradicionais, a lógica empresarial é definida e executada no servidor de aplicação utilizando linguagens de programação de aplicação como ABAP ou C++. Com o SAP HANA Cloud, grande parte dessa lógica agora pode ser definida usando SQLScript, que permite que o desenvolvedor defina e execute todas as tarefas de processamento de dados no banco de dados para obter um desempenho aprimorado.

O SQLScript permite que você use variáveis para dividir uma instrução SQL complexa grande em instruções menores e mais simples. Isso torna o código muito mais fácil de entender. Ele também ajuda no desempenho do SQL HANA Cloud porque muitas dessas instruções menores podem ser executadas em paralelo.

Assista a este vídeo para ver um exemplo:

No exemplo estudado, queremos descobrir qual editora tem mais livros:

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);

O compilador e otimizador SQLScript determina como executar melhor essas instruções, seja usando uma expressão de subconsulta comum com dicas de banco de dados ou combinando isso em uma única consulta complexa. O código se torna mais fácil de escrever e entender, mais sustentável e a produtividade do desenvolvedor aumenta.

Ao dividir o SQLScript em instruções menores e preencher variáveis de tabela, você também espelha o modo como aprendeu a criar suas visões de cálculo. Assim como quando você começa a criar visões de cálculo em camadas, começando de baixo para cima, você faz o mesmo com seu código SQLScript. Considere que a sequência exata das suas etapas SQLScript não é necessariamente a ordem de tempo de execução, porque o otimizador irá sempre decidir sobre o melhor plano de execução. No entanto, o otimizador nunca alterará o resultado desejado. Isso também é válido para visões de cálculo.

O uso de variáveis

O uso de variáveis em instruções SQL não é especificado pelo SQL ANSI-92. No SAP HANA Cloud, o SQLScript implementa o conceito de variável como uma extensão para o SQL ANSI-92.

As variáveis podem ser declaradas, atribuídas e reutilizadas dentro de um script.

Uso de variáveis no SQLScript

  • Declarar uma variável

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

    Exemplo 1: DECLARE a int;

    Exemplo 2: DECLARE b int = 0; (o valor é atribuído ao criar a variável)

  • Atribuir uma variável (definir o valor de uma variável)

    <variable_name> = <value> or <expression>

    Exemplo 1: a = 3;

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

  • Usar uma variável em uma expressão

    :<variable_name> (com dois pontos) retorna o valor atual da variável

    Exemplo: b = :a + 5; (atribui o valor de a + 5 a b)

Tipos de dados SQLScript

O SQLScript também adiciona tipos de dados extras para ajudar a resolver os recursos ausentes do SQL padrão, por exemplo, tipos de dados espaciais e tipos de dados de texto.

Tipos de dados ANSI-92 e SQLScript

ClassificaçãoTipos de dados ANSI-92 padrãoTipos de dados específicos de SQLScript
Data/horaDATA, HORA, TIMESTAMPSECONDDATE
NuméricoDECIMAL, INTEGER, SMALLINT, FLOAT, REAL, DOUBLETINYINT, BIGINT, SMALLDECIMAL
Cadeia de caracteresCHAR, NCHAR, VARCHAR, NVARCHARALPHANUM, SHORTTEXT
BinárioBINÁRIO, VARBINÁRIO 
Objeto grande BLOB, CLOB, NCLOB, TEXT, BINTEXT
Booleano BOOLEANO
Espacial ST_POINT, ST_GEOMETRY

Processamento de parâmetros de entrada definidos nas visões de cálculo com SQLScript

Quando você usa uma instrução select em SQLScript para consultar uma visão de cálculo que tem parâmetros de entrada, você usa a palavra-chave PLACEHOLDER com o nome do parâmetro de entrada empacotado em símbolos $$ e o valor que deseja transferir para o parâmetro de entrada - por exemplo:

Transferência de parâmetros de entrada para a visão de cálculo

Use a palavra-chave PLACEHOLDER para transferir parâmetros de entrada para a visão de cálculo em uma instrução select:

Code Snippet
1234
SELECT "PRODUCT", sum("TAXED_AMOUNT") FROM "_SYS_BIC"."MyPackage/SalesResults" ('PLACEHOLDER' = ('$$Tax Amount$$', '17.5')) GROUP BY "PRODUCT"
Referência ao parâmetro de entrada no script SQL

No SQLScript, você faz referência ao parâmetro de entrada usando dois pontos:;

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

Também é possível transferir parâmetros de saída gerados de um SQLScript para uma visão de cálculo usando o recurso de mapeamento de parâmetros.

Lógica de loop e condicional

Em geral, o código SQL é escrito de forma declarativa. Isso significa que você indica a intenção da ação e não determina como as etapas de processamento de dados devem ser executadas em uma determinada ordem. Fazemos isso para que você permita que o otimizador SQL descubra o melhor plano de execução com base em muitos fatores dinâmicos no momento da execução.

No entanto, às vezes você precisa controlar a lógica de processamento do SQL para que as etapas sejam executadas em uma determinada ordem. Por exemplo, quando você precisa executar uma etapa somente se uma determinada condição for cumprida ou se precisar fazer loop várias vezes. Nesses casos, você usará a lógica imperativa.

Isso (principalmente) não está disponível no ANSI SQL e, portanto, o SAP HANA fornece linguagem de lógica declarativa como parte do SQLScript para fornecer controle de fluxo.

A falta de linguagem lógica imperativa é o que muitas vezes faz com que o desenvolvedor mova o processamento de dados para a camada de aplicação. Quando uma aplicação é executada no HANA, você realmente deve enviar o máximo possível de processamento de dados para o banco de dados. A lógica imperativa do SAP HANA SQLScript permite que isso reduza a necessidade de processamento de dados nas camadas de aplicação, e muito mais pode ser feito no banco de dados.

Dica

Lembre-se de que a lógica imperativa não pode ter o mesmo desempenho que a lógica declarativa. Isso ocorre porque o otimizador SQL não é livre para decidir sobre a sequência de etapas e tem que tomar cuidado para seguir sua lógica, o que pode destruir otimizações. Se você precisar da melhor performance, tente evitar a lógica imperativa.

Lógica condicional

A instrução IF
Code Snippet
12345678910
IF <bool-expr1> THEN {then-stmts1} {ELSEIF <bool-expr2> THEN {then-stmts2}} {ELSE {else-stmts3}} END IF
Exemplo de uma instrução IF usando uma cláusula ELSE.

A figura anterior mostra um exemplo da instrução IF, que consiste em uma expressão booleana, :found is NULL. Se a expressão for avaliada como verdadeira, a instrução CALL ins_msg_proc('result of count(*) cannot be NULL'); no bloco obrigatório THEN é executada. A declaração IF termina com END IF. As peças restantes são opcionais.

Se a expressão booleana :found is NULL não for avaliada como verdadeira, a ramificação ELSE é avaliada. Na maioria dos casos, esta ramificação começa com ELSE. A instrução CALL ins_msg_proc('result of count(*) not NULL- as expected'); é executada sem mais verificações. Depois de uma outra ramificação, não são permitidas mais ELSE ramificação ou ELSEIF ramificação.

Como alternativa, quando ELSEIF é usado em vez de ELSE, outra expressão booleana pode ser avaliada. Se ela for avaliada como verdadeira, é executada a seguinte instrução. Você pode adicionar um número arbitrário de cláusulas ELSEIF desta forma.

Esta instrução pode ser usada para simular a instrução switch-case conhecida de muitas linguagens de programação.

WHILE e FOR Loops

O loop WHILE
Code Snippet
123
WHILE <bool-stmt> DO {stmts} END WHILE
O loop WHILE executa a instrução stmts no corpo do loop, desde que a expressão booleana no início bool-stmt do loop seja avaliada como verdadeira.
O loop FOR
Code Snippet
123
FOR <loop-var> IN {REVERSE} <start>..<end> DO {stmts} END FOR
O loop FOR itera um intervalo de valores numéricos – indicado pelo início e pelo fim na sintaxe – e vincula o valor atual a uma variável (loop-var) em ordem crescente. A iteração começa com o início do valor e é incrementada em um até que o loop-var seja maior que o fim.

Por isso, se o início for maior que o fim, o loop do corpo não será avaliado. Para cada valor enumerado da variável loop, as instruções no corpo do loop são avaliadas. A palavra-chave opcional REVERSE especifica a iteração do intervalo em ordem decrescente.