CDS Scalar Functions
Quando o CDS não tem a função que você precisa
O HANA tem a função WEEKDAY(). O ABAP CDS, não. Antes da release 2308, você ficava preso: ou reimplementava a lógica de forma desajeitada em CDS, ou descia para uma AMDP table function só para devolver uma coluna. As AMDP scalar functions existiam, mas não eram acessíveis de dentro do CDS.
As CDS Scalar Functions resolvem isso. Desde o ABAP 2308, você pode encapsular lógica SQLScript do HANA num objeto e usá-lo como se fosse uma função nativa do CDS — direto na lista de SELECT, no GROUP BY, em qualquer posição que espere um valor escalar. A execução roda no banco (push-down), e a lógica fica reutilizável em quantas views você quiser.
Este guia mostra como criar uma CDS Scalar Function do zero: os três objetos que a compõem, a sintaxe de cada um, a ordem de ativação que evita erros e quando o recurso realmente vale a pena.
O essencial em 4 linhas
Uma CDS Scalar Function recebe parâmetros e devolve um valor escalar, usável como built-in dentro de qualquer CDS view.
São três objetos: a Definition (
DEFINE SCALAR FUNCTION), uma Implementation Reference (objeto separado, form-based) e o método AMDP (FOR SCALAR FUNCTION).O método AMDP roda SQLScript no HANA, com interface derivada implicitamente da definition e retorno na variável
result.Disponível no S/4HANA 2023 (FPS00) e no ABAP Cloud. Use quando falta uma built-in; não use para lógica tabular (aí é table function).
O que é uma CDS Scalar Function?
Uma CDS Scalar Function é uma função user-defined que aceita parâmetros de entrada e retorna exatamente um valor escalar — uma coluna, uma linha. A novidade da release 2308 ("CDS Scalar Functions Implemented by AMDP") foi tornar as AMDP scalar functions conhecidas pelo ABAP Dictionary e, portanto, utilizáveis dentro do CDS. Antes disso, elas viviam isoladas no mundo AMDP.
No exemplo que dá origem a quase todo tutorial do tema: você precisa converter uma data em dia da semana. O HANA tem WEEKDAY(), o CDS não — então você cria uma scalar function que delega ao HANA via AMDP e passa a chamá-la como se fosse nativa.
Quando usar (e quando não usar)?
Use uma CDS Scalar Function quando precisa de uma função SQL nativa do HANA que não existe como built-in do CDS (WEEKDAY, funções geoespaciais, regex), e quando quer reusar essa lógica em várias views com push-down ao banco. O candidato ideal é uma lógica estável, determinística e de retorno escalar.
Quando evitar:
Já existe uma built-in equivalente (
division,abs,currency_conversion,concat) — use a built-in.A lógica precisa retornar múltiplas linhas/colunas → use uma AMDP Table Function.
Envolve loops complexos ou estado mutável → isso é trabalho de classes ABAP.
A lógica será usada uma única vez — o overhead dos três objetos não compensa.
Quais são os três objetos?
Esta é a parte que mais confunde quem está começando: a CDS Scalar Function não é um objeto só, são três, e eles são separados de propósito. A documentação da SAP (Release News 2308) deixa explícito:
# | Objeto | Função |
|---|---|---|
1 | CDS Scalar Function Definition | A assinatura: parâmetros e tipo de retorno ( |
2 | Implementation Reference | Objeto separado, editor form-based no ADT, que liga a definition à engine e ao método AMDP. |
3 | AMDP Function Implementation | Método estático em classe AMDP, com |
Ponto que confunde muita gente: a DDL define scalar function não contém uma cláusula implementation ... by method. O vínculo entre a definition e o método AMDP é feito pelo objeto separado de Implementation Reference (no abapGit, são tipos distintos: DSFD para a definition e DSFI para a reference). Não tente colocar o método dentro da DDL — não é assim que a feature 2308 funciona.
Como definir a função (DEFINE SCALAR FUNCTION)?
A Definition é um objeto DDL simples: declara os parâmetros tipados e o tipo de retorno escalar, terminando com ponto e vírgula. Sem cláusula de implementação:
define scalar function ZGETWEEKDAY
with parameters
input_date : abap.datn
returns abap.char( 3 );A forma geral aceita vários parâmetros:
define scalar function function_name
with parameters
param1 : type1,
param2 : type2
returns return_type;Em seguida, você cria a Implementation Reference pelo wizard do ADT (New → Other ABAP Repository Object → Core Data Services → Scalar Function Implementation). É um editor form-based: você seleciona a definition, a engine e aponta a classe e o método AMDP. Não há código a digitar aqui.
Observação: aqui a implementação é o mesmo nome do definition da scalar function, porém com um fuxino no final _SQL para engine de seleção, para casos analíticos se utiliza o sufixo _ANA .
Em seguida adicionamos a classe AMDP no AMDP Reference:
Como implementar a lógica via AMDP (FOR SCALAR FUNCTION)?
A implementação fica numa classe AMDP que implementa IF_AMDP_MARKER_HDB, com um método estático marcado com FOR SCALAR FUNCTION. O corpo é SQLScript puro, executado no HANA:
CLASS zcl_okt_scalar_functions DEFINITION
PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_amdp_marker_hdb.
CLASS-METHODS get_weekday
FOR SCALAR FUNCTION zgetweekday.
ENDCLASS.
CLASS zcl_okt_scalar_functions IMPLEMENTATION.
METHOD get_weekday
BY DATABASE FUNCTION
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY.
-- HANA WEEKDAY() retorna 0=Monday ... 6=Sunday
result := CASE WEEKDAY( :input_date )
WHEN 0 THEN 'MON'
WHEN 1 THEN 'TUE'
WHEN 2 THEN 'WED'
WHEN 3 THEN 'THU'
WHEN 4 THEN 'FRI'
WHEN 5 THEN 'SAT'
WHEN 6 THEN 'SUN'
END;
ENDMETHOD.
ENDCLASS.Quatro detalhes definem o padrão e são fáceis de errar:
Interface implícita: você não declara
IMPORTING/RETURNING— os parâmetros são derivados automaticamente da definition.Retorno em
result: a variável de retorno é sempreresult; você atribui o valor a ela.OPTIONS READ-ONLYé obrigatório — funções escalares não modificam dados.DETERMINISTICé opcional: adicione apósOPTIONSse a mesma entrada sempre produz a mesma saída — o HANA passa a bufferizar o resultado durante a query.
Detalhe do ABAP Cloud: em ambientes Cloud, o método AMDP exige a adição de manuseio de cliente — CDS SESSION CLIENT DEPENDENT ou CDS SESSION CLIENT INDEPENDENT — para deixar explícito o comportamento multi-cliente. On-premise (S/4HANA 2023 FPS00) isso não é exigido da mesma forma.
Como usar a função numa CDS view?
Depois de ativada, você chama a função como qualquer built-in, usando o operador de argumento nomeado =>. No cenário do dia da semana:
define view entity ZI_OKT_RESERVATION_BY_WEEKDAY
as select from ZI_OKT_RESERVATION_ANALYSIS
{
key reservation_id,
reservation_dt,
zgetweekday( input_date => reservation_dt ) as Weekday,
AmountInEur,
status
}E porque ela se comporta como built-in, dá para usá-la até no GROUP BY, combinando com agregação:
define view entity ZI_OKT_RESERVATIONS_PER_WEEKDAY
as select from ZI_OKT_RESERVATION_ANALYSIS
{
zgetweekday( input_date => reservation_dt ) as Weekday,
count( * ) as ReservationCount,
sum( AmountInEur ) as TotalAmount
}
group by zgetweekday( input_date => reservation_dt )Outro exemplo clássico é uma razão reutilizável. A definition e o método AMDP, lado a lado:
define scalar function ZI_DEMO_RATIO
with parameters
portion : abap.decfloat34,
total : abap.decfloat34
returns abap.decfloat34;METHOD calc_ratio
BY DATABASE FUNCTION FOR HDB
LANGUAGE SQLSCRIPT OPTIONS READ-ONLY.
result := :portion / :total * 100;
ENDMETHOD.Uma nota honesta: passar uma expressão agregada ou de janela (como sum(x) over()) diretamente como argumento da função é algo que não consegui confirmar na documentação oficial. Se o seu cenário precisa disso, calcule a agregação numa view intermediária e passe o campo já agregado como parâmetro — ou valide o suporte na sua release antes de depender disso.
Qual a ordem de ativação?
A ordem de criação e ativação importa, porque os objetos têm dependências entre si. A sequência correta é:
Ative a Scalar Function Definition (objeto DDL).
Crie e ative a Implementation Reference.
Implemente o método AMDP na classe e ative.
Inverter essa ordem tende a gerar erros de ativação por dependências ainda não resolvidas. Uma cautela prática para transportes: a definition viaja com os objetos de dicionário (DDIC) e o método AMDP com os objetos ABAP — planeje o transporte das duas partes em conjunto para que a função não chegue incompleta no destino.
Scalar Function ou Table Function: qual usar?
As duas rodam SQLScript no HANA via AMDP, mas devolvem coisas diferentes. A escolha é direta: precisa de um valor? Scalar. Precisa de um conjunto de linhas? Table.
Aspecto | Scalar Function | Table Function |
|---|---|---|
Retorno | Valor escalar (1 coluna/1 linha) | Resultado tabular (N colunas/N linhas) |
Uso | Em posição de operando (como built-in) | Como data source (no |
DDL |
|
|
Método AMDP |
|
|
Quando usar | Cálculos pontuais reutilizáveis | Consultas complexas inteiras |
Onde está disponível e quais engines existem?
O recurso está disponível no SAP S/4HANA 2023 (FPS00) on-premise/privado e no ABAP Cloud (SAP BTP ABAP environment e S/4HANA Cloud). Quanto às engines, a arquitetura prevê duas — daí a convenção de sufixo _SQL e _ANA — mas há uma ressalva importante.
Correção sobre as engines: para funções escalares definidas por você (customer/partner), apenas a engine HANA SQL (_SQL) é selecionável na prática. A engine analítica (_ANA) é reservada às funções analíticas pré-entregues pela SAP. Então, ao criar a sua scalar function, espere usar _SQL.
Perguntas frequentes
Qual a diferença entre AMDP scalar function e CDS scalar function?
A AMDP scalar function sempre existiu, mas era acessível só no mundo AMDP. A CDS Scalar Function (release 2308) é o que torna essa lógica conhecida pelo ABAP Dictionary e utilizável dentro do CDS, como built-in. Na prática, a CDS Scalar Function é implementada por um método AMDP — as duas trabalham juntas.
Preciso declarar os parâmetros no método AMDP?
Não. A interface do método (parâmetros de entrada e retorno) é derivada implicitamente da Scalar Function Definition. Você só escreve o método com FOR SCALAR FUNCTION e atribui o resultado à variável result — sem IMPORTING/RETURNING manuais.
A DEFINE SCALAR FUNCTION leva uma cláusula de implementação?
Não. A DDL da definition só tem parâmetros e returns, terminando com ponto e vírgula. O vínculo com o método AMDP é feito por um objeto separado — a Implementation Reference (form-based no ADT) — e não por uma cláusula implementation ... by method dentro da DDL.
Quando devo marcar a função como DETERMINISTIC?
Só quando a mesma entrada sempre produz a mesma saída — nada de tabelas mutáveis ou funções de tempo corrente. O DETERMINISTIC é opcional e vem após OPTIONS; ele permite ao HANA bufferizar o resultado durante a query. Marcá-lo numa função não-determinística devolve resultados incorretos cacheados.
Posso usar a função em ABAP SQL, fora do CDS?
Sim. Por ser conhecida pelo Dictionary, a CDS Scalar Function pode ser usada em posições de operando também em ABAP SQL, não só dentro de CDS views. Isso a torna um ponto único de reuso para a lógica escalar — uma correção propaga para todos os consumidores, sem copy-paste.
Conclusão
As CDS Scalar Functions fecham uma lacuna antiga do ABAP CDS: usar lógica SQLScript do HANA como se fosse uma função nativa, com push-down e reuso real. O caminho são três objetos — Definition, Implementation Reference e método AMDP — ativados nessa ordem, com a interface derivada automaticamente e o retorno em result.
Guarde a regra de bolso: só crie uma scalar function quando não houver built-in equivalente e a lógica for escalar, determinística e reutilizável. Para resultados tabulares, o caminho é a table function. E lembre que a implementação não mora na DDL — mora no método AMDP, conectado pela Implementation Reference.
Referências oficiais
Comentários 0
Ainda sem comentários
Seja o primeiro a comentar este artigo.
Entre na conversa
Faça login para deixar seu comentário neste artigo.