SAP-Fiori:系列(5)Gateway ODATA (V2) CURD之Update

OData V2 UPDATE 操作详解

在 OData V2 中,UPDATE 操作用于修改已存在的实体资源。根据 HTTP 规范,更新可以通过两种方法实现:PUT (完整替换)和 MERGEPATCH(部分更新)。本文将详细讲解如何在 OData V2 服务中执行更新操作,包括客户端请求构造、SAP Gateway 后端实现、常见错误及最佳实践。


1. UPDATE 的核心概念

方法 说明 幂等性 OData V2 支持
PUT 完整替换整个实体,未提供的字段会被重置为默认值或清空
MERGE 部分更新,只修改请求体中提供的字段,其他字段保持不变 否(但规范推荐视为幂等) 是(SAP Gateway 常用)
PATCH 与 MERGE 类似,但遵循 RFC 5789(PATCH 方法) OData V3/V4 更常见,V2 部分服务支持

在 SAP Gateway(OData V2)中,通常使用 MERGE 作为默认的部分更新方法,也支持 PUT 。具体支持情况可以通过 $metadata 或服务文档确认。


2. 客户端 UPDATE 请求示例

假设我们要更新 ZUSERSetId=2 的用户,将其 Name 改为 "Jerry"Address 改为 "上海市浦东新区"。200显示已更新成功

2.1 使用 MERGE(部分更新,推荐)

请求 URL

复制代码
http://ip:host/sap/opu/odata/SAP/ZXKJ_USER_SRV/ZUSERSet(5)

HTTP 方法MERGE

请求体(Atom/XML 格式)

复制代码
<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
       xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
       xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
    <title type="text">ZUSERSet(2)</title>
    <updated>2026-04-27T10:00:00Z</updated>
    <category term="ZXKJ_USER_SRV.ZUSER"
              scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
    <content type="application/xml">
        <m:properties>
            <d:Name>Jerry</d:Name>
            <d:Address>上海市浦东新区</d:Address>
        </m:properties>
    </content>
</entry>

实际开发中,MERGE 更常用,因为客户端无需知道当前所有字段的值,只需发送需要更改的字段即可。


3. 成功响应

  • 204 No Content:更新成功,无内容返回(最常见)。

  • 200 OK:更新成功,响应体包含更新后的完整实体(某些服务配置下会返回)。


4. ABAP 后端实现(SAP Gateway)

在 SAP Gateway 中,更新操作在 DPC_EXT 类的 **UPDATE_ENTITY**方法中实现。该方法同时处理 PUT 和 MERGE。

4.1 方法签名

复制代码
METHOD <entityset>_update_entity.
  " 导入参数:
  "   it_key_tab        : 主键列表
  "   io_data_provider  : 请求数据提供者
  "   iv_entity_name    : 实体名称
  "   iv_entity_set_name: 实体集名称
  "   io_tech_request_context : 技术请求上下文(可获取操作类型 PUT/MERGE)

4.2 实现逻辑(以 ZKJUSER 表为例)

复制代码
    DATA: ls_entity TYPE zkjuser,      " 数据库表结构
          ls_update TYPE zkjuser,      " 待更新的数据
          lv_id     TYPE int1.

    " 1. 从请求中读取更新的数据
    io_data_provider->read_entry_data( IMPORTING es_data = er_entity ).

    " 2. 从主键表中获取 Id
    READ TABLE it_key_tab INTO DATA(ls_key) WITH KEY name = 'Id'.
    IF sy-subrc = 0.
      lv_id = ls_key-value.
    ELSE.
      RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
        EXPORTING
          textid  = /iwbep/cx_mgw_busi_exception=>business_error
          message = '未提供主键 Id'.
    ENDIF.

    " 3. 检查记录是否存在
    SELECT SINGLE * FROM zkjuser INTO ls_entity
      WHERE id = lv_id.
    IF sy-subrc <> 0.
      RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
        EXPORTING
          textid  = /iwbep/cx_mgw_busi_exception=>business_error
          message = |Id = { lv_id } 的用户不存在|.
    ENDIF.

*    " 4. 合并数据(根据请求类型决定如何合并)
*    IF io_tech_request_context->get_http_method( ) = 'PUT'.
*      " PUT: 完全替换,未在请求中提供的字段需要清空
*      ls_update = er_entity.   " er_entity 包含请求中的全部字段
*      " 注意:如果请求中某些字段缺失,它们将变为初始值
*    ELSE.
*      " MERGE: 部分更新,只覆盖请求中提供的字段
*
*    ENDIF.
    " 先用原有数据填充,再用请求数据覆盖
    ls_update = ls_entity.
    MOVE-CORRESPONDING er_entity TO ls_update.
    " 5. 执行数据库更新
    UPDATE zkjuser FROM ls_update.

    IF sy-subrc = 0.
      COMMIT WORK.
      " 将更新后的数据返回给客户端(可选)
      er_entity = ls_update.
    ELSE.
      ROLLBACK WORK.
      RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
        EXPORTING
          textid  = /iwbep/cx_mgw_busi_exception=>business_error
          message = '更新失败,请重试'.
    ENDIF.

5.3 关键点解析

  • 主键处理 :主键值通常来自 URL 路径(如 ZUSERSet(5)),通过 it_key_tab 解析。注意请求体中的主键字段通常不需要,但若服务端强制要求,可以读取并比较。

  • 客户端隔离 :务必在 WHERE 条件中加入 mandt = sy-mandt,防止误更新其他客户端的数据。

  • 事务管理 :更新成功后调用 COMMIT WORK,失败则 ROLLBACK WORK

  • 返回数据 :可以将更新后的实体赋值给 er_entity,这样客户端可以收到更新后的完整数据(配合状态码 200)。如果希望返回 204 无内容,可以不赋值(但需要检查服务配置)。

相关推荐
duangww9 小时前
SAP订单费用报表
abap
HeathlX1 天前
SAP-Fiori:系列(3)Gateway ODATA (V2) CURD之Create
abap
HeathlX1 天前
SAP-Fiori:系列(4)Gateway ODATA (V2) CURD之Delete
sap·abap
戰皇Hermes3 天前
ABAP cl_document_bcs-用户权限不足导致正文内容变成附件txt
abap
duangww3 天前
SAP 生产订单组件修改
abap
HeathlX3 天前
SAP-Fiori:Gateway ODATA(V2)
abap
HeathlX3 天前
SAP-Fiori:Gateway ODATA (V2) CURD之Query
abap
小田的博客5 天前
SAP ABAP 上传EXCEL文件报错
sap
Henry-SAP6 天前
SAP MRP销售订单与预测驱动的业务解析
人工智能·sap·erp