mcpField
S
sap-sqlscript

sap-sqlscript

github.com/secondsky数据与数据库480724 次安装3 周前更新
代码仓库

关于 sap-sqlscript

面向 SAP HANA 开发者的 SQLScript 技能,涵盖过程式数据库逻辑、AMDP 与性能实践。附带语法、排错和优化参考资料,适用于将数据处理逻辑部署在数据库层。

主要功能

  1. 01匿名块、存储过程与函数
  2. 02变量、游标和异常处理
  3. 03AMDP 集成指导
  4. 04声明式 SQL 性能实践
  5. 05内置参考资料与排错指南

适用场景

  1. 01编写 HANA 存储过程和函数
  2. 02实现 AMDP 数据库逻辑
  3. 03排查 SQLScript 异常
  4. 04优化数据密集型查询

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/secondsky/sap-skills --skill sap-sqlscript

安装后在 Claude Code 中输入/sap-sqlscript确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
agents/
openai.yaml
references/
advanced-features.md
amdp-integration.md
built-in-functions.md
data-types.md
edge-cdp-control.md
exception-handling.md
glossary.md
performance-guide.md
skill-reference-guide.md
syntax-reference.md
troubleshooting.md
templates/
amdp-class.abap
amdp-procedure.sql
bulk-operations.sql
cursor-iteration.sql
procedure-with-error-handling.sql
scalar-function.sql
simple-procedure.sql
table-function.sql

详细介绍

SAP SQLScript 开发指南

何时使用此技能

在编写 SQLScript 过程、匿名块、表函数/标量函数、AMDP 方法、异常处理程序、游标逻辑、批量操作,或需要在靠近数据的位置运行且对 HANA 性能敏感的数据库逻辑时,使用此技能。

对于基于浏览器的 Datasphere 或 HANA Cloud SQL 编辑器问题排查,请使用 sap-browser-automation,以处理应用内手动身份验证、需经用户同意的 Edge 配置文件复用、全新 Edge/CDP 启动、身份验证状态引导和恢复。加载本地 references/edge-cdp-control.md,了解 SQLScript 专属边界。CDP 仅用于本地 UI 检查、控制台诊断、部署消息和经批准的截图;默认情况下,数据库验证仍应使用 SQL/HANA 工具。

概述

SQLScript 是 SAP HANA 对 SQL 的过程式扩展,可在数据库层直接执行复杂的数据密集型逻辑。它遵循代码到数据范式,将计算推送到数据所在的位置,而不是将数据移至应用层。

主要特征
  • 不区分大小写
  • 所有语句都以分号结尾
  • 引用变量时使用冒号前缀(:variableName)
  • 赋值时不加冒号
  • 单行操作使用 DUMMY 表
两种逻辑类型
类型描述执行方式
声明式纯 SQL 序列转换为数据流图,并行处理
命令式控制结构(IF、WHILE、FOR)按顺序处理,会阻止并行执行

目录


容器类型

1. 匿名块

仅使用一次、不存储在数据库中的逻辑。适用于测试和临时执行。

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

示例:

DO
BEGIN
  DECLARE lv_count INTEGER;
  SELECT COUNT(*) INTO lv_count FROM "MYTABLE";
  SELECT :lv_count AS record_count FROM DUMMY;
END;
2. 存储过程

带有输入/输出参数、可重复使用的数据库对象。

CREATE [OR REPLACE] PROCEDURE <procedure_name>
  (
    [IN <param> <datatype>],
    [OUT <param> <datatype>],
    [INOUT <param> <datatype>]
  )
  LANGUAGE SQLSCRIPT
  [SQL SECURITY {DEFINER | INVOKER}]
  [DEFAULT SCHEMA <schema_name>]
  [READS SQL DATA | READS SQL DATA WITH RESULT VIEW <view_name>]
AS
BEGIN
  <procedure_body>
END;
3. 用户定义函数

标量 UDF - 返回单个值:

CREATE FUNCTION <function_name> (<input_parameters>)
RETURNS <scalar_type>
LANGUAGE SQLSCRIPT
AS
BEGIN
  <function_body>
  RETURN <value>;
END;

表 UDF - 返回表(只读):

CREATE FUNCTION <function_name> (<input_parameters>)
RETURNS TABLE (<column_definitions>)
LANGUAGE SQLSCRIPT
READS SQL DATA
AS
BEGIN
  RETURN SELECT ... FROM ...;
END;

数据类型

SQLScript 支持多种数据类型,可用于不同场景。完整文档请参阅 references/data-types.md,其中包括:

  • 数值类型(TINYINT、INTEGER、DECIMAL 等)
  • 字符类型(VARCHAR、NVARCHAR、CLOB 等)
  • 日期/时间类型(DATE、TIME、TIMESTAMP、SECONDDATE)
  • 二进制类型(VARBINARY、BLOB)
  • 类型转换函数(CAST、TO_ 函数)
  • NULL 处理模式

变量声明

标量变量
DECLARE <variable_name> <datatype> [:= <initial_value>];

-- Examples
DECLARE lv_name NVARCHAR(100);
DECLARE lv_count INTEGER := 0;
DECLARE lv_date DATE := CURRENT_DATE;

注意: 未初始化的变量默认为 NULL。

表变量

隐式声明:

lt_result = SELECT * FROM "MYTABLE" WHERE status = 'A';

显式声明:

DECLARE lt_data TABLE (
  id INTEGER,
  name NVARCHAR(100),
  amount DECIMAL(15,2)
);

使用 TABLE LIKE:

DECLARE lt_copy TABLE LIKE :lt_original;
数组
DECLARE arr INTEGER ARRAY := ARRAY(1, 2, 3, 4, 5);
-- Access: arr[1], arr[2], etc. (1-based index)
-- Note: Arrays cannot be returned from procedures

控制结构

IF-ELSE 语句
IF <condition1> THEN
  <statements>
[ELSEIF <condition2> THEN
  <statements>]
[ELSE
  <statements>]
END IF;

比较运算符:

运算符含义
=等于
>大于
<小于
>=大于或等于
<=小于或等于
!=, <>不等于

重要: IF-ELSE 不能在 SELECT 语句中使用。请改用 CASE WHEN。

WHILE 循环
WHILE <condition> DO
  <statements>
END WHILE;
FOR 循环
-- Numeric range
FOR i IN 1..10 DO
  <statements>
END FOR;

-- Reverse
FOR i IN REVERSE 10..1 DO
  <statements>
END FOR;

-- Cursor iteration
FOR row AS <cursor_name> DO
  <statements using row.column_name>
END FOR;
带 EXIT 的 LOOP
LOOP
  <statements>
  IF <condition> THEN
    BREAK;
  END IF;
END LOOP;

表类型

定义可重复使用的表结构:

CREATE TYPE <type_name> AS TABLE (
  <column1> <datatype>,
  <column2> <datatype>,
  ...
);

在过程中使用:

CREATE PROCEDURE get_employees (OUT et_result MY_TABLE_TYPE)
LANGUAGE SQLSCRIPT AS
BEGIN
  et_result = SELECT * FROM "EMPLOYEES";
END;

游标

游标逐行处理结果集。模式:声明 → 打开 → 获取 → 关闭

**性能提示:**游标会绕过数据库优化器,按顺序处理行。主要用于基于主键的查询。尽可能优先使用基于集合的操作。

DECLARE CURSOR <cursor_name> FOR
  SELECT <columns> FROM <table> [WHERE <condition>];

OPEN <cursor_name>;

FETCH <cursor_name> INTO <variables>;

CLOSE <cursor_name>;

完整示例:

DO
BEGIN
  DECLARE lv_id INTEGER;
  DECLARE lv_name NVARCHAR(100);
  DECLARE CURSOR cur_employees FOR
    SELECT id, name FROM "EMPLOYEES" WHERE dept = 'IT';

  OPEN cur_employees;
  FETCH cur_employees INTO lv_id, lv_name;
  WHILE NOT cur_employees::NOTFOUND DO
    -- Process row
    SELECT :lv_id, :lv_name FROM DUMMY;
    FETCH cur_employees INTO lv_id, lv_name;
  END WHILE;
  CLOSE cur_employees;
END;

FOR 循环替代方案:

FOR row AS cur_employees DO
  SELECT row.id, row.name FROM DUMMY;
END FOR;

异常处理

EXIT HANDLER

发生异常时暂停执行并进行清理。

DECLARE EXIT HANDLER FOR <condition_value>
  <statement>;

条件值:

  • SQLEXCEPTION - 任何 SQL 异常
  • SQL_ERROR_CODE <number> - 特定错误代码

访问错误详情:

  • ::SQL_ERROR_CODE - 数字错误代码
  • ::SQL_ERROR_MESSAGE - 错误消息文本

示例:

CREATE PROCEDURE safe_insert (IN iv_id INTEGER, IN iv_name NVARCHAR(100))
LANGUAGE SQLSCRIPT AS
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    SELECT ::SQL_ERROR_CODE AS err_code,
           ::SQL_ERROR_MESSAGE AS err_msg FROM DUMMY;
  END;

  INSERT INTO "MYTABLE" VALUES (:iv_id, :iv_name);
END;
CONDITION

将用户定义的名称与错误代码关联:

DECLARE <condition_name> CONDITION FOR SQL_ERROR_CODE <number>;

-- Example
DECLARE duplicate_key CONDITION FOR SQL_ERROR_CODE 301;
DECLARE EXIT HANDLER FOR duplicate_key
  SELECT 'Duplicate key error' FROM DUMMY;
SIGNAL 和 RESIGNAL

抛出用户定义的异常(代码 10000-19999):

-- Throw exception
SIGNAL <condition_name> SET MESSAGE_TEXT = '<message>';

-- Re-throw in handler
RESIGNAL [<condition_name>] [SET MESSAGE_TEXT = '<message>'];

常见错误代码:

代码描述
301唯一约束冲突
1299未找到数据

AMDP 集成

ABAP 托管数据库过程允许在 ABAP 类中使用 SQLScript。

类定义
CLASS zcl_my_amdp DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_amdp_marker_hdb.  " Required interface

    TYPES: BEGIN OF ty_result,
             id   TYPE i,
             name TYPE string,
           END OF ty_result,
           tt_result TYPE STANDARD TABLE OF ty_result.

    CLASS-METHODS: get_data
      IMPORTING VALUE(iv_filter) TYPE string
      EXPORTING VALUE(et_result) TYPE tt_result.
ENDCLASS.
方法实现
CLASS zcl_my_amdp IMPLEMENTATION.
  METHOD get_data BY DATABASE PROCEDURE
    FOR HDB
    LANGUAGE SQLSCRIPT
    OPTIONS READ-ONLY
    USING ztable.

    et_result = SELECT id, name
                FROM ztable
                WHERE category = :iv_filter;
  ENDMETHOD.
ENDCLASS.
AMDP 限制
  • 参数必须采用传值方式(不支持 RETURNING)
  • 仅允许使用标量类型、结构、内表
  • 不允许嵌套表或深层结构
  • 不允许使用 COMMIT/ROLLBACK
  • 开发必须使用 Eclipse ADT
  • 首次调用时自动创建

性能最佳实践

1. 尽早减少数据量
-- Good: Filter and project early
lt_filtered = SELECT col1, col2 FROM "BIGTABLE" WHERE status = 'A';
lt_result = SELECT a.col1, b.name
            FROM :lt_filtered AS a
            JOIN "LOOKUP" AS b ON a.id = b.id;

-- Bad: Join then filter
lt_result = SELECT a.col1, b.name
            FROM "BIGTABLE" AS a
            JOIN "LOOKUP" AS b ON a.id = b.id
            WHERE a.status = 'A';
2. 优先使用声明式而非命令式
-- Good: Set-based operation
lt_result = SELECT id, amount * 1.1 AS new_amount FROM "ORDERS";

-- Bad: Row-by-row processing
FOR row AS cur_orders DO
  UPDATE "ORDERS" SET amount = row.amount * 1.1 WHERE id = row.id;
END FOR;
3. 避免混用引擎
  • 不要在同一查询中混用行存储表和列存储表
  • 避免在纯 SQL 中使用计算引擎函数
  • 使用一致的存储类型
4. 使用 UNION ALL 替代 UNION
-- Faster when duplicates impossible or acceptable
SELECT * FROM table1 UNION ALL SELECT * FROM table2;

-- Slower: removes duplicates
SELECT * FROM table1 UNION SELECT * FROM table2;
5. 避免动态 SQL
-- Bad: Re-optimized each execution
EXECUTE IMMEDIATE 'SELECT * FROM ' || :lv_table;

-- Good: Static SQL with parameters
SELECT * FROM "MYTABLE" WHERE id = :lv_id;
6. 将命令式逻辑放在最后

将控制结构放在过程末尾,以最大限度地并行处理声明式语句。


系统限制

限制值
每笔事务的表锁数量16,383
单条语句中的表数量4,095
SQL 语句长度2 GB
过程大小受 SQL 语句长度限制(2 GB)

**注意:**实际限制可能因 HANA 版本而异。请查阅 SAP 文档,了解特定版本的限制。


调试工具

  • SQLScript 调试器 - SAP Web IDE / Business Application Studio
  • 计划可视化工具 - 分析执行计划
  • 昂贵语句跟踪 - 识别瓶颈
  • SQL 分析器 - 查询优化建议

快速参考

字符串拼接
lv_result = lv_str1 || ' ' || lv_str2;
NULL 处理
COALESCE(value, default_value)
IFNULL(value, default_value)
NULLIF(value1, value2)
日期操作
ADD_DAYS(date, n)
ADD_MONTHS(date, n)
DAYS_BETWEEN(date1, date2)
CURRENT_DATE
CURRENT_TIMESTAMP
类型转换
CAST(value AS datatype)
TO_VARCHAR(value)
TO_INTEGER(value)
TO_DATE(string, 'YYYY-MM-DD')
TO_TIMESTAMP(string, 'YYYY-MM-DD HH24:MI:SS')

相关技能

要全面开展 SAP 开发,请将此技能与以下技能结合使用:

技能使用场景
sap-abapAMDP 场景下的 ABAP 编程模式
sap-abap-cds使用 SQLScript 过程的 CDS 视图
sap-cap-capireCAP 框架数据库过程集成
sap-hana-cli用于过程部署和测试的 HANA CLI
sap-btp-cloud-platformHANA 构件的 BTP 部署

捆绑资源

参考文档
  • references/skill-reference-guide.md - 所有参考资料的索引,支持快速导航
  • references/glossary.md - SQLScript 术语和概念
  • references/syntax-reference.md - 完整的 SQLScript 语法参考
  • references/built-in-functions.md - 内置函数目录
  • references/data-types.md - 数据类型和转换
  • references/exception-handling.md - 异常处理模式
  • references/amdp-integration.md - AMDP 集成模式
  • references/performance-guide.md - 优化技巧
  • references/advanced-features.md - 横向连接、JSON、查询提示、货币转换
  • references/troubleshooting.md - 常见错误和解决方案
  • references/edge-cdp-control.md - 用于共享 sap-browser-automation Edge/CDP 和身份验证层的 SQLScript 专用扩展
可用于生产环境的模板

复制并自定义这些模板,以用于常见模式:

  • templates/simple-procedure.sql - 带错误处理的基本存储过程
  • templates/procedure-with-error-handling.sql - 全面的错误处理模式
  • templates/table-function.sql - 带验证的表 UDF
  • templates/scalar-function.sql - 标量 UDF 示例
  • templates/amdp-class.abap - 完整的 AMDP 类样板代码
  • templates/amdp-procedure.sql - AMDP 实现模板
  • templates/cursor-iteration.sql - 游标模式(经典模式和 FOR 循环)
  • templates/bulk-operations.sql - 高性能批量操作
专用 Agent
  • sqlscript-analyzer - 分析代码中的性能问题和最佳实践
  • procedure-generator - 根据需求交互式生成过程
  • amdp-helper - 协助创建和调试 AMDP 类
斜杠命令
  • /sqlscript-validate - 验证代码并支持自动修复
  • /sqlscript-optimize - 性能分析和优化建议
  • /sqlscript-convert - 在独立格式和 AMDP 格式之间转换
验证钩子

在 Write/Edit 操作时自动执行代码质量检查:

  • 错误处理完整性
  • 安全漏洞
  • 性能反模式
  • 命名约定
  • AMDP 合规性

评论

支持 Markdown