SAP 数据库操作相关的 SQL 语句:查询篇
ABAP SQL 介绍
ABAP SQL 是 SQL 的子集,SQL 是访问数据库的标准化语言。用于读取和更改数据的主要 ABAP SQL 关键字如下:
关键字 | 作用 |
---|---|
SELECT |
从数据库表中读取数据 |
INSERT |
往数据库表中新增行 |
UPDATE |
更改数据库表行的内容 |
MODIFY |
将行插入数据库表或更改现有行的内容 |
DELETE |
从数据库表中删除行 |
ABAP SQL 语句使用 ABAP SQL 接口。该接口将所有访问 AS ABAP 标准数据库的 ABAP SQL 语句转换为平台相关的 SQL,并将结果转发到数据库系统。
Open SQL 语句只能使用在 ABAP 字典中创建的数据库表。打开 SQL 语句,对 SAP 数据库中的数据执行读取、写入、修改、插入、更新或删除等操作。
Open SQL 语句被传递到数据库接口。数据库接口将开放式SQL转换为原生SQL,传递给数据库得到结果。
视图的处理方式与打开的 SQL 语句中的数据库表相同。下图指定了 Open SQL 与关系数据库接口的架构:
SELECT 语句
SELECT
语句用于从数据库表中读取数据。在进行编程时,始终建议仅检索一条记录,以便更顺利地进行处理。如果 SELECT
语句检索多行,则结果集中的第一行将检索到工作区。如果需要在 ABAP 程序中处理使用 SELECT
语句检索的所有行,那么建议使用 CURSOR
语句。
语法:
SELECT required-columns
INTO host-variables
FROM source-table
[WHERE logical-condition]
[GROUP BY grouping-columns]
[HAVING having-condtion]
[ORDER BY ordering-columns].
- required-column:指定表的列名,从那里检索到主机变量的数据。
- host-variables:指定主变量,从 required-columns 中获取的列数据。
- source-table :指定数据库表或视图名称。
- logical-condition:指定选择标准的条件。
- grouping-columns:指定分组列以从具有相同值的多行中生成单行。
- having-conditions:指定
GROUP BY
子句的逻辑条件 - ordering-columns:指定结果行的顺序。排序可以是升序 (ASC) 或降序 (DESC)。
您可以使用 ABAP SQL SELECT
语句从一个或多个数据库表(或视图)读取数据。这可以通过将结果集分配给合适的数据对象来创建多行或单行结果集,即你可以将多行读取结果存储在内部表中,也可以将单行结果存储在结构中。 SELECT
语句包含多个用于不同目的的子句。
数据库查询的几个原则
在使用 SELECT
语句中,尽可能把握以下几个原则:
尽可能的在
WHERE
条件中包含多的索引字段作为条件WHERE
条件中的索引字段按表中的索引顺序排列尽可能的在
WHERE
条件中包含多的条件,即使字段不是索引的在
SELECT
完成之后,使用SY-SUBRC
进行检查,每次执行 SELECT 语句后,如果操作成功,则系统字段 sy-subrc 更新为 0,如果不成功则更新为 0。执行
SELECT
语句后,系统字段SY-DBCNT
包含检索到的数据库行数。
不要在 LOOP
循环中使用 SELECT
语句
在循环中使用 Select
语句将会频繁的访问表,尽量减少数据库访问的操作。以下语句是不建议的。
LOOP AT it_tab INTO wa_tab.
SELECT * FROM MARA INTO TABLE it_mara WERE matnr = wa_tab-matnr.
ENDLOOP.
取数的时候不能使用 SELECT……ENDSELECT
语句循环操作
错误:
SELECT * FROM dbtab.
MOVE-CORRESPONDING dbtab TO it_tab.
APPEND it_tab.
ENDSELECT.
正确:
SELECT * FROM dbtab INTO TABLE it_tab.
注意:必须避免嵌套的 SELECT,因为每条记录将连接一次数据库。
尽量多使用内表
- 为了提高程序的性能,通常先把数据库表中的数据取到内表中,在内表进行数据处理。减少重复访问相同数据表的情况。
例:
SELECT <FIELD>
与 SELECT *
比较
- 尽可能使用
SELECT <FIELD>
来代替SELECT *
,以减少数据传输量,当数据量大时,前者速度会明显更快。
不建议写法 | 建议写法 |
---|---|
SELECT * FROM dbtab INTO TABLE it_tab WHERE <condition>. |
SELECT field1 field2 FROM dbtab INTO TABLE it_tab WHERE <condition n>. |
仅用于某种特殊情况时,如表的字段数很少或数据记录不多 | 当表中包含的大量字段时, 使用 SELECT <Field> 虽然会增加代码的工作量,但会减少内存的使用及网络的负担 |
外部检查
尽可能避免使用 SELECT COUNT (*)
来确认表存在的记录数,因为该语句将会对表进行全扫描
SELECT SINGLE
语句
当使用
SELECT SINGLE
时,要求在WHERE
条件语句中包含所有的关键字当不能确定所有关键字而能确定只有一条记录匹配时,可使用
SELECT ... UP TO 1 ROWS
来查询
不要在 SELECT
语句中排序
对数据排序有两种方式:一种为在数据库服务器中排序;一种为在应用服务器中排序。
不建议写法 | 建议写法 |
---|---|
SELECT field1 field2 FROM dbtab INTO TABLE it_tab WHERE<condition>. ORDER BY field1. |
SELECT field1 field2 FROM dbtab INTO TABLE it_tab WHERE <condition n>. SORT it_tab BY field1. |
应用服务器排序更快 |
SELECT DISTINCT
语句使用
尽可能避免在 SELECT
语句中使用 GROUP BY
, ORDER BY
, DISTINCT
等功能。 需要在数据库服务器进行排序,且会影响整个系统性能如果没有合适的索引,使用DISTINCT语句时,数据库服务器经常不访问缓存
不建议写法:
SELECT DISTINCT field FROM dbtab INTO TABLE it_tab WHERE<condition>.
建议写法:
SELECT field FROM dbtab INTO TABLE it_tab WHERE <condition n>.
SORT it_tab BY field1.
DELETE ADJACENT DUPLICATES FROM it_tab COMPARING field.
FOR ALL ENTRIES
语句
FOR ALL ENTRIES
后紧跟的内表称为驱动内表。
在使用该语句时,驱动内表不能为空,若为空,则等价于无此条件,可能造成全表的检索。所以,在使用 FOR ALL ENTRIES 时,要先对驱动内表是否为空进行判断
在使用该语句前,尽可能保持少的驱动内表条目数,尽可能使驱动内表中的条目为唯一的(可先进行删除重复行等操作)。这样可避免在数据库中进行了不必要的读取
避免使用该语句读取小的数据库表(如配置表),对于小的数据库表使用单独的SELECT语句将会更好
使用该语句时,尽可能的连接数据库表中的索引,否则将会重复的全表扫描,并注意按数据库表中的索引顺序来写WHERE语句
驱动内表与
INTO
后的内表不可以是同一个内表
INNER JOIN
与 LEFT OUTER JOIN
语句
表连接取数是在数据库服务器里进行的,可以减少数据在网络上的传输。但是有一个缺点是表连接不使用应用服务器的缓存。
SELECT vbak~auart vbap~matnr INTO TABLE it_tab
FROM vbak AS vbak INNER JOIN vbap AS vbap ON vbak~vbeln = vbap~vbeln
WHERE vbeln IN s_vbeln.
vbak为主表,vbap为副表
在
WHERE
条件中必须有主表的关键字或索引在
WHERE
条件中尽可能的指定跟主表有关的条件在某种情况下可以考虑建立对应的视图来代替表连接的使用
INNER JOIN
语句
在使用该语句时我们一般以较小的表作为主表。当然也存在一些例外,它与数据形式和筛选状态有关。
当该表存在一些比较特殊的主键或第二索引时,这也是程序优化的主要方向之一
当该表存在最大的筛选条件时,它可以减少数据库 I/O 读取和硬盘读取的时间
LEFT OUTER JOIN
语句
使用 LEFT OUTER JOIN
时应特别注意,该语句会读取 OUTER
表中的所有数据,不管该数据在 INNER
表中是否存在,当在 INNER
表中没有匹配的数据时,字段值将为 NULL
以 PACKAGE
的形式存取数据
当表的数据量很大时,使用
SELECT PACKAGE SIZE
语句可将数据以包的形式进行封装,在LOOP
循环中就可以包的形式对数据进行操作在
APPENDING TABLE
中不可使用PACKING SIZE
在
FOR ALL ENTRIES
中不可使用PACKING SIZE
,FOR ALL ENTRIES
会定义其自己的PACKAGE
大小
- 点赞
- 收藏
- 关注作者
评论(0)