使用实体操作语言

学习目标

  • 实施 EML 语句。

实体操作语言 (EML)

EML 由可用于操作业务对象数据的语句组成。使用 READ ENTITIES 语句读取数据;对于所有其它操作,使用具有相应附加项 UPDATE、CREATE 或 DELETE 的 MODIFY ENTITIES 语句。

注意

仅当业务对象接口的行为定义包含相应的 use createuse updateuse delete 指令时,才能使用 CREATE、UPDATE 和 DELETE 操作。尝试使用禁止的操作会导致语法错误。

要从业务对象读取数据,请使用 READ ENTITIES 语句。语句有两个重要参数:一个内部表包含要读取的数据的键值,另一个包含查询的结果。

这些内部表具有称为派生行为定义类型的特殊数据类型。当开发人员创建行为定义且包含业务对象的部分或全部字段以及控制系统如何处理特定请求的更多字段时,系统会自动创建它们。使用 DATA 语句中的新附加项 TYPE TABLE FOR <operation> 声明内部表。

类型 TABLE FOR READ IMPORT 包含业务对象的一个或多个关键字段。%control 结构是生成的结构,指示当前操作中实际使用的业务对象字段。在我们的示例中,系统会自动填充结构,您无需担心。

类型TABLE FOR READ RESULT 包含业务对象的所有字段。此表包含执行 read 语句后的结果集。

读取导入表包含业务对象的每个关键字段的列,在本例中为 agencyID。要读取特定代理,请在包含其键值的内部表中添加行。除关键字段外,该表还包含列 %is_braft%control。使用 %is_draft,您可以指定是要读取草稿数据还是活动数据。%control 结构用于指定要读取的字段。

注意

在我们的示例中,我们仅读取活动数据,并且 %control 结构由框架根据附加 FIELDS 后的字段列表填充。

使用 READ ENTITIES OF 或 MODIFY ENTITIES OF 语句处理业务对象时,必须首先指定行为定义的名称。后跟关键字 ENTITY 和要使用的实体的名称。如果实体具有别名,则应在此处使用。

注意

添加 OF 后不能使用别名。这是因为从技术上讲,您此时指定行为定义的名称,而不是实体的名称。

READ ENTITIES 语句根据您在 WITH 附加中传递的键值读取业务对象数据。它在 RESULT 附加项中返回内部表中的结果。在 语句中,您还可以指定需要业务对象的哪些字段。在此示例中,我们使用 ALL FIELDS 附加返回所有字段。但是,如果仅需要字段的子集,则可以使用变式 FIELDS(field1**field2…)来限制读取的数据量。

注意

与 SELECT 语句不同,字段列表不是以逗号分隔的。

结果表包含业务对象的所有字段以及控制字段 %is_braft。如果 READ ENTITIES 语句包含 ALL FIELDS 变式,则系统会提供所有字段的值。如果使用 FIELDS ( f1fn) 变式,将仅填充您请求的字段。

注意

即使关键字段未在 FIELDS ( f1…f n ) 变式中指定,也会始终填充这些字段。

如果要更新数据,请使用 TYPE TABLE FOR UPDATE 声明内部表。其中包含业务对象的所有字段以及 %control 结构。在 MODIFY ENTITIES 语句的变式中,系统自动填充 %control 结构。

MODIFY ENTITIES 语句更新事务缓冲区中的数据。在 FIELDS 附加中,指定应更改的字段。在 WITH 附加中,传递包含要更新的数据的内部表。

在业务对象外使用 EML 时,必须使用 COMMIT ENTITIES 语句触发保存序列并将数据保存在数据库中。

注意

稍后,在本课程中,我们将在业务对象的行为实施中使用 EML。在行为实施中,既不必也不允许使用 COMMIT ENTITIES 触发提交。

如何实施 EML 语句

演示观看演示(SAP 官方交互式练习)

使用 EML 修改数据

在本练习中,使用 EML 对业务对象 /DMO/R_AGENCYTP 的根实体执行标准操作更新。为避免后续出现不一致,不直接访问业务对象,而是通过其发布的稳定接口 /DMO/I_AGENCYTP 进行访问。

模板:

解决方案:

  • /LRN/CL_S4D400_BOS_EML(全局类)

任务 1: 分析当前数据

使用数据预览工具检查标识为 "0700##" 的旅行社的当前名称,其中 ## 代表组编号。

步骤

  1. 打开 CDS 视图实体 /DMO/I_AgencyTP 的定义。

  2. 如果上一练习中的数据定义 /DMO/I_AGENCYTP 仍处于打开状态,请切换到相应标签。否则,按 Ctrl + Shift + A 打开 ABAP 开发对象。

  3. 打开数据预览工具。

  4. 右键单击源代码中的任意位置以打开上下文菜单。

  5. 从上下文菜单中,选择打开方式数据预览

  6. 检查标识为 "0700##" 的旅行社的当前名称,其中 ## 代表组编号。

  7. 向下滚动到列 AgencyID 中值为 "0700##" 的条目,并记录**名称**列中的值。

任务 2: 创建全局类

在您自己的包中,创建新的 ABAP 类。

步骤

  1. 创建名为 ZCL_##_EML 的新 ABAP 类,其中 ## 代表组编号。确保该类实施接口 IF_OO_ADT_CLASSRUN

  2. 选择 文件新建ABAP 类

  3. 在包字段中输入的名称。在名称字段中,输入名称 ZCL_##_EML,其中 ## 是您的组编号。输入描述。

  4. 接口组框中,选择添加

  5. 输入 IF_OO_ADT_CLASSRUN。当接口出现在命中列表中时,双击该接口将其添加到类定义中。

  6. 选择下一步

  7. 选择传输请求,然后选择完成

任务 3: 更新数据

实施 EML 语句以更改标识为 "0700##" (## 代表组编号)的旅行社名称。

步骤

  1. 在方法 IF_OO_ADT_CLASSRUN~MAIN 中,为实体 /DMO/I_AgencyTP 的 EML 更新声明具有正确派生类型的内部表(建议名称:agencies_upd)

  2. 添加以下代码:

DATA agencies_upd TYPE TABLE FOR UPDATE /DMO/I_AgencyTP.
  1. 使用包含 "0700##" 的单行填充内部表,作为列 AGENCYID 的值(其中 ## 代表组编号)和列 NAME 的任何新值。

  2. 在数据声明之后,添加类似于以下代码的代码:

agencies_upd = VALUE #( ( agencyid = '0700##' name = 'Some fancy new name' ) ).
  1. 为业务对象接口 /DMO/I_AgencyTP 实施 EML 语句 MODIFY ENTITIES。更新根实体的数据,确保仅更改字段 NAME

提示

请记住,接口行为为根实体 /DMO/ I_AgencyTP 定义别名 /DMO/ Agency。

  1. 在 方法的末尾,添加以下代码:

MODIFY ENTITIES OF /dmo/i_agencytp
ENTITY /dmo/agency
UPDATE FIELDS ( name )
WITH agencies_upd.
  1. 为了从应用程序获取一些可见结果,请使用方法 out->write 将文本文字写入控制台。

  2. MODIFY ENTITIES 语句之后,添加以下代码:

out->write( `Method execution finished!`  ).
  1. 激活并测试类。

  2. Ctrl + F3 激活类。

  3. F9 键运行类。

  4. 检查新名称是否已写入数据库。

  5. 返回到 CDS 视图实体 /DMO/I_AgencyTP 的数据预览。

  6. 数据预览标签的工具栏中,选择刷新

  7. 将 COMMIT ENTITIES 语句添加到代码以提交更改。

  8. 返回到全局类 ZCL_##_EML 中的方法 IF_OO_ADT_CLASSRUN~MAIN

  9. 如下调整代码:

METHOD if_oo_adt_classrun~main.
DATA agencies_upd TYPE TABLE FOR UPDATE /dmo/i_agencytp.
agencies_upd = VALUE #( ( agencyid = '0700##' name = 'Some fancy new name' ) ).
MODIFY ENTITIES OF /dmo/i_agencytp
ENTITY /dmo/agency
UPDATE FIELDS ( name )
WITH agencies_upd.
COMMIT ENTITIES.
out->write( `Method execution finished!`  ).
ENDMETHOD.
  1. 再次激活并测试类。确认更改现在已在数据库中。

  2. Ctrl + F3 激活类。

  3. F9 键运行类。

  4. 返回到 CDS 视图实体 /DMO/I_AgencyTP 的数据预览。

  5. 数据预览标签的工具栏中,选择刷新