SAP HANA SQL 脚本教程:语法和示例

什么是 SQL 脚本?
SQL 脚本是 SQL 扩展的集合。它可以在存储过程中代替纯 SQL 使用。它决定了功能和过程扩展。
In SQL 脚本用户可以定义主要用于创建存储过程的结构和表的局部变量。
SQL 脚本也可以在计算视图中使用。在 SQL 脚本中,有两个不同的逻辑容器 -
- 过程(过程允许您描述作为输入和数据库表传递的数据的一系列数据转换)。
- 用户定义函数(用户定义函数容器分为标量用户定义函数和表用户定义函数)。
SQL 脚本语言元素如下 -
声明式 SQL 脚本逻辑(功能扩展)
- 它允许定义表类型而不引用数据库表。
- 典型的语句,如 SELECT。
- 计算引擎 (CE) 功能。
⚠️ 版本说明: 计算引擎计划运算符,例如 CE_COLUMN_TABLE 和 CE_JOIN 等 CE_ 函数,已被弃用。 SAP新开发的代码应该使用标准的 SQL 语句,优化器至少能够很好地处理这些语句。现有的 CE 代码仍然可以运行,但下次更改存储过程时应该进行迁移。
编排SQL脚本逻辑(功能扩展)
编排逻辑用于通过使用 DDL、DML 和 SQL 查询语句来实现数据流,并使用循环和条件等命令式语言结构来实现控制流逻辑。
- 数据定义语言语句。例如创建模式。
- 数据操作语言(例如插入)。
命令式 SQL 脚本逻辑(过程扩展)
命令式逻辑将逻辑拆分为多个数据流。例如 IF、ELSEIF、ELSE、CASE、FOR(循环)和异常。
SQL脚本的重要性
只有SQL脚本提供了将数据密集型逻辑或应用程序服务器的操作迁移到数据库服务器所需的元素。
SQL脚本的要点
- SQL脚本在HANA数据库内的计算引擎中执行和处理。
- SQL脚本能够执行复杂的计算。
- 在 SQL 脚本中,可以声明一个局部变量来保存中间结果。
- SQL 脚本过程可以通过使用“OUTPUT 参数”返回更多结果,而普通 SQL 过程只能返回一个结果。
- 在 SQL 脚本中,您可以定义可用作参数的全局或本地表类型。
通过使用SQL Script,可以实现并行处理模式。
SQL脚本过程示例
过程是最常见的容器。以下示例读取员工数据,对其进行筛选,并通过输出表参数返回结果。
CREATE PROCEDURE DHK_SCHEMA.GET_HIGH_EARNERS ( IN im_min_salary DECIMAL(15,2), OUT ex_employees TABLE (EMP_NAME NVARCHAR(100), SALARY DECIMAL(15,2)), OUT ex_row_count INTEGER ) LANGUAGE SQLSCRIPT READS SQL DATA AS BEGIN -- Declarative logic: a table variable, not a physical table lt_all = SELECT EMP_NAME, SALARY FROM DHK_SCHEMA.EMPLOYEE WHERE SALARY >= :im_min_salary; -- Imperative logic: branch on the result SELECT COUNT(*) INTO ex_row_count FROM :lt_all; IF :ex_row_count = 0 THEN ex_employees = SELECT '' AS EMP_NAME, 0 AS SALARY FROM DUMMY WHERE 1 = 0; ELSE ex_employees = SELECT * FROM :lt_all ORDER BY SALARY DESC; END IF; END;
有三条约定值得注意。任何对变量的读取都要以冒号开头,因此 :lt_all 读取表格变量 lt_all 左侧的赋值语句会将其赋值给它。READS SQL DATA 语句告诉优化器该过程没有副作用,从而允许更激进的并行化。而返回多个输出参数的过程正是纯 SQL 所缺乏的能力。
调用方式很简单:
CALL DHK_SCHEMA.GET_HIGH_EARNERS (50000, ?, ?);
标量和表用户自定义函数
过程执行操作,而函数返回值,并且可以在查询中使用。SQL 脚本提供两种形式,它们不能互换。
| 参数 | 标量用户自定义函数 | 表格用户自定义函数 |
|---|---|---|
| Returns & Exchanges | 单一值 | 结果集 |
| 用于 | SELECT 列表、WHERE 子句、表达式 | FROM 子句,就像一个表 |
| 可以修改数据 | 没有 | 没有 |
| 典型用途 | 可重复使用的计算方法,例如税率 | 参数化视图返回筛选后的行 |
-- Scalar function: returns one value CREATE FUNCTION DHK_SCHEMA.ADD_BONUS (im_salary DECIMAL(15,2)) RETURNS total DECIMAL(15,2) LANGUAGE SQLSCRIPT AS BEGIN total := :im_salary * 1.10; END; SELECT EMP_NAME, DHK_SCHEMA.ADD_BONUS(SALARY) AS WITH_BONUS FROM DHK_SCHEMA.EMPLOYEE;
表函数使用 RETURNS TABLE 定义,然后在 FROM 子句中进行查询,这使得它成为构建可重用、参数化数据集的自然方式。 计算视图 或者报告可以消耗。
SQL脚本最佳实践
SQL脚本如果编写时考虑到引擎的并行处理能力,性能就会很好;如果像编写应用程序代码那样编写,性能就会很差。六个习惯决定了最终结果。
- 尽量使用声明式语言而非命令式语言。 单个基于集合的语句比逐行处理的循环性能高出几个数量级。只有当逻辑确实无法用集合运算表达时,才应该使用 FOR 循环。
- 避免使用光标。 它们强制逐行处理数据,完全破坏了计算引擎的运作。几乎所有游标都可以重写为连接或聚合操作。
- 保持各陈述独立。 两个互不引用的表变量并行计算。将每一步都串联起来执行,即可串行化整个过程。
- 声明 READS SQL DATA where true。 这表明该手术没有副作用,从而可以进行更多优化。
- 尽早筛选。 减少第一个表变量中的行数会缩小下游所有变量的行数,而最后的筛选已经弥补了损失。
- 迁移出 CE_ 函数。 它们已被弃用,不能与 SQL 在同一条语句中自由混合使用,而且 SQL 优化器现在可以更好地处理相同的工作。
语句级语法将在下文中介绍。 SAP HANA SQL过程内部可用的函数 SAP HANA SQL 函数以及在建模对象中使用这些过程的对象 SAP HANA建模 教程。
