尽量不要使用SELECT… ENDSELECT,会给访问数据库带来额外的网络开销(每次循环都会访问两次数据库)
- 如果需要检查表或视图是否有满足某条件的记录存在,请使用Select … Up To 1 Rows 语句,而不要使用带Exit的Select-Endselect-loop语句。如果条件中包含所有的主键字段,则应该使用Select Single语句。Select Single语句仅需要与数据库通信一次,而 Select-Endselect则需要两次。
案例:禁止使用
SELECT * FROM SBOOK INTO GS_SBOOK
WHERE CARRID = 'LH'.
EXIT.
ENDSELECT.
IF SY-SUBRC = 0.
案例:正确示例
SELECT SINGLE * FROM SBOOK INTO GS_SBOOK
WHERE CARRID = 'LH'.
IF SY-SUBRC = 0.
ENDIF.
- 如果想查询最大值、最小值、总和、平均值或者条目数,则应该使用统计函数;这样可以大大降低网络负载
案例:禁止使用
DATA: MAX_MSGNR type t100-msgnr.
MAX_MSGNR = '000'.
SELECT * FROM T100 INTO T100_WA
WHERE SPRSL = 'D' AND
ARBGB = '00'.
CHECK: T100_WA-MSGNR > MAX_MSGNR.
MAX_MSGNR = T100_WA-MSGNR.
ENDSELECT.
案例:正确示例
DATA: LV_MAX_MSGNR type t100-msgnr.
SELECT MAX( MSGNR ) FROM T100 INTO LV_MAX_MSGNR
WHERE SPRSL = 'D'
AND ARBGB = '00'.
- 如果仅需读取表或视图中的个别字段,那么应该使用select列表而不要使用Select * ;这样可以大大降低网络负载。
案例:禁止使用
SELECT * FROM DD01L INTO LS_DOM
WHERE DOMNAME LIKE 'CHAR%'
AND AS4LOCAL = 'A'.
APPEND LS_DOM TO GT_DOM
ENDSELECT.
案例:正确示例
SELECT DOMNAME FROM DD01L
INTO TABLE GT_DOM
WHERE DOMNAME LIKE 'CHAR%'
AND AS4LOCAL = 'A'.
- 一般情况下使用Into Table总是会快于Select循环中使用Append 语句
案例:禁止使用
SELECT * FROM T006 INTO LS_T006.
APPEND LS_T006 TO LT_T006.
ENDSELECT.
案例:正确示例
SELECT * FROM T006
INTO TABLE LT_T006.
- 更新数据库表时,尽可能使用内表更新而不要使用单行操作。应用程序和数据库系统频繁通信会造成大量的系统负载
案例:禁止使用
LOOP AT LT_CUS INTO LS_CUS.
INSERT INTO CUSTOMERS VALUES LS_CUS.
ENDLOOP.
案例:正确示例
INSERT CUSTOMERS FROM TABLE LT_CUS.
- 如果要从几个逻辑关联的表中读取数据,应该使用表连接而不要使用嵌套的select语句;这样可以有效的降低网络负载。
案例:禁止使用
SELECT * FROM SPFLI INTO LS_SPFLI.
SELECT * FROM SFLIGHT INTO LS_SFLIGHT
WHERE CARRID = LS_SPFLI-CARRID
AND CONNID = LS_SPFLI-CONNID.
ENDSELECT.
ENDSELECT.
案例:正确示例
SELECT * INTO TABLE LT_FLIGHT
FROM SPFLI AS P INNER JOIN SFLIGHT AS F
ON P~CARRID = F~CARRID
AND P~CONNID = F~CONNID.
- 使用For all entries in之前必须先判断内表是否为空,如果内表为空则不会进行连接查询
案例:禁止使用
SELECT VBLEN POSNR
INTO TABLE GT_SOITEM
FROM VBAP
FOR ALL ENTRIES IN GT_VBAK
WHERE VBELN = GT_VBAK-VBELN.
案例:正确示例
IF NOT GT_VBAK[] IS INITIAL.
SELECT VBLEN POSNR
INTO TABLE GT_SOITEM
FROM VBAP
FOR ALL ENTRIES IN GT_VBAK
WHERE VBELN = GT_VBAK-VBELN.
ENDIF.
- 不要JOIN超过三张表,连接查询表过多会影响查询效率,而且不便于排错,应该拆分为多个表连接查询。如果一定要连接很多表,可以在hana平台中使用cdsview
案例:禁止使用
* 获取生产订单数据
SELECT
AFPO~AUFNR,
JEST~STAT,
AUFK~AUART,
T003P~TXT,
AUFK~VAPLZ,
* AUFK~WAWRK,
AFPO~MATNR,
MAKT~MAKTX,
AFKO~GLTRP,
AFKO~GSTRP,
AFPO~MEINS,
AFPO~PSMNG,
AFPO~WEMNG,
AFPO~CHARG
FROM AFPO
LEFT JOIN AUFK ON AUFK~AUFNR = AFPO~AUFNR
LEFT JOIN T003P ON AUFK~AUART = T003P~AUART
LEFT JOIN MAKT ON AFPO~MATNR = MAKT~MATNR
LEFT JOIN JEST ON AUFK~OBJNR = JEST~OBJNR
LEFT JOIN AFKO ON AFKO~AUFNR = AFPO~AUFNR
WHERE
AFPO~MATNR IN @s_matnr AND
AFPO~AUFNR IN @s_aufnr AND
AUFK~AUART IN @s_auart AND
JEST~STAT IN @s_stat AND
AUFK~VAPLZ IN @s_vaplz AND
MAKT~SPRAS = @sy-LANGU AND
T003P~SPRAS = @sy-LANGU
INTO CORRESPONDING FIELDS OF TABLE @gt_order.
案例:正确示例
* 筛取主表信息
SELECT
AFPO~AUFNR,
AUFK~AUART,
AUFK~VAPLZ,
AFPO~MATNR,
AFKO~GLTRP,
AFKO~GSTRP,
AFPO~MEINS,
AFPO~PSMNG,
AFPO~WEMNG,
AFPO~CHARG,
AUFK~OBJNR,
T003P~TXT
FROM AFPO
LEFT JOIN AUFK ON AUFK~AUFNR = AFPO~AUFNR
LEFT JOIN AFKO ON AFKO~AUFNR = AFPO~AUFNR
LEFT JOIN T003P ON T003P~AUART = AUFK~AUART
WHERE
AFPO~MATNR IN @s_matnr AND
AFPO~AUFNR IN @s_aufnr AND
AUFK~AUART IN @s_auart AND
AUFK~VAPLZ IN @s_vaplz AND
T003P~SPRAS = @sy-LANGU
INTO CORRESPONDING FIELDS OF TABLE @gt_order.
CHECK gt_order IS INITIAL.
* 筛取MAKT从表信息
SELECT
MAKTX,
MATNR
FROM MAKT
FOR ALL ENTRIES IN @gt_order
WHERE
MAKT~MATNR = @gt_order-matnr AND
MAKT~SPRAS = @sy-LANGU
INTO CORRESPONDING FIELDS OF TABLE @DATA(lt_makt).
* 筛取jest从表信息
SELECT
STAT,
OBJNR
FROM JEST
FOR ALL ENTRIES IN @gt_order
WHERE
JEST~STAT IN @s_stat AND
JEST~OBJNR = @gt_order-OBJNR
INTO CORRESPONDING FIELDS OF TABLE @DATA(lt_jest).
LOOP AT gt_order INTO gw_order.
*给gt_order主表赋值
ENDLOOP.