定义含输入参数的 CDS 视图

学习目标

  • 使用输入参数定义 CDS 视图。

  • 提供 CDS 视图参数的值。

  • 将参数链接到 ABAP 系统字段。

是否需要输入参数

在前面的课程中,您了解了在数据库中进行计算时 CDS 视图的强大程度。您可能已经问自己 CDS 视图的使用者在多大程度上会影响计算的完成方式。当然,使用者可以提供 WHERE 子句以对结果执行选择。但是,当您想要为货币转换选择目标货币时,这有什么帮助?

具有输入参数的 CDS 视图消除了此差距。它们允许视图的使用者在从该视图检索数据时提供附加信息。CDS 视图依次评估此信息并在计算结果时将其考虑在内。参数的一些可能用例如下:

  • 消费者指定货币转换的目标货币。

  • 消费者指定计算价格时是否含税。

  • 消费者提供连接字段时使用的分隔符。

  • 消费者指定返回可翻译文本的语言。

输入视图的另一个重要动机是具有汇总的 CDS 视图,您想要在其中过滤输入汇总的数据。例如,如果计算总收入并且想要指定应考虑收入的截止日期。

最后,SQL 不了解强制选择条件。使用者可以提供 WHERE 子句,也可能不提供。使用强制输入参数,视图可以强制使用者提供必要的选择条件,例如语言代码、日期或用户名。

输入参数声明

您可以通过在 CDS 视图实体名称后添加 WITH PARAMETERS 来定义输入参数。然后在以逗号分隔的列表中定义参数。

每个输入参数都必须使用基本数据类型进行键入。参数名称和参数类型以冒号 (:) 分隔。参数类型可以是预定义的 ABAP 字典类型(格式为 abap.<type>(<len>))或数据元素。不允许结构类型、表类型或参考类型。

您可以使用参数注释为参数提供元数据。

访问参数

要访问输入参数,必须在 CDS 视图定义中使用前缀 $parameters,后跟句号 (.)。

可以在以下位置使用输入参数:

  • 作为元素列表中的独立元素

  • 作为病例区分的输入

  • 作为表达式和函数的输入

  • 在 WHERE 子句中条件的右侧

  • 在路径表达式中过滤条件的右侧。

现在,我们来看一些示例。

参数 TargetCurrency 直接在元素列表中使用。典型动机可能是此元素用于其他元素的 @semantics.amount.currencyCode: 注释。

在此,参数用于 CASE 区分,允许消费者决定是返回空闲座位还是返回已占用座位。

在此示例中,输入参数 TargetCurrency 用作内置函数(即货币转换函数)的输入。它允许视图的使用者 指定显示航班价格所使用的货币。

在此示例中,输入参数 Language 用于路径表达式的过滤条件中。它允许视图的使用者指定元素 CurrencyName 中文本的语言。

在此示例中,输入参数 FirstFlightDate 用于视图定义的 WHERE 条件中。这将建立一种强制选择条件。强制消费者按最小航班日期筛选航班。

数据预览中的输入参数

当您打开定义输入参数的 CDS 视图的数据预览工具时,系统会提示您为这些输入参数输入实际值,然后才能分析结果。请注意参数名称旁边的星号 (*),表示参数是必填项。

仅接受与参数类型兼容的条目。但该工具不会执行任何进一步检查。

提示

当焦点位于输入字段上时,屏幕会在输入掩码上方显示预期类型。

视图中的输入参数

当您定义新的 CDS 视图并使用输入参数作为数据源的 CDS 视图时,必须为所有输入参数提供实际值。让我们看一个示例:

此 CDS 视图从定义四个参数的 CDS 视图进行读取。

参数在源视图名称后面的一对括号内提供。由于并非只有一个参数,因此以逗号分隔的列表形式提供这些参数。

提示

定义从含参数的 CDS 视图读取的 CDS 视图时,可以使用代码完成(Ctrl + 空格)插入 CDS 视图的完整签名。

每个参数名称后面都有一个冒号 (:),用作参数赋值运算符,之后是实际值。一个选项是作为实际值的文字。另一个非常常见的选择是"转发"参数。这意味着调用视图定义参数本身,并将其用于提供其数据源的参数。因此,此视图的使用者负责提供实际值。使用此技术,您可以通过整堆的 CDS 视图移交信息。

ABAP SQL 中的输入参数

在 ABAP SQL 中提供 CDS 视图输入参数的语法与您在 CDS 中使用的语法非常相似。唯一的区别在于分配操作符:在 CDS 中,它是冒号 ":",而在 ABAP SQL 中,改用等号 (=)。

要提供实际值,可以从以下选项中进行选择:

文字

根据参数类型,可以使用数字文字或文本文字作为实际值。

主机变量

您可以使用 ABAP 常量或 ABAP 变量来提供实际值,而不是文字。与 ABAP SQL 中一样,主机变量和常量必须使用"at"符号 (@) 进行转义。类型必须与参数类型兼容。特别是,仅允许基本 ABAP 数据对象。

主机表达式

甚至可以在 ABAP SQL 语句中嵌入整个 ABAP 表达式,并将结果用作视图参数的实际值。这些

主机表达式

必须用一对括号括起来,并以"at"符号( @)为前缀。请注意,空格必须在左括号之后、右括号之前。表达式必须具有基本结果,并且类型必须与参数类型兼容。

如何定义和使用含输入参数的 CDS 视图

播放视频,了解如何定义和使用含输入参数的 CDS 视图。

视频:本节含 SAP 官方视频(视频 ID 1_ji7xd8fj),需在 learning.sap.com 在线观看。

使用 CDS 视图参数访问 ABAP 系统字段

ABAP 运行时维护保存一般感兴趣信息的各种系统字段:系统日期和时间、登录客户端和语言、当前用户的用户名等。如果要在 CDS 实体中使用这些系统字段的值,建议方式如下:

  1. 在 CDS 视图中,定义类型与系统字段类型相匹配的输入参数,例如日期或语言代码。

  2. 使用 Environment.systemField: 注释参数,并选择与您要访问的系统字段相关的注释值,例如 #SYSTEM_DATE 或 #SYSTEM_LANGUAGE。

如果这样注释参数,则在使用者未提供其他值的情况下,ABAP 运行时将自动为 参数提供相关系统字段的值。因此,在 ABAP SQL 语句中使用视图作为数据源时,仍可以像以前一样提供所有参数。但是,语法检查仅强制您提供未链接到系统字段的参数。对于链接到系统字段的参数,ABAP 运行时使用相关系统字段的值作为缺省值。

在此示例中,CDS 视图的两个参数链接到系统日期和系统语言。ABAP 代码未提供任何参数。因此,ABAP 运行时从系统字段中获取值。

链接到 ABAP 系统字段的参数看起来非常像可选参数。但是,请牢记以下内容:此机制仅在从 ABAP 中访问视图时有效。在 CDS 和数据库级别,参数仍然是强制参数。

目前, Environment.systemField 注释支持七个不同的值。该清单将其与相关系统字段一起显示。

注意

对于某些系统字段,不建议在 ABAP 云中进行直接访问。建议您改用 ABAP 类 CL_ABAP_CONTEXT_INFO 的 getter 方法。

如何在 ABAP CDS 中访问 ABAP 系统字段

播放视频,了解如何访问 ABAP CDS 中的 ABAP 系统字段。

视频:本节含 SAP 官方视频(视频 ID 1_zkqqg1rt),需在 learning.sap.com 在线观看。

定义和使用含输入参数的 CDS 视图实体

使用 SQL 函数以及使用的文字和会话变量作为输入来扩展 CDS 视图实体。现在,您可以使用输入参数替换一些文字和会话变量。

模板:

  • /LRN/CL_S4D430_RLS_PATH_EXPR(全局类)

解决方案:

  • /LRN/C_EMPLOYEE_PAR(数据定义)

  • /LRN/CL_S4D430_CPS_PARAMETER(全局类)

任务 1: 定义输入参数

创建您在上一练习中处理的 CDS 视图实体的副本(建议名称:Z##_C_EmployeeQueryP,其中 ## 是您的组编号)。

注意

如果尚未完成上一练习,请改为创建 CDS 数据定义 /LRN/C_EMPLOYEE_FNC 的副本。

在新的数据定义中,将硬编码的目标货币替换为输入参数(建议名称:p_target_curr),将会话变量 $session.system_field 替换为第二个输入参数(建议名称:p_date)。

步骤

  1. 使用 SQL 函数创建数据定义的副本(建议名称为 Z##_C_EmployeeQuery,其中 ## 是您的组编号)。或者,从数据定义 /LRN/C_EMPLOYEE_FNC(新视图实体的建议名称:Z##_C_EmployeeQueryP)中复制。

  2. 在项目浏览器视图中,右键单击 Z##_C_EMPLOYEE_QUERY 数据定义或 /LRN/C_EMPLOYEE_FUNC 数据定义以打开上下文菜单。

  3. 从上下文菜单中,选择复制 ....

  4. 在包字段中输入的名称。在名称字段中,输入名称 Z##_C_EmployeeQueryP,其中 ## 代表组编号。

  5. 调整描述,然后选择下一步

  6. 确认传输请求并选择完成

  7. 编辑视图实体的定义。定义输入参数以替换货币转换的硬编码货币代码(建议名称:p_target_curr)。使用在 CurrencyCodeUSD 视图元素中使用的相同类型。

  8. 如下调整代码:

define view entity Z##_C_EmployeeQueryP
with parameters
p_target_curr : /dmo/currency_code
as select from Z##_R_Employee
  1. 定义第二个输入参数以替换使用会话变量 $session.system_date(建议名称:p_date)。使用合适的预定义类型。

  2. 如下调整代码:

define view entity Z##_C_EmployeeQueryP
with parameters
p_target_curr : /dmo/currency_code,
p_date        : abap.dats
as select from Z##_R_Employee
  1. 使用标签对第二个参数进行注释(建议值:评估日期)。

注意

对于第一个参数,这不是必需的,因为该参数是使用数据元素键入的。

  1. 如下调整代码:

define view entity Z##_C_EmployeeQueryP
with parameters
p_target_curr : /dmo/currency_code,
@EndUserText.label: 'Date of evaluation'
p_date        : abap.dats
as select from Z##_R_Employee
  1. CurrencyCodeUSD 视图元素的定义中,将 CAST 表达式替换为输入参数 。

提示

使用代码完整化访问 参数。

  1. 如下调整代码:

// cast( 'USD' as /dmo/currency_code ) as CurrencyCodeUSD,
$parameters.p_target_curr as CurrencyCodeUSD,
  1. 调整 CurrencyCodeUSD 视图元素的名称(建议名称:CurrencyCode)。

注意

不要忘记同时调整两个@Semantics.amount.currencyCode 注释的值。

  1. 如下调整代码:

@EndUserText.label: 'Annual Salary'
@Semantics.amount.currencyCode: 'CurrencyCode'
currency_conversion( amount=> AnnualSalary,
source_currency => CurrencyCode,
target_currency => $projection.CurrencyCode,
exchange_rate_date => $session.system_date
)      as AnnualSalaryConverted,
@EndUserText.label: 'Monthly Salary'
@Semantics.amount.currencyCode: 'CurrencyCode'
cast( $projection.AnnualSalaryConverted as abap.fltp )
/ 12.0                    as MonthlySalaryConverted,
// CurrencyCode,
// cast( 'USD' as /dmo/currency_code ) as CurrencyCodeUSD,
$parameters.p_target_curr as CurrencyCode,
  1. 在货币转换中,将会话变量 $session.system_date 替换为日期参数。

  2. 如下调整代码:

@EndUserText.label: 'Annual Salary'
@Semantics.amount.currencyCode: 'CurrencyCode'
currency_conversion( amount             => AnnualSalary,
source_currency    => CurrencyCode,
target_currency    => $projection.CurrencyCode,
exchange_rate_date => $parameters.p_date
)      as AnnualSalaryConverted,
  1. CompanyAssociation 视图元素的计算中,将会话变量 $session.system_date 替换为 date 参数。

  2. 如下调整代码:

division( dats_days_between( EntryDate,
$parameters.p_date ),
365,
1 )      as CompanyAffiliation,
  1. 激活并测试 CDS 视图实体。

  2. Ctrl + F3 激活开发对象。

  3. F8 在数据预览工具中测试 CDS 视图实体。

  4. 输入两个参数的值,然后选择打开数据预览

提示

强制参数在参数名称旁边有一个星号 (*)。

任务 2: 在 ABAP SQL 中使用输入参数

创建 ABAP 类 /LRN/CL_S4D430_RLS_PATH_EXPR 的副本(建议名称:ZCL_##_PARAMETER,其中 ## 是您的组编号)。在新类中,调整 SELECT 语句。在 FROM 子句中,将 CDS 视图实体 /LRN/C_Employee_Qry 替换为您在此练习中创建的 CDS 视图实体(建议名称为:Z##_C_EmployeeQueryP)。在 字段 列表中,添加一些使用输入参数的视图元素。

步骤

  1. /LRN/CL_S4D430_RLS_PATH_EXPR 类复制到您自己的包中的类(建议名称:ZCL_##_PARAMETER,其中 ## 代表组编号)。

  2. 在项目浏览器视图中,右键单击 /LRN/CL_S4D430_RLS_PATH_EXP 类以打开上下文菜单。

  3. 从上下文菜单中,选择复制 ....

  4. 在包字段中输入的名称。在名称字段中,输入名称 ZCL_##_PARAMETER,其中 ## 是您的组编号。

  5. 调整描述,然后选择下一步

  6. 确认传输请求并选择完成

  7. IF_OO_ADT_CLASSRUN~MAIN 方法中,更改 SELECT 语句。在 FROM 子句中,将 /LRN/C_Employee_Qry 替换为您刚刚创建的 CDS 视图实体的名称 (Z##_C_EmployeeQueryP)。

  8. 如下调整代码:

SELECT
FROM Z##C_EmployeeQueryP
FIELDS employeeid,
  1. 为视图实体的输入参数提供值。将文字用于货币代码(例如**,'JPY'**),并将系统字段 sy-datum 用于日期参数。

提示

请记住,sy-datum 是主机变量,必须使用 @ 进行转义。

  1. 如下调整代码:

SELECT
FROM Z##C_EmployeeQueryP(
p_target_curr = 'JPY',
p_date        = @sy-datum )
FIELDS employeeid,
  1. 将以下视图元素添加到 FIELDS 列表:MonthlySalaryConvertedCurrencyCodeCompanyDependation

  2. 如下调整代码:

SELECT
FROM Z##C_EmployeeQueryP(
p_target_curr = 'JPY',
p_date        = @sy-datum )
FIELDS employeeid,
firstname,
lastname,
departmentid,
departmentdescription,
assistantname,
\_department\_head-lastname AS headname,
MonthlySalaryConverted,
CurrencyCode,
CompanyAffiliation
INTO TABLE @DATA(result).
  1. 激活全局类并将其作为控制台应用执行。

  2. Ctrl + F3 激活开发对象。

  3. F9 将全局类作为控制台应用执行。

任务 3: 将参数链接到系统字段

确保当未指定其他值时,ABAP 系统会自动使用系统日期填充它。然后从 ABAP 类的 SELECT 语句中移除参数 。

步骤

  1. 返回到 CDS 数据定义并注释 p_date 参数以将其链接到系统日期。使用代码完整化选择注释值。

  2. 如下调整代码:

define view entity Z##_C_EmployeeQueryP
with parameters
p_target_curr : /dmo/currency_code,
@EndUserText.label: 'Date of evaluation'
@Environment.systemField: #SYSTEM_DATE
p_date        : abap.dats
as select from Z##_R_Employee
  1. 激活并测试 CDS 视图实体。

  2. Ctrl + F3 激活开发对象。

  3. F8 在数据预览工具中测试 CDS 视图实体。

  4. 输入货币代码参数的值并选择打开数据预览

提示

强制参数在参数名称旁边有一个星号 (*)。

  1. 返回到 ABAP 类并移除或注释 FROM 子句中的日期参数。

  2. 如下调整代码:

SELECT
FROM /LRN/C_Employee_Par(
p_target_curr = 'JPY'
*            , p_date = @sy-datum
)
FIELDS employeeid,
  1. 激活全局类并将其作为控制台应用执行。

  2. Ctrl + F3 激活开发对象。

  3. F9 将全局类作为控制台应用执行。