All skills
secondsky avatar

/sap-sqlscript

@620a19a
by Eddiesecondsky/sap-skills456 stars
120

This skill should be used when the user asks to "write a SQLScript procedure", "create HANA stored procedure", "implement AMDP method", "optimize SQLScript performance", "handle SQLScript exceptions", "debug HANA procedure", "create table function", "inspect a browser-based Datasphere SQL editor with Microsoft Edge CDP", or mentions SQLScript, SAP HANA procedures, AMDP, EXIT HANDLER, or code-to-data paradigm. Comprehensive SQLScript development guidance for SAP HANA database programming including syntax patterns, built-in functions, exception handling, performance optimization, cursor management, and ABAP Managed Database Procedure (AMDP) integration.

Use this Skill: https://skilld.dev/gh/secondsky/sap-skills/sap-sqlscript

This session only. Nothing lands on disk.

referencessyntax-reference.md

≈2.8k tokens on demand. Your agent reads this file only when SKILL.md points to it.

SQLScript Complete Syntax Reference

Table of Contents

Procedure Syntax

CREATE PROCEDURE

CREATE [OR REPLACE] PROCEDURE <schema_name>.<procedure_name>
  (
    [IN <parameter_name> <sql_type> [DEFAULT <default_value>]],
    [OUT <parameter_name> <sql_type>],
    [INOUT <parameter_name> <sql_type>]
  )
  LANGUAGE SQLSCRIPT
  [SQL SECURITY {DEFINER | INVOKER}]
  [DEFAULT SCHEMA <schema_name>]
  [READS SQL DATA]
  [WITH RESULT VIEW <view_name>]
  [DETERMINISTIC]
AS
BEGIN
  [SEQUENTIAL EXECUTION]
  <procedure_body>
END;

Note: SEQUENTIAL EXECUTION forces the procedure to execute sequentially without parallelism. This is rarely needed but can be useful for procedures that rely on side effects or specific ordering guarantees.

Parameter Modes

Mode Description
IN Input parameter (read-only within procedure)
OUT Output parameter (write-only, initial value undefined)
INOUT Input and output (read/write)

Security Modes

Mode Description
SQL SECURITY DEFINER Execute with privileges of procedure owner
SQL SECURITY INVOKER Execute with privileges of caller

Function Syntax

Scalar User-Defined Function

CREATE [OR REPLACE] FUNCTION <schema_name>.<function_name>
  (
    <parameter_name> <sql_type> [DEFAULT <value>],
    ...
  )
RETURNS <return_type>
LANGUAGE SQLSCRIPT
[SQL SECURITY {DEFINER | INVOKER}]
[DEFAULT SCHEMA <schema_name>]
[DETERMINISTIC]
AS
BEGIN
  DECLARE result <return_type>;
  -- function logic
  RETURN result;
END;

Table User-Defined Function

CREATE [OR REPLACE] FUNCTION <schema_name>.<function_name>
  (
    <parameter_name> <sql_type> [DEFAULT <value>],
    ...
  )
RETURNS TABLE (
  <column_name> <sql_type>,
  ...
)
LANGUAGE SQLSCRIPT
SQL SECURITY INVOKER
READS SQL DATA
[DEFAULT SCHEMA <schema_name>]
AS
BEGIN
  RETURN SELECT <columns> FROM <source>;
END;

Anonymous Block Syntax

DO [(<parameter_clause>)]
BEGIN [SEQUENTIAL EXECUTION]
  <block_body>
END;

With Parameters

DO (
  IN iv_input INTEGER => 100,
  OUT ov_output INTEGER => ?
)
BEGIN
  ov_output = :iv_input * 2;
END;

Variable Declaration Syntax

Scalar Variables

DECLARE <variable_name> <sql_type> [:= <initial_value>];
DECLARE <var1>, <var2> <sql_type>;  -- Multiple variables same type

Constant Variables

DECLARE <constant_name> CONSTANT <sql_type> := <value>;

Table Variables

-- Inline definition
DECLARE <table_var> TABLE (
  <column_name> <sql_type> [NOT NULL],
  ...
);

-- From existing table structure
DECLARE <table_var> TABLE LIKE <table_name>;
DECLARE <table_var> TABLE LIKE :<other_table_var>;

-- From table type
DECLARE <table_var> <table_type_name>;

Array Variables

DECLARE <array_name> <sql_type> ARRAY;
DECLARE <array_name> <sql_type> ARRAY := ARRAY(<value1>, <value2>, ...);

Assignment Syntax

Scalar Assignment

<variable> := <expression>;
<variable> = <expression>;  -- Alternative syntax

SELECT INTO

SELECT <column> INTO <variable> FROM <table> [WHERE ...];
SELECT <col1>, <col2> INTO <var1>, <var2> FROM <table>;

Table Variable Assignment

<table_var> = SELECT <columns> FROM <table>;
<table_var> = :<other_table_var>;

Control Flow Syntax

IF-THEN-ELSE

IF <condition> THEN
  <statements>
[ELSEIF <condition> THEN
  <statements>]
[ELSE
  <statements>]
END IF;

CASE Expression

-- Simple CASE
CASE <expression>
  WHEN <value1> THEN <result1>
  WHEN <value2> THEN <result2>
  ELSE <default_result>
END

-- Searched CASE
CASE
  WHEN <condition1> THEN <result1>
  WHEN <condition2> THEN <result2>
  ELSE <default_result>
END

WHILE Loop

WHILE <condition> DO
  <statements>
END WHILE;

DO n TIMES Loop

Repeat a block a fixed number of times:

DO <n> TIMES
BEGIN
  <statements>
END;

Example:

DO 10 TIMES
BEGIN
  INSERT INTO "LOG_TABLE" (message) VALUES ('Iteration');
END;

FOR Loop

-- Numeric range (inclusive on both ends)
FOR <var> IN [REVERSE] <start>..<end> DO
  <statements>
END FOR;

-- Cursor iteration
FOR <row_var> AS <cursor_name> DO
  <statements using row_var.column_name>
END FOR;

-- Inline cursor
FOR <row_var> AS (SELECT <columns> FROM <table>) DO
  <statements>
END FOR;

Range Semantics: The numeric FOR loop range is inclusive on both bounds. FOR i IN 1..5 iterates with i = 1, 2, 3, 4, 5 (five iterations total).

LOOP with EXIT

LOOP
  <statements>
  IF <condition> THEN
    BREAK;  -- or LEAVE
  END IF;
  [CONTINUE;]  -- Skip to next iteration
END LOOP;

Cursor Syntax

Declaration

DECLARE CURSOR <cursor_name> FOR
  <select_statement>;

-- With parameters
DECLARE CURSOR <cursor_name> (<param> <type>) FOR
  SELECT * FROM <table> WHERE col = :<param>;

Operations

OPEN <cursor_name>;
OPEN <cursor_name> (<param_value>);

FETCH <cursor_name> INTO <var1>, <var2>, ...;

CLOSE <cursor_name>;

Cursor Attributes

Attribute Type Description Typical Usage
<cursor>::ISCLOSED BOOLEAN TRUE if cursor is closed Check before OPEN to avoid "already open" error
<cursor>::NOTFOUND BOOLEAN TRUE if FETCH found no row Loop termination condition after FETCH
<cursor>::ROWCOUNT INTEGER Number of rows fetched so far Progress tracking, batch processing limits

Usage Example:

WHILE NOT cur::NOTFOUND DO  -- Check NOTFOUND to exit loop
  FETCH cur INTO lv_var;
  IF cur::ROWCOUNT > 1000 THEN  -- Limit processing
    BREAK;
  END IF;
END WHILE;

Table Type Syntax

CREATE TYPE

CREATE TYPE <schema_name>.<type_name> AS TABLE (
  <column_name> <sql_type> [NOT NULL],
  ...
);

DROP TYPE

DROP TYPE <schema_name>.<type_name> [CASCADE];

Exception Handling Syntax

EXIT HANDLER

DECLARE EXIT HANDLER FOR <condition>
  <statement>;

DECLARE EXIT HANDLER FOR <condition>
BEGIN
  <statements>
END;

CONTINUE HANDLER

CONTINUE HANDLER catches exceptions and continues execution of the procedure (unlike EXIT HANDLER which suspends execution):

DECLARE CONTINUE HANDLER FOR <condition>
  <statement>;

DECLARE CONTINUE HANDLER FOR <condition>
BEGIN
  <statements>
END;

Note: Use CONTINUE HANDLER when you want to log errors and continue processing. See references/exception-handling.md for detailed comparison of EXIT vs CONTINUE handlers.

Condition Declaration

DECLARE <condition_name> CONDITION FOR SQL_ERROR_CODE <number>;

SIGNAL

SIGNAL <condition_name>;
SIGNAL <condition_name> SET MESSAGE_TEXT = '<message>';
SIGNAL SQL_ERROR_CODE <number> SET MESSAGE_TEXT = '<message>';

RESIGNAL

RESIGNAL;
RESIGNAL <condition_name>;
RESIGNAL SET MESSAGE_TEXT = '<message>';

Table Variable Operators

INSERT

:<table_var>.INSERT((<value1>, <value2>, ...));
:<table_var>.INSERT(:<other_table_var>);
:<table_var>.INSERT(:<other_table_var>, <row_number>);

UPDATE

:<table_var>.UPDATE((<new_value1>, <new_value2>, ...), <row_number>);

DELETE

:<table_var>.DELETE(<row_number>);
:<table_var>.DELETE(<start_row>, <count>);

SEARCH

<position> = :<table_var>.SEARCH((<column_name>, <search_value>), <start_position>);

UNNEST Function

Convert array to table:

UNNEST(<array1> [, <array2>, ...]) [WITH ORDINALITY]
  AS <table_alias> (<col1> [, <col2>, ...] [, <ordinality_col>])

Example:

DECLARE arr INTEGER ARRAY := ARRAY(10, 20, 30);
lt_result = SELECT * FROM UNNEST(:arr) AS t(value);

Dynamic SQL Syntax

EXECUTE IMMEDIATE

EXECUTE IMMEDIATE <sql_string>;
EXECUTE IMMEDIATE <sql_string> INTO <variable>;
EXECUTE IMMEDIATE <sql_string> USING <param1>, <param2>, ...;

EXEC (Procedure Call)

EXEC <sql_string>;

Warning: Avoid dynamic SQL for performance and security reasons.


Operators

Arithmetic

Operator Description
+ Addition
- Subtraction
* Multiplication
/ Division
% Modulo

String

Operator Description
|| Concatenation

Comparison

Operator Description
= Equal
!=, <> Not equal
< Less than
> Greater than
<= Less than or equal
>= Greater than or equal
BETWEEN Range check
IN Set membership
LIKE Pattern matching
IS NULL NULL check
IS NOT NULL Not NULL check

Logical

Operator Description
AND Logical AND
OR Logical OR
NOT Logical NOT

Comments

-- Single line comment

/* Multi-line
   comment */

/**
 * Documentation comment
 */

Source: SKILL.md on GitHub

1 warning16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill provides a comprehensive set of templates, reference guides, and optimization tips for SAP HANA SQLScript development. It includes production-ready code patterns for stored procedures, functions, and ABAP Managed Database Procedures (AMDP), along with performance and security best practices for the SAP ecosystem.

  • Socket16d

    1 alert: gptAnomaly

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    5/20 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 620a19a. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 weeks ago.

Activeupdated 2 months ago
Other metadata
metadata
{
  "maintainer": "Eduard Jiglau",
  "maintainer_email": "hello@sap-ai-skills.com",
  "website": "https://sap-ai-skills.com",
  "version": "2.4.1",
  "last_verified": "2026-05-31",
  "production_tested": "No; documentation and community references only, no live HANA runtime evidence",
  "sap_hana_version": "2.0 SPS08",
  "hana_cloud_version": "QRC 1/2026",
  "errors_prevented": 15
}

README badge

README badge for secondsky/sap-skills/sap-sqlscript