文章目录
- 绪论
- ABAP工作区的主要 T-CODE(4)
- 第1章 包与变更传输系统(CTS)
- 第2章 数据类型
- 2.1 概要
- 2.1.6 ABAP命名规则(23)
- 1. 全局变量(23)
- 定义全局变量
- 2. 局部变量(24)
- 定义局部变量
- 2.2 ABAP基本数据类型
- 2.2.1 固定长度的 ABAP 基本数据类型(29)
- 基本数据类型
- 2.2.2 数字型(30)
- 2. 数字运算符(演算子)
- (1)基本运算法则
- (2)数字运算用函数
- (3)Floating-Point 函数
- 2.2.3 字符串类型(35)
绪论
ABAP工作区的主要 T-CODE(4)
T-CODE | 描述 | 说明 |
AUT10 | 审计追踪功能 | 查询到针对事务代码,文档对象的变更记录 |
SCC1 | 传输请求(同系统跨Client) | 用于在同一系统下不同clients之间传输内容,内容通过传输请求打包 |
SCOT | 邮件发送配置 | 相关通信服务配置 |
SE09 | 传输组织 | 释放/创建/修改CTS(变更传输系统)的开发工具 |
SE11 | ABAP数据字典 | 创建如数据表,视图,结构体等对象的开发工具 |
SE16 | 数据库数据编辑器 | 创建/修改/查询数据库表数据的开发工具 |
SE21 | 包编辑器 | 创建/修改/查询包的开发工具 |
SE24 | 类编辑器 | 创建/修改/查询类的开发工具 |
SE37 | 函数编辑器 | 创建/修改/查询函数的开发工具 |
SE38 | ABAP编辑器 | 创建/修改/查询ABAP程序的开发工具 |
SE41 | 菜单制作器 | 给程序创建GUI状态 |
SE43 | 维护局部菜单 | 创建/修改/查询SAP菜单的开发工具 |
SE80 | 对象导航器 | 集合了所有与ABAP开发相关的工作区 |
SE91 | 建立消息类和消息 | 创建/修改/查询消息类的开发工具 |
SE93 | 维护事务码 | 创建/修改/查询事务码的开发工具 |
SM04 | 用户监视 | 监视用户的活动 |
SM12 | 锁查看与维护 | 锁定对象/表条目冻结说明 |
STAD | 统计记录界面 | 查看用户的操作记录 |
STMS | 传输系统配置 | 用于在不同系统之间传输内容,内容通过传输请求打包 |
第1章 包与变更传输系统(CTS)
第2章 数据类型
2.1 概要
2.1.6 ABAP命名规则(23)
1. 全局变量(23)
全局变量(Global Variable)是指在一个程序或函数内可以访问的数据类型。在程序内部的所有领域都可以参照并修改,因此没有局域性。在程序激活状态下全局变量一直占用着内存地址。定义全局变量时变量名以 G 开头,具体数据类型定义的方法如下所示。
定义全局变量
数据类型 | 前缀 | 使用实例 | 程序代码 |
字段 | V 或D | GV_CARRID 或 GD_CARRID | DATA GV_SFLIGHT TYPE S_CARR_ID. 或 DATA GD_SFLIGHT TYPE S_CARR_ID. |
结构体 | S | GS_SFLIGHT | DATA GS_SFLIGHT TYPE SFLIGHT. |
常量 | C | GC_RATE | CONSTANTS GC_RATE TYPE I VALUE ‘3.14’. |
内表 | T | GT_SFLIGHT | DATA GT_SFLIGHT TYPE STANDARD TABLE OF SFLIGHT. |
类 | O | GO_ALVGRID | DATA GO_ALVGRID TYPE REF TO CL_SALV_TABLE. |
RANGE(范围) | R | GR_CARRID | RANGES GR_CARRID FOR SFLIGHT-CARRID. |
参照变量(数据对象) | F | GF_OBJ | DATA GF_OBJ TYPE REF TO OBJECT. |
如果需要细分命名规则,则可以把前缀(Prefix)长度设为3位。
前缀 1 →范围, 前缀 2→数据类型, 前缀 3→数据类型
例如,在 GVF_CARRID 变量中前缀代表的意思分别为 G—全局,V—字段,F—浮点型,但是变量名过长不利于编码,因此应尽量避免定义过长。如果一定要显示变量类型,则可以采用类似于 GV_FXX(浮点型),GV_IXX(索引),GV_DXX(日期型)形式,可以用 “_” 后第一个字母来区分数据类型。只存在于 ABAP 语言中的 PARAMETERS 和 SELECT-OPTIONS 变量分别用 “P” 、“S” 作为前缀使用。
PARAMETERS: P_CARRID TYPE S_CARR_ID.
SELECT-OPTIONS: S_CARRID FOR SFLIGHT-CARRID.
2. 局部变量(24)
局部变量(Local Variable)是指只有在程序模块内部有效的变量。所谓的模块是指函数、子程序等为了实现单位功能集成成块的代码。局部变量定义方法如下所示。
定义局部变量
数据类型 | 前缀 | 使用实例 | 程序代码 |
字段 | V 或 D | LV_CARRID 或 LD_CARRID | DATA LV_SFLIGHT TYPE S_CARR_ID. 或 DATA LD_SFLIGHT TYPE S_CARR_ID. |
结构体 | S | LS_SFLIGHT | DATA LS_SFLIGHT TYPE SFLIGHT. |
常量 | C | LC_RATE | CONSTANTS LC_RATE TYPE I VALUE ‘3.14’. |
内表 | T | LT_SFLIGHT | DATA LT_SFLIGHT TYPE STANDARD TABLE OF SFLIGHT. |
类 | O | LO_ALVGRID | DATA LO_ALVGRID TYPE REF TO CL_SALV_TABLE. |
RANGE(范围) | R | LR_CARRID | RANGES LR_CARRID FOR SFLIGHT-CARRID. |
参照变量(数据对象) | F | LF_OBJ | DATA LF_OBJ TYPE REF TO OBJECT. |
2.2 ABAP基本数据类型
2.2.1 固定长度的 ABAP 基本数据类型(29)
基本数据类型
初始长度 | 可变长度 | 初始值 | 意义 | |
数字型 | ||||
I | 4 | 4 | 0 | 整数(自然数) |
F | 8 | 8 | 0 | 浮点型 |
P | 8 | 1-16 | 0 | Packed number 整数部分=16-小数指定 |
字符型 | ||||
C | 1 | 1~65535 | ‘……’ | 文本字段(alphanumeric characters) |
D | 8 | 8 | ‘00000000’ | 日期字段(样式:YYYYMMDD) |
N | 1 | 1~65535 | ‘0……0’ | 数字文本字段(数字型字符串)有前导0 |
T | 6 | 6 | ‘000000’ | (样式:HHMMSS) |
十六进制类型 | ||||
X | 1 | 1~65535 | X’0……0’ | 十六进制字段 |
2.2.2 数字型(30)
2. 数字运算符(演算子)
(1)基本运算法则
数字类型 F、I、P 在数据计算中使用的基本符号及关键字如下表所示。
基本运算法则
符号 | 说明 | 使用例 | 与符号相同的关键字 |
+ | 加法 | < p > = < n > + < m >. | ADD < n > TO < m >. |
- | 减法 | < p > = < m > - < n >. | SUBTRACT < n > FROM < m >. |
* | 乘法 | < p > = < m > * < n >. | MULTIPLY < m > BY < n >. |
/ | 除法 | < p > = < m > / < n >. | DIVIDE < m > BY < n >. |
DIV | 取整 | < p > = < m > DIV < n >. | |
MOD | 取余 | < p > = < m > MOD < n >. | |
** | 乘幂 | < p > = < m > ** < n >. |
通过下面的代码学习数据基本运算法则的使用方法。
DATA: gv_int1 TYPE i VALUE 2,
gv_int2 TYPE i VALUE 3,
gv_iresult TYPE i.
gv_iresult = gv_int1 + gv_int2.
WRITE: / '1:',gv_iresult.
ADD 1 TO gv_iresult.
WRITE: / '2:',gv_iresult.
DATA: gv_pack1 TYPE p DECIMALS 2 VALUE '2.17',
gv_pack1 TYPE p DECIMALS 2 VALUE '5.43',
gv_presult TYPE p DECIMALS 2.
gv_presult = gv_pack2 / gv_pack2.
WRITE: / '3:',gv_presult.
MULTIPLY gv_presult BY gv_pack2.
WRITE: / '4:',gv_presult.
DATA: gv_float1 TYPE f VALUE '1.337',
gv_float2 TYPE f VALUE '2.7',
gv_fresult TYPE f,
gv_cresult TYPE c LENGTH 16.
gv_fresult = gv_float2 * gv_float1.
WRITE: / '5:',gv_fresult.
CALL FUNCTION 'FLTP_CHAR_CONVERSION'
EXPORTING
DECIM = 2
INPUT = gv_fresult
IMPORTING
FLSTR = gv_cresult.
WRITE: / '6:',gv_cresult.
使用类型 F 时,需要调用 FLTP_CHAR_CONVERSION 函数把类型转换成字符型后进行输出。调用函数时指定参数 DECIM,则通过四舍五入计算出相应的小数位。
(2)数字运算用函数
数字运算用函数如下表所示。
数字运算用函数
函数 | 说明 | 使用例 |
ABS | 返回绝对值 | ABS( -100 ) 返回 100 |
SIGN | 返回符号 | 负数→-1, 0→0 正数→+ |
CEIL | 返回不小于该值的最小整数. | ceil( 1.3 ), ceil( 1.7 ) 返回 2 |
FLOOR | 与 CEIL 相反 | floor( 1.3 ), floor( 1.7 ) 返回 1 |
TRUNC | 取得整数部分 | trunc( 1.3 ), trunc( 1.7 ) 返回 1 |
FRAC | 取得小数部分 | frac( ‘2.9’ ) 返回 0.9 |
(3)Floating-Point 函数
Floating Point 函数
函数 | 功能 |
ACOS、ASIN、ATAN;COS、SIN、TAN | 三角函数(Trigonometric functions) |
COSH、SINH、TANH | 双曲线函数(Hyperbolic functions) |
EXP | 指数函数(Exponential function,e=2.7182818285). |
LOG | 自然对数函数(以 e 为底) |
LOG10 | 常用对数函数(以 10 为底) |
SQRT | 平方根函数(Square root) |
2.2.3 字符串类型(35)
字符串类型也称为字符串字段,分为一下 4 种。
C:用于定义文字、数字、特殊文字。
N:用于显示 C 类型数字,以字符串形式显示整数。
D:日期类型。
T:时间类型。
定义 C 类型数据时需要指定其字段长度。如果没有指定字段长度或数据类型时,默认为 1 位。指定类型 C 的长度时可以直接在变量后使用符号 “()” (如 Data: G_char(3) tyoe C.)或也可以使用关键字 LENGTH 指定。关键字 LENGTH 只适用于指定类型 C、N、D、T 的长度。下面所示语句虽然写法不同,但是执行结果是相同的。
DATA: gv_fd,
gv_fd TYPE c,
gv_fd(1) TYPE c,
gv_fd TYPE c LENGTH 1.
通过下面的代码学习字符串类型中的类型 C。
DATA: gv_f0,
gv_f1 TYPE c,
gv_f2(1) TYPE c,
gv_f3(2) TYPE c,
gv_f4 TYPE c LENGTH 2,
gv_f5(5),
gv_len TYPE i.
MOVE: 'CHINA' TO gv_f0,
'CHINA' TO gv_f1,
'CHINA' TO gv_f2,
'CHINA' TO gv_f3,
'CHINA' TO gv_f4,
'CHINA' TO gv_f5.
WRITE: / gv_f0,
/ gv_f1,
/ gv_f2,
/ gv_f3,
/ gv_f4.
gv_len = SRTLEN( gv_f5 ).
WRITE: / gv_len.
结果:
C
C
C
CH
CH
CHINA
5
MOVE 语句与符号 “=” 有相同的功能,用于赋值。另外还有 MOVE-CORRESPONDING 语句,两个不同结构的结构体或内表之间相互赋值时使用,此句的特点是赋值时与顺序无关,自动查找相同名字的变量进行赋值。Strlen 语句用于返回字符串长度。WRITE 语句用于输出报表数据。“/” 符号代表换行。类型 N 是以字符串形式显示数字的类型。下面通过下面的代码确认具体实现形式。
DATA: gv_num1 TYPE i,
gv_num2 TYPE n LENGTH 4.
gv_num1 = 89.
WWRITE: / gv_num1.
gv_num2 = 89.
WWRITE: / gv_num2.
结果:
89
0089
- 定义类型 I,与变量长度无关,输出变量自身值。而定义为类型 N,当变量值长度不足时,加前导零补足位数的形式输出且以字符串形式显示数值。
下面学习日期型 D 和时间型 T。
* 1.日期型计算
DATA: gv_date TYPE d.
gv_date = sy-datum.
WRITE: / gv_date.
gv_date= gv_date + 3.
WRITE: / gv_date.
* 2.时间型计算
DATA: gv_time TYPE t.
gv_time = sy-uzeit.
WRITE: / gv_time.
gv_time= gv_time - 60.
WRITE: / gv_time.
结果:
20210927
20210930
230519
230419
- 日期型
定义日期型变量 “gv_date” ,赋系统变量- “sy-datum” 。“gv_datum” 是存储当天日期的系统变量。日期型变量与数字型变量进行计算时可以计算出天数(day)。- 时间型
系统变量 sy-uzeit 中包含现在时刻。时间型变量以秒(second)为单位进行运算。
当用户登陆 SAP 系统后,系统基本信息自动会保存到 SYST 结构体中,用户本地 profile 信息 TIMEZONE 会保存到系统变量 SY-ZONLO 中。当然,存储系统时间的系统变量 sy-uzeit 和 sy-timlo 也是一样的。
String相关命令(39)
①FIND
ABAP字段中存在字段B时,SY-SUBRC 返回值为0
gv_str = 'ABAP'.
gv_chr = 'B'.
FIND gv_chr IN gv_str.
IF SY-SUBRC EQ 0.
WRITE 'B found'.
ENDIF.
结果:B found
②REPLACE
将ABAP变换成BBAP
gv_str = 'ABAP'.
gv_chr = 'BBAP'.
REPLACE 'ABAP' IN gv_str WITH gv_chr.
WRITE / gv_str.
结果:BBAP
③TRANSLATE
大小写字母转换 LOWER CASE / UPPER CASE,ABAP→abap / abap→ABAP
gv_str = 'ABAP'.
TRANSLATE gv_str TO LOWER CASE.
WRITE / gv_str.
结果:abap
④SHIFT
ABAP依次向左移动
gv_str = 'ABAP'.
SHIFT gv_str.
WRITE / gv_str.
结果: BAP
⑤CONDENSE
去空格并向左对齐,经常与 NO-GAPS 一起使用去掉空格
gv_str = 'AB AP'.
CONDENSE gv_str NO-GAPS.
WRITE / gv_str.
结果:ABAP
⑥OVERLAY
填充Character的空格,但不覆盖原来字符
gv_str = ' B P'.
gv_chr = 'AAAA'.
OVERLAY gv_str WITH gv_chr.
WRITE / gv_str.
结果:ABAP
⑦CONCATENATE
AB+AP连接成ABAP
gv_str = 'AB'.
gv_chr = 'AP'.
CONCATENATE gv_str gv_chr INTO gv_str.
WRITE / gv_str.
结果:ABAP
⑧SPLIT
以字符C为中心分为AB与AP
gv_str = 'ABCAP'.
SPLIT gv_str AT 'C' INTO gv_str gv_chr.
WRITE / gv_str gv_chr.
结果:AB AP
单引号“ ’ ”与grave“ ` ”的区别(39)
DATA gv_char(32) TYPE c.
gv_char = 'This is a'.
CONCATENATE gv_char 'text ' INTO gv_char SEPARATED BY space.
* 结果 => ''This is a text''
CONCATENATE gv_char `text ` INTO gv_char SEPARATED BY space.
* 结果 => ''This is a text ''
若使用 grave(`) ,则能够识别字符串中包含的所有空格。
SEPARATED BY space 加空格
数据字典类型与ABAP基本数据类型
程序中经常使用的ABAP数据字典类型(52) 面试
很难
ABAP数据字典类型 | ABAP基本数据类型 |
ACCP | N(6) |
CHAR n | C(n) |
CLNT | C(3) |
CUKY | C(5) |
CURR n,m | P((n+1)/2 DECIMAL m |
DEC n,m | P((n+1)/2 DECIMAL m |
DATS | D(8) |
FLTP | F(8) |
INT1 | X(1) |
INT2 | X(2) |
INT4 | X(4) |
LANG | C(1) |
NUMC n | N(n) |
PREC | X(2) |
QUAN n,m | P((n+1)/2 DECIMAL m |
RAW n | X(n) |
TIMS | T(6) |
UNIT | C(n) |
VARC n | C(n) |
LRAW | X(n) |
LCHR | C(n) |
STRING | STRING |
2.5 赋值
2.5.1 给变量赋值(52)
定义变量时可以通过 VALUE 语句赋初始值,实际处理数据的程序中使用 MOVE 或 WRITE TO 语句给变量赋值。
gv_char1 = gv_char.
MOVE gv_char TO gv_char1.
MOVE-CORRESPONDING gs_string TO gs_string1.
WRITE gv_char TO gv_char1(I).
MOVE TO 语句与 gv_char1 = gv_char. 中的 Equal(=) 语句相同。赋值字符串字段值时可以使用 MOVE-CORRESPONDING 语句。这时 gs_string 和 gs_string1 的字段名可以不相同。
MOVE-CORRESPONDING 语句还经常用于不同结构体之间赋值,其特点是找到名字相同的字段名进行赋值。当字段名及顺序不同的结构体之间相互赋值时,如果用 MOVE 语句,则会按顺序进行赋值,因此要使用 MOVE-CORRESPONDING 语句。 MOVE 语句还可以用于类型转换(Type Conversions),即 gs_string 的数据类型会转换成 gs_string1 类型。
在ABAP语言中除了类型 D(Date) 与类型 T(Time) 外都可以互相转换类型,一共有64种形态的类型可以相互转换。
WRITE 语句主要有两种用法。一种是输出报表(Output to a list),另一种是变量赋值(Output to a field or internal Table)。变量赋值时一般用 WRITE TO 语句,将数据对象 gv_char 的值转换成类型C后赋给 gv_char1 。前提是 gv_char 类型可以转换成C类型的字段,否则会发生 Syntax
或者runtime error
的错误。后面 (I) 里可以使用除了 UNDER 和 NO-GAP 以外的所有编辑格式选项。关于 (I) 具体参数可以在 HELP 中查询。(摁F1)
下面是关于 MOVE-CORRESPONDING 语句的代码,其中结构体 GS_REN 和 GS_INFO 由不同字段构成。将结构体 GS_REN 赋值给结构体 GS_INFO 时,需要多次使用 MOVE 语句才能实现。但是如果使用 MOVE-CORRESPONDING 语句,则使用一次即可实现。
DATA: BEGIN OF gs_ren,
name(20) VALUE 'Kim Sung Joon',
country(10) VALUE 'China',
city(20) VALUE 'Beijing',
END OF gs_ren,
BEGIN OF gs_info,
name(20),
city(20),
phone(10) VALUE '1521001234',
END OF gs_info.
MOVE-CORRESPONDING gs_ren TO gs_info.
WRITE: / gs_info-name,
gs_info-city,
gs_info-phone.
结果:
Kim Sung Joon Beijing 1521001234
第3章 OPEN SQL 与 NATIVE SQL
3.1 概要
3.1.4 OPEN SQL 与 NATIVE SQL(60)
1. OPEN SQL
OPEN SQL 是由创建数据库数据的 ABAP 命令构成的,在不同的 DBMS(数据库管理系统)环境下其语法相同。 OPEN SQL 不能使用 DDL、DCL,只能使用类似于 SELECT 语句的 DML 语言。另外,还可以使用本地缓冲器,并且比 NATIVE SQL 的使用方法简单。ABAP 程序有激活时自动执行 Syntax Check 的特点。
2. NATIVE SQL
NATIVE SQL 语言可以直接连接到数据库使用 DML、DDL 语言。
3.1.6 OPEN SQL 概要(61)
OPEN SQL 命令语句
关键字 | 功能 |
SELECT | 从数据库表中读取数据 |
INSERT | 往数据库表中追加数据 |
UPDATE | 修改数据库表的数据 |
MODIFY | 执行INSERT + UPDATE 功能 UPDATE:数据库表中已存在此数据时(以 key 值区分是否存在) INSERT:数据库表中不存在此数据时(以 key 值区分是否存在) |
DELETE | 删除数据库表数据 |
3.2 OPEN SQL ——读取数据
读取数据的命令
语句 | 功能 |
SELECT < result > | SELECT 语句可以罗列数据库表字段,读取一件或多件数据 |
INTO < target > | INTO 语句用来指定查询出来的数据存储地即变量,然后在程序中使用此变量 |
FROM < source > | FROM 语句用来指定要查询的数据库表。可以写在 INTO 语句前后 |
WHERE < cond > | 可以限制要查询数据的条件 |
GROUP BY < fidleds > | 用于分组查询数据。例如,分组求合计时经常使用 GROUP BY语句 |
HAVING < cond > | HAVING 是用于限制 GROUP BY 条件的语句。类似于 SELECT 的 WHERE 语句 |
ORDER BY < fidleds > | 用于排序(sort)查询的数据 |
3.2.1 SELECT 语句(63)
SELECT 语句从数据库表中读取必要的数据。
1. SELECT
SELECT 语句分为两个部分。一部分为< lines >,用于指定查询数据的条数,当查询一条时用 SINGLE 语句。另一部分是< conlumns >,用于指定要查询的数据库表字段。
SELECT <lines> <conlumns>...
2. 一条数据
从数据库中取得一条数据时使用 SINGLE 语句。使用此语句只会取得一条数据,因此要正确给出要查询数据的条件,即在 WHERE 条件里追加所有 key 值,当没有指出所有 key 值时,会返回多条中的任意一条,会导致读取的数据与预期结果不同。读取数据库表所有字段时使用 *。
如果系统找到一个完全符合指定条件的行, SY-SUBRC 返回0,否则返回4。
SELECT SINGLE matnr
INTO lv_matnr/gs_data-matnr
FROM VBAK
WHERE vbeln = lv_vbeln/gs_data-vbeln.
3. Several Line
当取得多条数据时 SELECT 结果会保存到内部定义的表中。这种表在ABAP语言里称为内表(Internal Table)。 DISTINCT 语句用于删除重复值。
SELECT [DISTINCT] matnr
WHERE
4. AS(别名)
利用 AS 语句可以给字段指定别名。
SELECT matnr AS matnr1
3.2.2 INTO 语句(64)
用此语句指定存储 SELECT 语句查询的结果值的目的地。
1. 结构体
当查询一条数据时使用结构体(Work Area,变量,结构体),使用星号*
能取得所有字段的值。此时使用 CORRESPONDING FIELDS OF 语句会自动找到相同字段名匹配赋值。
SELECT ...
INTO [CORRESPONDING FIELDS OF] <gs_data>.
2. 内表(Internal Table)
当查询多条数据时使用内表。往内表插入数据时使用 APPENDING ,不能使用 INTO ,INTO 是删除内表数据后插入数据时使用的。
如果不用 CORRESPONDING FIELDS OF 语句的话,会按顺序插入内表;用的话,按照字段名插入。
SELECT ...
INTO|APPENDING [CORRESPONDING FIELDS OF] TABLE <itab>.
3. Single Field(65)
查询数据库表的个别字段或者使用 Aggregate 函数时使用如下所示的语句。INTO 语句后面列出两个以上目标地时需要用括号分别指定变量名。若存在空白,则会发生语法错误。
SELECT ...
INTO (f1,f2,...) ...
在 SELECT 语句里查询两个字段的语句如下所示。推荐在 FROM 后使用 WHERE 语句来限制查找到数据的条件。
SELECT SINGLE carrid connid
INTO (gv_carrid,gv_connid)
FROM SFLIGHT.
3.2.3 FROM 语句(65)
用 FROM 语句指定要查询数据的相应数据库表(或者视图)。FROM 语句后面可以指定一个数据库表或者多个数据库表的连接。不仅可以使用 AS 语句添加别名,还可以动态地定义数据库表名。FROM 语句有两个选项,一个是定义表的选项,另一个是控制访问数据库表的选项。
SELECT ...
FROM table option ...
在 FROM 语句中控制访问数据库表的选项语法如下表所示。
FROM 语句的选项
语句 | 说明 |
CLIENT SPECIFIED | 解除自动 clint 设置(可跨公司选择数据) |
BYPASSING BUFFER | 不会从 SAP 本地缓冲器中读取数据。即使数据库表中设置了 Buffering 也会直接访问数据库读取数据 |
UP TO n ROWS | 限制查询数据的个数。可以预防由于用户使用问题而导致的降低数据库性能问题。例如,由于在选择条件中没有指定日期而导致查询大批量数据的情况 |
1. 选择静态表
可以定义静态表查询数据。这时可以使用别名,但是表名不能在 SELECT 语句中使用。
SELECT ...
FROM <dbtab> [AS <alias>] <options>
2. 选择动态表
可以定义动态表查询数据。这时表名一定要用大写字母指定并且必须是 ABAP 数据字典中存在的名字。
SELECT ...
FROM (dbtab)
3. JOIN 语句
在关系数据库中同时取得多个数据库表值时使用 JOIN 语句来连接表。一般使用 Primary Key(此后用缩写PK来替代)和 Foreign Key(此后用缩写FK来替代)来连接数据库表,但是偶尔也会用符合逻辑的相关值进行连接,用 ON 语句指定两个表连接条件。
SELECT ...
FROM <tab> [INNER] JOIN <dbtab> [AS <alias>] ON <cond> <options> ...
下面是说明 INNER JOIN 语句的实例。可以发现,存储航空信息的数据库表SFLIGHT中不存在航空公司名字,但是数据库表SCARR中存在航空公司ID所对应的航空公司名字。因此用 JOIN 语句连接这两个表就可以读取航空公司的名字。使用 JOIN 语句时若不指定 JOIN 类型,则默认为是 INNER JOIN 。
TYPES: BEGIN OF t_str,
carrid TYPE sflight-carrid,
carrname TYPE scarr-carrname,
END OF t_str.
DATA: gs_str TYPE t_str.
SELECT SINGLE a~carrid
b~carrname
INTO CORRESPONDING FIELDS OF gs_str
FROM sflight AS a INNER JOIN scarr AS b ON a~carrid EQ b~carrid
WHERE a~carrid = 'AA'.
WRITE: gs_srt-carrid,gs_str-carrname.
结果:
AA American Airlines
上面代码中的 JOIN 语句中 AS语句用于指定别名即 sflight AS a 语句中 a 作为数据库表 sflight 别名使用。使用别名能简化代码,从上面代码中可以看出,sflight~carrid 语句可以用 a~carrid 语句替代。
4. INNER JOIN 与 OYTER JOIN
数据库表连接类型有 INNER JOIN 与 OUTER JOIN 这两种。其中 OUTER JOIN 的方法如下所示。
SELECT ...
FROM <tab> LEFT [OUTER] JOIN <dbtab> [AS <alias>] ON <cond> <options> ...
假设有如下图所示的两个人事信息数据库表。数据库表 INSA 存储员工基本信息,数据库表 CERT 存储员工取得的证书信息。员工 ZHOU 与 KIM 有证书,而员工 ZHONG 却没有证书。当以员工编号字段为基准执行 INNER JOIN ,则从查询对象中应该排除员工 ZHONG 。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qlZNaiPf-1658986980533)(C:\Users\尚嘉伟\AppData\Roaming\Typora\typora-user-images\image-20211005131550741.png)]
INSA 表与 CERT 表的 INNER JOIN
假设要显示所有员工的基本信息并且还要追加显示证书信息时要使用 OUTER JOIN 。在 ABAP OPEN SQL 中只能使用 LEFT OUTER JOIN 。此语句是将左边的表作为基准表读取数据。其结果如下图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YKS999M4-1658986980535)(C:\Users\尚嘉伟\AppData\Roaming\Typora\typora-user-images\image-20211005131634894.png)]
INSA 表与 CERT 表的 OUTER JOIN
下面代码说明 OUTER JOIN 的方法。假设数据库表 SCARR 中所有航空公司的名字都不存在,因此航空公司为了避免遗漏航空公司的航空器信息要 LEFT OUTER JOIN 数据库表 SFLIGHT 与数据库表 SCARR。
TYPES: BEGIN OF t_str,
carrid TYPE sflight-carrid,
carrname TYPE scarr-carrname,
END OF t_str.
DATA: gs_str TYPE t_str.
SELECT SINGLE a~carrid
b~carrname
INTO CORRESPONDING FIELDS OF gs_str
FROM sflight AS a LEFT OUTER JOIN scarr AS b ON a~carrid EQ b~carrid
WHERE a~carrid = 'AA'.
WRITE: gs_srt-carrid,gs_str-carrname.
5. 限制查询个数
利用下列语句可以限制要查询的数据个数。
SELECT ...
FROM <tab>
UP TO <n> ROWS...
3.2.4 WHERE 语句(69)
WHERE 语句可以指定查询条件使用户正确地取得自己所需数据,此语句还适用于 UPDATE、DAELETE 等命令
1. WHERE 条件语句
SELECT ...
FROM <tab>
UP TO <n> ROWS...
下表说明在 WHERE 语句中使用的运算符类型。
运算符 | 意义 | 运算符 | 意义 | 运算符 | 意义 |
EQ = | 等于 | GE >= | 大于或等于 | GT > | 大于 |
NE <> >< | 不等于 | LE <= | 小于或等于 | LT < | 小于 |
2. Interval 条件
需要在条件中追加范围值时使用此语句。
SELECT ...
WHERE <s> [NOT] BETWEEN <f1> AND <f2>
例如,取得字段 COL 为 1~10 的数据时可以写成如下代码。
WHERE COL BETWEEN 1 AND 10
3. 字符串比较
比较字符串时使用 LIKE 语句。若要取得以 ABC 开头的数据,则可以追加如下条件。
COL2 ='ABCDEFGHIJK'.
SELECT ~ WHERE COL2 LIKE 'ABC%'.
若要取得以 ABC 开头的4位长字符串时,例如,在 ABCD、ABCE、AFCF、ABCG 等数据中只比较一位时可以使用符号 ‘_’ 。
WHERE COL2 LIKE 'ABC '
4. LIST VALUE
利用 IN 语句可以取得符合多种情况的数据。例如,读取居住在’北京’、'上海’的人时条件可以为 “WHERE 地址 IN (‘北京’,‘上海’)” 。
SELECT ... WHERE <s> [NOT] IN (<f1>,...,<fn>) ...
7. FOR ALL ENTRIES 语句
SELECT ...
FROM 数据库表
FOR ALL ENTRIES IN 内表<itab>
WHERE 字段 = 内表itab-字段 "要用内连接
FOR ALL ENTRY 语句与嵌套 SELECT 语句或 Subquery 的功能相似。使用 FOR ALL ENTRY 语句时,WHERE 语句中使用的条件必须是内表 itab 中存在的字段。
*注意
itab 的字段要与比较对象的表字段类型一致。
不能使用类似 LIKE、BETWEEN、IN 等比较语句。
itab 中自动删除重复数据(Unique Key为基准)。
itab 为空则取得所有数据。
itab 中数据多时会增加 LOOP 循环次数,因此会降低选择速度。例如 itab 中数据为3条,则会执行3次 “SELECT ENDSELECT”。
下列代码是先查询存储航班时刻表的数据库表 spfli 的所有数据后用 FOR ALL ENTRIES 语句从日期别航班运行信息数据库表中查询相关数据的程序。
DATA: gt_spfli TYPE TABLE OF spfli,
gt_sflight TYPE TABLE OF sflight,
gs_sflight TYPE sflight.
SELECT *
FROM spfli
INTO TABLE gt_spfli.
SELECT *
FROM sflight
INTO TABLE gt_sflight
FOR ALL ENTRIES IN gt_spfli
WHERE carrid = gt_spfli-carrid
AND connid = gt_spfli-connid.
LOOP AT gt_sflight INTO gs_sflight.
WRITE: / gs_sflight-carrid,
gs_sflight-connid.
ENDLOOP.
3.2.5 GROUPING 语句
使用 Aggregate 函数之前,选择数据时需要用 GROUP BY 语句进行分组。GROUPP BY 语句是当表的特定字段中存在相同值时其值就显示在一行中。
SELECT <f1> <f2> <agg>...
GROUP BY <f1> <f2>....
GROUP BY 语句后使用的字段一定要在 SELECT 语句中查询出来。
在 SELECT 语句中可以使用字段及函数。Aggregate 函数请参照下表。
AGGREGATE 函数种类
函数 | 功能 | 函数 | 功能 | 函数 | 功能 |
AVG | 取平均值 | MAX | 取最大值 | MIN | 取最小值 |
COUNT | 取个数 | STDDEV | 取标准偏差 | SUM | 取合计 |
也可以动态地指定 GROUP BY 语句。
GROUP BY (itab)...
下面练习一下分别取得每个航班ID的平均预约占有率。
DATA: gv_carrid TYPE sflight-carrid,
gv_connid TYPE sflight-connid,
gv_paymentsum TYPE i.
SELECT carrid
connid
AVG( paymentsum )
INTO (gv_carrid,gv_connid,gv_paymentsum)
FROM sflight
GROUP BY carrid connid.
WRITE: / gv_carrid,
gv_connid,
gv_paymentsum.
结果:
AA 0017 136,905
AA 0064 90,139
AZ 0555 33,741
AZ 0788 320,638
在 OPEN SQL 中利用 SUM 函数时使用 INTO CORRESPONDING FIELDS OF TABLE 语句会取不到预期的结果。此时要利用 AS 语句为合计的字段起个别名,具体使用方法如下面代码所示。
SELECT carrid SUM( price ) AS price FROM sflight INTO CORRESPONDING FIELDS OF TABLE gt_glt WHERE carrid = 'AA'.
3.2.6 GROUPING 条件语句——HAVING(73)
HAVING 是用 GROUP BY 语句分组查询数据时使用的条件语句。类似于 WWHERE 条件语句可以动态地定义其条件。
SELECT <f1> <f2> <agg>...
...
GROUP BY <f1> <f2>
HAVING <cond>.
要取得 3.2.5 代码中的平均占有率大于 100,000 件的数据时实现方法如下所示。
SELECT carrid
connid
AVG( paymentsum )
INTO (gv_carrid,gv_connid,gv_paymentsum)
FROM sflight
GROUP BY carrid connid
HAVING AVG( paymentsum ) > 100000.
3.2.7 SORT 语句(73)
在查询数据时使用 ORDER BY 语句,则查询出来的结果会按照 ORDER BY 指定的字段进行排序。若不使用 ORDER BY 就会任意地显示排序结果。
- ORDER BY PRIMARY KEY
- 根据表的 KEY 值进行排序。
- 只适用于 SELECT * 语句。
- 在 JOIN 语句和视图中无法使用。
SELECT <lines> *
...
ORDER BY PRIMARY KEY.
ORDER BY 中可以使用所有字段。用 ASCENDING,DESCENDING 语句可以指定排序类型,如升、降序。
SELECT ...
...
ORDER BY <f1> [ASCENDING|DESCENDING]
<f2> [ASCENDING|DESCENDING] ...
也可以动态地定义 ORDER BY 语句。使用的内表类型应为 char 且长度不能超过72位。
SELECT ...
...
ORDER BY (itab)
通过下面的代码练习做一个以预约座位为基准升序排序的程序。
DATA: gv_carrid TYPE sflight-carrid,
gv_connid TYPE sflight-connid,
gv_paymentsum TYPE i.
SELECT carrid
connid
AVG( paymentsum ) as paymentsum
INTO (gv_carrid,gv_connid,gv_paymentsum)
FROM sflight
GROUP BY carrid connid.
WRITE: / gv_carrid,
gv_connid,
gv_paymentsum.
ENDSELECT.
结果:
AZ 0555 33,741
LH 2407 38,371
LH 2402 79,572
DL 1699 80,025
由于在 ORDER BY 语句中无法使用 AVG(paymentsum) 等 Aggregate 函数,因此查询数据时要用 AS 语句起别名 “paymentsum”。
3.3 OPEN SQL——数据修改
3.3.1 INSERT 语句(75)
往
中无法使用。
SELECT <lines> *
...
ORDER BY PRIMARY KEY.
ORDER BY 中可以使用所有字段。用 ASCENDING,DESCENDING 语句可以指定排序类型,如升、降序。
SELECT ...
...
ORDER BY <f1> [ASCENDING|DESCENDING]
<f2> [ASCENDING|DESCENDING] ...
也可以动态地定义 ORDER BY 语句。使用的内表类型应为 char 且长度不能超过72位。
SELECT ...
...
ORDER BY (itab)
通过下面的代码练习做一个以预约座位为基准升序排序的程序。
DATA: gv_carrid TYPE sflight-carrid,
gv_connid TYPE sflight-connid,
gv_paymentsum TYPE i.
SELECT carrid
connid
AVG( paymentsum ) as paymentsum
INTO (gv_carrid,gv_connid,gv_paymentsum)
FROM sflight
GROUP BY carrid connid.
WRITE: / gv_carrid,
gv_connid,
gv_paymentsum.
ENDSELECT.
结果:
AZ 0555 33,741
LH 2407 38,371
LH 2402 79,572
DL 1699 80,025
由于在 ORDER BY 语句中无法使用 AVG(paymentsum) 等 Aggregate 函数,因此查询数据时要用 AS 语句起别名 “paymentsum”。
3.3 OPEN SQL——数据修改
3.3.1 INSERT 语句(75)
往