Sooner or later, every HANA developer hits a wall with plain SQL. You need loops, conditionals, cursors, exception handling — real procedural logic — but you need it running inside the database, close to the data, not in a loop in ABAP or Node.js dragging rows back and forth. That's what SQLScript is for.
This post covers SQLScript, how ABAP calls it through AMDP, and where calculation views fit — including what's deprecated and what replaced it.
SQLScript: procedural logic inside HANA
SQLScript is HANA's extension of SQL with procedural constructs: variables, IF/CASE branches, loops, cursors, exception handlers, and table variables. The key idea is set-based processing — you operate on whole tables at once instead of row-by-row, and the database engine parallelizes it across cores.
A simple example — a procedure that computes total revenue per region:
CREATE PROCEDURE GET_REVENUE_BY_REGION (
OUT result TABLE (REGION NVARCHAR(50), REVENUE DECIMAL(15,2))
)
LANGUAGE SQLSCRIPT AS
BEGIN
result = SELECT region,
SUM(amount) AS revenue
FROM SALES_ORDERS
GROUP BY region;
END;
Nothing fancy, but notice the pattern: SQLScript procedures take table-typed parameters and return tables. They compose — one procedure's output feeds the next. The golden rule: keep it declarative and set-based. The moment you write a cursor loop over a million rows, you've usually lost the plot; there's almost always a set-based rewrite.
Key takeaway: SQLScript brings procedural logic into the database so compute-heavy work runs where the data lives. Write it set-based — table in, table out — and let HANA parallelize it.
AMDP: calling SQLScript from ABAP
ABAP developers don't write SQLScript directly. They use AMDP — ABAP Managed Database Procedures. An AMDP is an ABAP class method whose body is SQLScript, managed by the ABAP development tools (transport, syntax check, activation) but executed on the HANA database.
CLASS zcl_revenue_calc DEFINITION PUBLIC.
PUBLIC SECTION.
INTERFACES if_amdp_marker_hdb.
METHODS get_revenue
IMPORTING VALUE(iv_year) TYPE gjahr
EXPORTING VALUE(et_result) TYPE ztt_revenue.
ENDCLASS.
CLASS zcl_revenue_calc IMPLEMENTATION.
METHOD get_revenue BY DATABASE PROCEDURE
FOR HDB LANGUAGE SQLSCRIPT.
et_result = SELECT region, SUM(amount) AS revenue
FROM sales_orders
WHERE year = :iv_year
GROUP BY region;
ENDMETHOD.
ENDCLASS.
The classic use case: logic too complex for a CDS view but too data-intensive to pull into the ABAP layer. Aggregations over huge tables, multi-step transformations, anything where moving the data would cost more than moving the logic. If you find yourself SELECTing a million rows into an internal table just to loop and aggregate — that's an AMDP-shaped problem.
Calculation views: the modeling layer
Calculation views are HANA's graphical (and SQL-based) modeling artifacts — the successors of the old analytic/attribute views. You build them in the database explorer by combining tables with joins, unions, aggregations, and filters, or you write them in SQL. They expose a clean, consumable result set that reporting tools, CDS table functions, and applications query like a table.
A typical pattern: a calculation view joins sales orders to customers and products, computes derived measures, and exposes it all as one virtual table. Downstream consumers never see the complexity.
Under the hood, calculation views execute on HANA's calculation engine — the optimizer path specifically built for these composed, columnar operations. When someone asks "which engine processes calculation views," that's the answer: not the row engine, not the join engine — the calculation engine.
What's deprecated (and what replaced it)
This trips people up in interviews and in real projects: scripted calculation views were deprecated back in HANA 1.0 SPS 11. The old approach — embedding SQLScript directly inside a calculation view — is dead.
The replacement is the CDS table function: you write the SQLScript in an AMDP method, then expose it as a CDS entity via a table function definition. Consumers query it like any other CDS view, but the heavy logic runs as SQLScript on the database.
-- CDS table function definition
@EndUserText.label: 'Revenue by region'
DEFINE TABLE FUNCTION ZTF_REVENUE_BY_REGION
WITH PARAMETERS @Environment.systemField: #CLIENT
clnt : abap.clnt,
year : abap.numc(4)
RETURNS {
client : abap.clnt;
region : abap.char(50);
revenue : abap.curr(15,2);
}
IMPLEMENTED BY METHOD zcl_revenue_calc=>get_revenue;
So the modern stack is: SQLScript in AMDP for the logic, table function to expose it, calculation views (graphical or SQL-based) for pure modeling. Scripted calc views belong in migration plans, not new designs.
Key takeaway: put procedural logic in SQLScript (via AMDP from ABAP), model with graphical or SQL calculation views, and expose scripted logic through CDS table functions. Scripted calculation views are deprecated — don't build new ones.