" 精确单条查询
SELECT SINGLE * FROM ekko INTO @DATA(ls_ekko)WHERE ebeln = '4500000123'." 多表连接 (HANA 推荐使用 CDS View,但 Open SQL 支持基础连接)
SELECT a~vbeln, b~name FROM vbak AS aINNER JOIN kna1 AS b ON a~kunnr = b~kunnrINTO TABLE @DATA(lt_data)UP TO 100 ROWS. " 分页限制
2. 数据操作
操作
语法范例
关键点
INSERT
INSERT ztable FROM ls_data.
单条/内表批量插入
UPDATE
UPDATE ztable SET name = 'ABC' WHERE id = 'X'.
WHERE 条件必须包含主键或索引
DELETE
DELETE FROM ztable WHERE date < '20230101'.
避免无条件的全表删除
MODIFY
MODIFY ztable FROM TABLE lt_data.
智能合并(Insert or Update)
三、性能优化黄金法则
🚀 索引策略
主键索引:自动创建(MANDT + 业务主键)
辅助索引:
SE11 创建,字段 ≤ 5 个
避免频繁更新字段建索引
强制索引(谨慎使用):
SELECT * FROM sflight %_HINTS DB6 'INDEX("SFLIGHT~PRIMARY")' ```
📦 数据吞吐控制
优化点
方案
效果
字段精简
SELECT carrid, connid ... 替代 SELECT *
减少 50%+ 数据传输
分页处理
UP TO 100 ROWS
防止内存溢出
缓冲利用
配置表设置 Full Buffer (SE11)
减少 90%+ 物理读
⚠️ 全表扫描禁忌
禁止:WHERE status <> 'C' (负向条件)
替代方案:
SELECT * FROM orders INTO TABLE @DATA(lt_orders) FOR ALL ENTRIES IN @lt_valid_statusWHERE status = @lt_valid_status-status.
四、高级特性与风险控制
1. 动态 SQL
DATA(lv_condition) = `CARRID = 'LH' AND PRICE > 500`.
DATA(lv_sql) = |SELECT * FROM SFLIGHT WHERE { lv_condition }|.TRY.EXEC SQL. PERFORMING loop_output. ENDEXEC.
CATCH cx_sy_dynamic_osql_error INTO DATA(lx_error)." 捕获 SQL 注入风险
ENDTRY.
风险提示:动态内容必须严格校验,避免 SQL 注入
2. 聚合与子查询
" 聚合函数绕过缓冲,优先在 HANA 层处理
SELECT carrid, AVG( price ) AS avg_priceFROM sflightGROUP BY carridINTO TABLE @DATA(lt_stats)##DB_FEATURE_MODE[HANA_DB]. " 提示使用 HANA 特性
五、Open SQL vs Native SQL 关键对比
维度
Open SQL
Native SQL
数据库依赖
❌ 零依赖
✅ 需写特定数据库语法
性能优化
✅ 自动缓冲 + 语法优化
❌ 需手动优化
操作范围
DML 操作 (SELECT/UPDATE/INSERT/DELETE)
✅ 支持 DDL (CREATE/ALTER)
安全性
✅ 自动权限检查
❌ 需手动实现
使用场景
标准业务逻辑
数据库特殊功能 (如 HANA 存储过程)
官方建议:优先使用 Open SQL,仅在必须时使用 Native SQL [[SAP Note 1791075]]
六、调试与监控工具链
工具
路径
用途
SQL Trace
ST05
分析实际执行语句 + 耗时 + 索引使用情况
Runtime Analysis
SE30/SAAB
定位程序性能瓶颈
EXPLAIN Plan
ST05 或 HANA Studio
查看执行计划 (需激活 %_HINTS 或 DB 工具)
七、企业级最佳实践
多表关联:
简单场景:Open SQL JOIN
复杂场景:CDS View (性能显著优于嵌套 SELECT)
批量处理:
" FOR ALL ENTRIES 严格规范
IF lt_input IS NOT INITIAL.SORT lt_input BY key. DELETE ADJACENT DUPLICATES.SELECT ... FOR ALL ENTRIES IN @lt_input ...
ENDIF.
错误处理:
UPDATE ztable SET ... WHERE ...
IF sy-subrc <> 0.MESSAGE e001 WITH '更新失败'.
ENDIF.