mcpField
A
abap-sql-amdp

abap-sql-amdp

github.com/likweitan数据与数据库7297 次安装2 周前更新
代码仓库

关于 abap-sql-amdp

abap-sql-amdp 是面向 ABAP 开发者的 SQL 与 AMDP 指南,覆盖现代查询语法、数据库过程及 Clean Core 使用边界。

主要功能

  1. 01现代 ABAP SQL 查询语法参考
  2. 02窗口函数、CTE 与集合操作示例
  3. 03AMDP 过程和 CDS 表函数指导
  4. 04说明 PRIVILEGED ACCESS 的用途
  5. 05按 Clean Core 等级评估 SQL 做法

适用场景

  1. 01编写或优化 ABAP SQL 查询
  2. 02实现 AMDP 过程或 CDS 表函数
  3. 03评估直接访问 SAP 数据库表的影响
  4. 04将旧代码迁移至 ABAP SQL 或 AMDP

安装

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

$npx skills add https://github.com/likweitan/abap-skills --skill abap-sql-amdp

安装后在 Claude Code 中输入/abap-sql-amdp确认已加载。

附带文件references/sql-functions-reference.md

详细介绍

ABAP SQL 与 AMDP

在 ABAP Cloud 和 Standard ABAP 中编写现代 ABAP SQL 语句和 ABAP Managed Database Procedures(AMDP)的指南。

Clean core 上下文:从已发布的 CDS 视图执行 SELECT 属于 Level A。直接对 SAP 数据库表进行读取属于 Level C(ATC 优先级 2);直接写入属于 Level D(ATC 优先级 1)。EXEC SQL(原生 SQL)是关键语句 → Level D。SYCM_USAGE_OF_APIS 会报告针对 SAP 数据库表和视图的 SQL 语句。有关级别的详细信息,请参阅 abap-cloud 技能。

工作流

  1. 确定用户的目标:

    • 编写或优化 ABAP SQL 查询
    • 使用高级 SQL 功能(窗口函数、CTE、聚合)
    • 创建 AMDP 过程或函数
    • 通过 AMDP 实现 CDS 表函数
    • 了解用于绕过授权检查的 PRIVILEGED ACCESS
  2. 识别上下文:

    • ABAP for Cloud Development 还是 Standard ABAP(影响可用语法)
    • 性能优化需求
    • AMDP 是否合理(尽可能优先使用 ABAP SQL)
  3. 使用现代 ABAP SQL 语法指导实现

现代 ABAP SQL 速查

使用内联声明的基本 SELECT
"Single record
SELECT SINGLE FROM ztravel
  FIELDS travel_id, description, total_price, currency_code
  WHERE travel_id = @lv_travel_id
  INTO @DATA(ls_travel).

"Multiple records into internal table
SELECT FROM ztravel
  FIELDS travel_id, description, total_price, currency_code
  WHERE status = 'O'
  ORDER BY total_price DESCENDING
  INTO TABLE @DATA(lt_travels)
  UP TO 100 ROWS.
SELECT 列表中的表达式
SELECT FROM zflight
  FIELDS carrier_id,
         connection_id,
         flight_date,
         seats_max - seats_occupied AS seats_free,
         CASE WHEN seats_occupied > seats_max * 80 / 100
              THEN 'FULL'
              ELSE 'AVAILABLE'
         END AS availability,
         CAST( price AS DECFLOAT34 ) AS price_dec,
         CONCAT( carrier_id, connection_id ) AS flight_key
  INTO TABLE @DATA(lt_flights).
聚合函数和 GROUP BY
SELECT FROM zflight
  FIELDS carrier_id,
         COUNT(*) AS flight_count,
         SUM( seats_occupied ) AS total_passengers,
         AVG( price ) AS avg_price,
         MIN( flight_date ) AS first_flight,
         MAX( flight_date ) AS last_flight
  GROUP BY carrier_id
  HAVING COUNT(*) > 10
  INTO TABLE @DATA(lt_stats).
窗口函数
SELECT FROM zflight
  FIELDS carrier_id,
         connection_id,
         flight_date,
         price,
         "Running total
         SUM( price ) OVER( PARTITION BY carrier_id
                            ORDER BY flight_date
                            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS running_total,
         "Row number within partition
         ROW_NUMBER( ) OVER( PARTITION BY carrier_id
                             ORDER BY flight_date DESCENDING ) AS row_num,
         "Ranking
         RANK( ) OVER( PARTITION BY carrier_id ORDER BY price DESCENDING ) AS price_rank,
         "Lead/Lag
         LAG( price, 1 ) OVER( PARTITION BY carrier_id ORDER BY flight_date ) AS prev_price,
         LEAD( price, 1 ) OVER( PARTITION BY carrier_id ORDER BY flight_date ) AS next_price
  INTO TABLE @DATA(lt_window).
公用表表达式(CTE)
WITH
  +connections AS (
    SELECT FROM zflsch
      FIELDS carrier_id, connection_id, city_from, city_to
      WHERE carrier_id IN @lt_carriers ),
  +flight_counts AS (
    SELECT FROM zflight
      FIELDS carrier_id, connection_id,
             COUNT(*) AS cnt
      GROUP BY carrier_id, connection_id ),
  +result AS (
    SELECT FROM +connections AS c
      INNER JOIN +flight_counts AS f
        ON c~carrier_id = f~carrier_id AND c~connection_id = f~connection_id
      FIELDS c~carrier_id, c~city_from, c~city_to, f~cnt )
  SELECT FROM +result
    FIELDS *
    ORDER BY cnt DESCENDING
    INTO TABLE @DATA(lt_result).
集合运算(UNION、INTERSECT、EXCEPT)
"UNION ALL (keeps duplicates) / UNION (removes duplicates)
SELECT FROM ztable1 FIELDS col1, col2
UNION ALL
SELECT FROM ztable2 FIELDS col1, col2
INTO TABLE @DATA(lt_union).

"INTERSECT — rows in both
SELECT FROM ztable1 FIELDS col1
INTERSECT
SELECT FROM ztable2 FIELDS col1
INTO TABLE @DATA(lt_intersect).

"EXCEPT — rows in first but not second
SELECT FROM ztable1 FIELDS col1
EXCEPT
SELECT FROM ztable2 FIELDS col1
INTO TABLE @DATA(lt_except).
PRIVILEGED ACCESS

绕过 CDS 访问控制(DCL)——请谨慎使用:

"Skips access control defined in CDS DCL
SELECT FROM zi_travel
  FIELDS travel_id, description
  WHERE status = 'O'
  INTO TABLE @DATA(lt_all_travels)
  PRIVILEGED ACCESS.
内置 SQL 函数
类别函数
字符串CONCAT、SUBSTRING、LENGTH、LEFT、RIGHT、LTRIM、RTRIM、UPPER、LOWER、REPLACE、LPAD、RPAD
数值ABS、CEIL、FLOOR、ROUND、MOD、DIV、DIVISION
日期/时间DATS_ADD_DAYS、DATS_DAYS_BETWEEN、TSTMP_ADD_SECONDS、TSTMP_CURRENT_UTCTIMESTAMP、DATN_ADD_MONTHS
转换CAST、COALESCE、CURRENCY_CONVERSION、UNIT_CONVERSION
空值COALESCE、CASE WHEN ... IS NULL
聚合COUNT、SUM、AVG、MIN、MAX、STRING_AGG
子查询
"Scalar subquery
SELECT FROM ztravel
  FIELDS travel_id,
         total_price,
         ( SELECT AVG( total_price ) FROM ztravel ) AS avg_price
  INTO TABLE @DATA(lt_with_avg).

"EXISTS subquery
SELECT FROM ztravel AS t
  FIELDS t~travel_id, t~description
  WHERE EXISTS ( SELECT FROM zbooking AS b
                   WHERE b~travel_id = t~travel_id
                     AND b~flight_date > @sy-datum )
  INTO TABLE @DATA(lt_with_bookings).

AMDP(ABAP Managed Database Procedures)

何时使用 AMDP
  • 大多数场景优先使用 ABAP SQL
  • 在以下情况下使用 AMDP:复杂计算可通过 SQLScript 获益、需要 CDS 表函数,或大规模数据处理需要数据库级优化
AMDP 类结构
CLASS zcl_my_amdp DEFINITION
  PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_amdp_marker_hdb.  "Mandatory for AMDP

    TYPES: BEGIN OF ty_result,
             carrier_id TYPE s_carr_id,
             total      TYPE i,
           END OF ty_result,
           tt_result TYPE STANDARD TABLE OF ty_result WITH EMPTY KEY.

    "AMDP procedure
    METHODS get_carrier_stats
      AMDP OPTIONS READ-ONLY CDS SESSION CLIENT DEPENDENT
      EXPORTING VALUE(et_result) TYPE tt_result.

    "AMDP table function for CDS table function
    CLASS-METHODS get_data FOR TABLE FUNCTION zdemo_amdp_tf.
ENDCLASS.
AMDP 过程实现
METHOD get_carrier_stats
  BY DATABASE PROCEDURE
  FOR HDB
  LANGUAGE SQLSCRIPT
  OPTIONS READ-ONLY
  USING zflight_ve.

  et_result = SELECT carrier_id,
                     COUNT(*) AS total
              FROM zflight_ve
              GROUP BY carrier_id
              ORDER BY total DESC;
ENDMETHOD.
用于 CDS 表函数的 AMDP 表函数

CDS 表函数定义:

@ClientHandling.type: #CLIENT_DEPENDENT
@ClientHandling.algorithm: #SESSION_VARIABLE
define table function ZDEMO_AMDP_TF
  with parameters @Environment.systemField: #SYSTEM_LANGUAGE p_lang : abap.lang
  returns {
    key carrier_id : s_carr_id;
    carrier_name   : s_carrname;
    flight_count   : abap.int4;
  }
  implemented by method zcl_my_amdp=>get_data;

AMDP 实现:

METHOD get_data
  BY DATABASE FUNCTION
  FOR HDB
  LANGUAGE SQLSCRIPT
  OPTIONS READ-ONLY
  USING zcarrier_ve zflight_ve.

  RETURN SELECT c.carrier_id,
                c.carrier_name,
                COUNT(*) AS flight_count
         FROM zcarrier_ve AS c
         INNER JOIN zflight_ve AS f
           ON c.carrier_id = f.carrier_id
         GROUP BY c.carrier_id, c.carrier_name;
ENDMETHOD.
AMDP 客户端安全性(ABAP Cloud)
附加项使用场景
CDS SESSION CLIENT DEPENDENT使用依赖客户端的 CDS 视图(最常见)
CLIENT INDEPENDENT仅使用与客户端无关的对象
AMDP OPTIONS READ-ONLYABAP for Cloud Development 中的必需项

输出格式

在解答 ABAP SQL 或 AMDP 相关问题时,按以下结构组织回复:

## ABAP SQL / AMDP Guidance

### Query

[The ABAP SQL statement or AMDP implementation]

### Explanation

[Key features used and why]

### Performance Notes

[Optimization considerations if relevant]

参考资料

SQL 和 AMDP 的 Clean Core 级别说明

场景级别说明
从已发布的 CDS 视图(I_*)中执行 SELECTA目标状态
从自己的自定义表中执行 SELECTA在同一软件组件内允许
从经典(指定的)SAP CDS 视图中执行 SELECTB在经典 ABAP 开发中可以接受
直接从 SAP 数据库表中读取CATC 优先级 2 —— 改用已发布的 CDS 视图
直接向 SAP 数据库表中写入DATC 优先级 1 —— 使用已发布或经典 API
EXEC SQL(原生 SQL)D严重语句 —— 使用 ABAP SQL 或 AMDP
数据库提示D严重语句
基于已发布 CDS 视图的 AMDPA将 USING 限制为已发布的实体
基于 SAP 表的 AMDPC/D读取 → C,写入 → D
基于已发布实体的 AMDP CDS 表函数A有效的 A 级下推技术

性能优化:调整旧代码时,使用 SQL Monitor 检测优化候选项,然后通过 CDS、AMDP 和 ABAP SQL 执行代码下推,而不是直接使用原生 SQL 或数据库提示。

相关技能

  • cds-view-entities:用于创建可与 ABAP SQL 配合使用的 CDS 数据模型
  • abap-cloud:用于了解 Clean Core 级别和 SQL 相关限制
  • rap:用于了解使用 CDS 视图的 RAP 数据模型
  • abap-cloud-migration:用于在优化期间替换直接表访问和 EXEC SQL
  • atc-cloudification:用于配置 SYCM_USAGE_OF_APIS 和 CI_CRITICAL_STATEMENTS

评论

支持 Markdown