使用 ABAP SQL 中的表达式
学习目标
在 ABAP SQL 中使用一些简单表达式。
文字
ABAP SQL 中的文字和常量
最简单的表达式是文字。与 ABAP 本身一样,ABAP SQL 也知道两种文字:文本文字(以简单引号指定)和数字文字(可以是正整数或负整数)。ABAP SQL 中的文字类型与 ABAP 中的文字类型相同:文本文字的类型为 C,数字文字的类型为 I。

在此示例中,字段列表的第一个元素是文本文字,而第二个和第三个元素是数字文字,一个为正值,另一个为负值。
注意
在后引号中指定的字符串文字在 ABAP SQL 中不可用。
建议您定义常量并在 ABAP SQL 语句中使用这些常量,而不是直接使用文字。这提高了可读性,并使您能够访问更多类型,而不仅仅是 C 和 I。在 ABAP SQL 语句中使用常量时,必须使用前缀 @。
在此示例中,元素列表的第四个元素是类型为 I、值为 1234、名称为 C_NUMBER 的常量。
试用:文字
创建实施接口 IF_OO_ADT_CLASSRUN 的新全局类。
将以下代码片段复制到方法 if_oo_adt_classrun~main() 的实施部分:
CONSTANTS c_number TYPE i VALUE 1234.
SELECT FROM /dmo/carrier
FIELDS 'Hello' AS Character, " Type c
1 AS Integer1, " Type i
-1 AS Integer2, " Type i
@c_number AS constant " Type i (same as constant)
INTO TABLE @DATA(result).
out->write(
EXPORTING
data = result
name = 'RESULT'
).
选择 CTRL + F3 激活类,然后选择 F9 将其作为控制台应用执行。
分析控制台输出。
调试方法 if_oo_adt_classrun~main() 的执行并分析内部表 RESULT 的列 CHARACTER 、 INTEGER1 和 INTEGER2 的类型。
将更多文字添加到 FIELDS 列表以熟悉语法。
CAST 表达式
与 ABAP 本身不同,ABAP SQL 不知道隐式类型转换。CDS 的 CAST 表达式允许您显式实施类型转换。

类型转换的操作数不仅可以是数据源的文字或字段。所有种类的其它表达式都有可能,如算术表达式、预定义函数和许多其他表达式。
您可以将大多数预定义的字典类型指定为目标类型,例如 INT4、CHAR、DEC、FLTP、DATS 等。在 ABAP SQL 中,无法将字典数据元素用作目标类型。
注意
源类型和目标类型的组合存在限制。某些组合根本不受支持。其他操作仅适用于限制,并可能导致运行时错误。可在 ABAP 语言文档中找到详细的矩阵。
ABAP 字典中的预定义类型
在 ABAP 字典中定义类型(例如数据元素)时,使用一组特定的预定义类型。当此类字典类型用于在 ABAP 中键入数据对象时,字典类型将映射到特定的预定义 ABAP 类型。例如,字典类型 CHAR 映射到 ABAP 类型 C,类型 INT4 映射到类型 I,类型 FLTP 映射到类型 F,类型 DEC 映射到 P 等。

某些字典类型在 ABAP 中没有直接对应类型。例如,字典类型 MANDT 在技术上与类型 CHAR(3) 相同,但在用于数据库表字段时具有特殊含义。在不需要此特殊含义的 ABAP 中,类型 MANDT 映射到类型 C LENGTH 3。同样,字典类型 UNIT 和 CUKY 映射到 ABAP 类型 C,QUAN 和 CURR 映射到 ABAP 类型 P。
字典类型 DEC、QUAN 和 CURR 的长度指定为位数。ABAP 类型 P 的长度指定为字节数。n 个字节对应于 2 个 *n - 1 个数字。
CAST 表达式示例

在此示例中,相同的文本文字将转换为不同的兼容目标类型。请注意以下事实:
如果源文字包含非数字字符,转换为数字类型(INT4、DEC、FLTP)会导致运行时错误。
转换为类型 DATS 不会检查 8 位数字是否构成有效日期。
类型 CHAR( 4) 是兼容类型,但转换会导致信息丢失。
注意
DEC_10_2 列中仅显示一个小数位的事实是 UI 的部件。
试用:CAST 表达式
创建实施接口 IF_OO_ADT_CLASSRUN 的新全局类。
将以下代码片段复制到方法 if_oo_adt_classrun~main() 的实施部分:
SELECT FROM /dmo/carrier
FIELDS '19891109' AS char_8,
CAST( '19891109' AS CHAR( 4 ) ) AS char_4,
CAST( '19891109' AS NUMC( 8 ) ) AS numc_8,
CAST( '19891109' AS INT4 ) AS integer,
CAST( '19891109' AS DEC( 10, 2 ) ) AS dec_10_2,
CAST( '19891109' AS FLTP ) AS fltp,
CAST( '19891109' AS DATS ) AS date
INTO TABLE @DATA(result).
out->write(
EXPORTING
data = result
name = 'RESULT'
).
选择 CTRL + F3 激活类,然后选择 F9 将其作为控制台应用执行。
分析控制台输出。
调试方法 if_oo_adt_classrun~main() 的执行并分析内部表 RESULT 各列的类型。
将更多 CAST 表达式添加到 FIELDS 列表以熟悉语法。
案例区别

ABAP SQL 提供可在 SELECT 语句的元素列表中用作其他表达式的操作数的案例区分。
大小写区分仅返回一个值。此值取决于一系列条件。大小写区分始终以关键字 CASE 开头,以关键字 END 结尾。其余部分取决于大小写区分的类型。
简单大小写区分对应于 ABAP 控制结构 CASE…ENDCASE。它将操作数的值与其他一系列操作数进行比较。您可以使用任何 SQL 表达式作为操作数,例如,表字段、文字、常量、ABAP 变量、SQL 表达式等。
复杂案例区分(也称为搜索案例)对应于 ABAP 控制结构 IF… ENDIF 及其可选部分 ELSEIF 和 ELSE。它评估关键字 WHEN 之后按给定顺序的 SQL 条件。第一个条件为真可确定 CASE 表达式的结果。如果条件均不为真,则结果由 ELSE 附加确定。

对于简单情况,此示例使用字段 TITLE 的内容将长文本返回为字段 TITLE_LONG。其中 TITLE 包含值 "Mr.",列 TITLE_LONG 包含值 "Mister"。其中 TITLE 包含 'Mrs.',列 TITLE_LONG 包含 'Misses'。对于 TITLE 中的任何其它值,TITLE_LONG 包含空格。

对于复杂情况,此示例使用一系列 SQL 条件来确定新列 BOOKING_STATE 的值。
如果列 SEATS_OCCUPIED 的值小于列 SEATS_MAX 的值,则新列将返回文本,指示有更多可用座位。只有情况并非如此,才会检查下一个条件,以此类推。
试用:案例区别
创建实施接口 IF_OO_ADT_CLASSRUN 的新全局类。
将以下代码片段复制到方法 if_oo_adt_classrun~main() 的实施部分:
SELECT FROM /dmo/customer
FIELDS customer_id,
title,
CASE title
WHEN 'Mr.' THEN 'Mister'
WHEN 'Mrs.' THEN 'Misses'
ELSE ' '
END AS title_long
WHERE country_code = 'AT'
INTO TABLE @DATA(result_simple).
out->write(
EXPORTING
data = result_simple
name = 'RESULT_SIMPLE'
).
**********************************************************************
SELECT FROM /DMO/flight
FIELDS flight_date,
seats_max,
seats_occupied,
CASE
WHEN seats_occupied < seats_max THEN 'Seats Avaliable'
WHEN seats_occupied = seats_max THEN 'Fully Booked'
WHEN seats_occupied > seats_max THEN 'Overbooked!'
ELSE 'This is impossible'
END AS Booking_State
WHERE carrier_id = 'LH'
AND connection_id = '0400'
INTO TABLE @DATA(result_complex).
out->write(
EXPORTING
data = result_complex
name = 'RESULT_COMPLEX'
).
选择 CTRL + F3 激活类,然后选择 F9 将其作为控制台应用执行。
分析控制台输出。
使用 CASE 表达式来熟悉语法。