其他
编写和优化 SAP HANA SQLScript 过程…
在 SAP HANA 中编写存储过程、匿名块、表/标量函数、AMDP、异常处理、游标和性能敏感数据库逻辑时,按此清单操作。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 35/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 38/100 ×0.15
适用场景
编写和优化 SAP HANA SQLSc特定
解决思路
- 使用 SQLScript 时遵循 code-to-data:把计算下推到数据所在的数据库层。
- 注意 SQLScript 大小写不敏感;所有语句以分号结尾;引用变量时加冒号前缀(:variableName),赋值时不加冒号。
- 单行操作使用 DUMMY 表,例如 SELECT :lv_count AS record_count FROM DUMMY;。
- 区分声明式逻辑和命令式逻辑:纯 SQL 序列会转成数据流图并行处理;IF、WHILE、FOR 等控制结构顺序处理并阻止并行。
- 匿名块用 DO [ (<parameter_clause>) ] BEGIN [SEQUENTIAL EXECUTION] <body> END; 编写,用于测试和临时执行。
- 存储过程用 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; 创建。
- 标量 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; 创建。
- 数据类型包括数值类型(TINYINT、INTEGER、DECIMAL 等)、字符类型(VARCHAR、NVARCHAR、CLOB 等)、日期/时间类型(DATE、TIME、TIMESTAMP、SECONDDATE)、二进制类型(VARBINARY、BLOB);使用 CAST 和 TO_ 系列函数转换,并处理 NULL,详见 references/data-types.md。
- 声明标量变量:DECLARE <variable_name> <datatype> [:= <initial_value>];;未初始化变量默认 NULL。
- 声明表变量:隐式用 lt_result = SELECT ...;,显式用 DECLARE lt_data TABLE (...);,或 DECLARE lt_copy TABLE LIKE :lt_original;。
- 声明数组:DECLARE arr INTEGER ARRAY := ARRAY(1, 2, 3, 4, 5);;数组索引从 1 开始,且数组不能从过程返回。
- 使用 IF <condition1> THEN ... [ELSEIF <condition2> THEN ...] [ELSE ...] END IF;;比较运算符包括 =、>、<、>=、<=、!=、<>。
- IF-ELSE 不能写在 SELECT 语句内;需要在 SELECT 中做条件判断时改用 CASE WHEN。
- 使用 WHILE <condition> DO ... END WHILE; 编写循环。
- 使用 FOR i IN 1..10 DO ... END FOR; 做数字范围循环,使用 FOR i IN REVERSE 10..1 DO ... END FOR; 做反向循环。
- 使用 FOR row AS <cursor_name> DO ... END FOR; 做游标迭代,通过 row.column_name 访问列。
- 使用 LOOP ... 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 → Open → Fetch → Close 模式:DECLARE CURSOR <cursor_name> FOR SELECT <columns> FROM <table> [WHERE <condition>]; OPEN <cursor_name>; FETCH <cursor_name> INTO <variables>; CLOSE <cursor_name>;。
- 游标会绕过数据库优化器并逐行顺序处理;只在基于主键的查询等场景使用,优先选择集合操作。
- 游标完整处理可用 WHILE NOT cur_employees::NOTFOUND DO ... FETCH cur_employees INTO lv_id, lv_name; END WHILE;,最后 CLOSE。
- 游标迭代可用 FOR row AS cur_employees DO ... END FOR; 替代。
- 异常处理用 DECLARE EXIT HANDLER FOR <condition_value> <statement>;;condition_value 可用 SQLEXCEPTION、SQL_ERROR_CODE <number>。
- 在异常处理中通过 ::SQL_ERROR_CODE 和 ::SQL_ERROR_MESSAGE 获取错误码和错误消息。
- 编写安全插入过程时,在 BEGIN 内先声明 EXIT HANDLER FOR SQLEXCEPTION,再执行 INSERT INTO "MYTABLE" VALUES (:iv_id, :iv_name);。
- 用 DECLARE <condition_name> CONDITION FOR SQL_ERROR_CODE <number>; 关联自定义条件名和错误码,例如 DECLARE duplicate_key CONDITION FOR SQL_ERROR_CODE 301;。
- 用 SIGNAL <condition_name> SET MESSAGE_TEXT = '<message>'; 抛出自定义异常,错误码范围 10000-19999。
- 在 handler 中用 RESIGNAL [<condition_name>] [SET MESSAGE_TEXT = '<message>']; 重新抛出异常。
- 记住常见错误码:301 唯一约束冲突,1299 无数据。
- AMDP 类定义需实现 INTERFACES if_amdp_marker_hdb,并定义 TYPES 与 CLASS-METHODS,例如 get_data IMPORTING VALUE(iv_filter) TYPE string EXPORTING VALUE(et_result) TYPE tt_result。
- AMDP 方法实现用 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.。
- AMDP 限制:参数必须 pass-by-value,不能有 RETURNING;只允许标量类型、结构、内表;不支持嵌套表和深层结构;不允许 COMMIT/ROLLBACK;必须用 Eclipse ADT 开发;首次调用时自动创建。
- 尽早减少数据量:先过滤和投影再 JOIN,例如先 SELECT col1, col2 FROM "BIGTABLE" WHERE status = 'A' 再与 LOOKUP 表 JOIN;避免先 JOIN 后过滤。
- 优先声明式而非命令式:用集合操作,例如 lt_result = SELECT id, amount * 1.1 AS new_amount FROM "ORDERS";;避免逐行 FOR 循环 UPDATE。
- 避免引擎混用:不要在同一查询中混用 Row Store 和 Column Store 表;避免将 Calculation Engine 函数与纯 SQL 混用;使用一致的存储类型。
- 在不需要去重或允许重复时用 UNION ALL 替代 UNION,例如 SELECT * FROM table1 UNION ALL SELECT * FROM table2;。
- 避免动态 SQL:不要用 EXECUTE IMMEDIATE 'SELECT * FROM ' || :lv_table;;改用带参数的静态 SQL,例如 SELECT * FROM "MYTABLE" WHERE id = :lv_id;。
- 把命令式逻辑放在过程最后,以最大化声明式语句的并行处理。
- 注意系统限制:每事务表锁 16,383;单语句表数量 4,095;SQL 语句长度 2 GB;过程大小受 SQL 语句长度限制(2 GB);实际限制可能随 HANA 版本变化,查阅 SAP 文档。
- 调试时使用 SQLScript Debugger(SAP Web IDE / Business Application Studio)、Plan Visualizer、Expensive Statement Trace、SQL Analyzer。
- 字符串拼接用 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-abap、sap-abap-cds、sap-cap-capire、sap-hana-cli、sap-btp-cloud-platform 等技能使用。
- 查阅 references/skill-reference-guide.md、references/glossary.md、references/syntax-reference.md、references/built-in-functions.md、references/data-types.md、references/exception-handling.md、references/amdp-integration.md、references/performance-guide.md、references/advanced-features.md、references/troubleshooting.md、references/edge-cdp-control.md。
- 复制并定制 templates/simple-procedure.sql、templates/procedure-with-error-handling.sql、templates/table-function.sql、templates/scalar-function.sql、templates/amdp-class.abap、templates/amdp-procedure.sql、templates/cursor-iteration.sql、templates/bulk-operations.sql。
- 使用 sqlscript-analyzer 分析性能与最佳实践,procedure-generator 交互生成过程,amdp-helper 辅助 AMDP 类创建和调试。
- 运行 /sqlscript-validate 验证并自动修复,/sqlscript-optimize 做性能分析和优化建议,/sqlscript-convert 在独立格式和 AMDP 格式间转换。
- 利用 Write/Edit 自动验证钩子检查错误处理完整性、安全漏洞、性能反模式、命名约定和 AMDP 合规性。
- 对于浏览器版 Datasphere 或 HANA Cloud SQL 编辑器排查,使用 sap-browser-automation 处理应用内手动认证、需同意的 Edge 配置文件复用、全新 Edge/CDP 启动、认证状态引导和恢复;加载 references/edge-cdp-control.md。
- CDP 仅用于本地 UI 检查、控制台诊断、部署消息和已批准截图;默认数据库验证仍应使用 SQL/HANA 工具。
适用边界 · 注意事项
- 没有 SAP HANA 数据库或 SQLScript/AMDP 运行时环境时,不要使用这些具体语法和部署步骤。
- 需要纯应用层开发或非 SAP 数据库开发时,不应套用 HANA 专有过程、AMDP 和 HANA 系统限制。
- 浏览器 CDP 自动化只用于本地 UI 检查与诊断,不应作为默认数据库验证手段。