ABAP 开发系列(08): SAP Open SQL

来源:互联网 发布:网络客服提成方案 编辑:程序博客网 时间:2024/05/16 14:34

  在学习 ABAP WorkBench时了解到SAP 的三层架构:

表现层(Presentation),应用层(Application),数据层(Database)

Open SQL就发生在 Application 和 Database 之间;

SAP Application将发送的Open SQL请求,与Database进行匹配,转换成接受的SQL语句,

DB再执行SQL,将结果返回给Application。

 

1.Open SQL 概述

ABAP程序中有两种方式访问数据库:Open SQLNative SQL

1.1 Open SQL 是完全集成到 ABAP语言中的Standard SQL的子集。它通过数据库接口将 Open SQL 转换成 Standard SQL,

所以它可以用相同的方式访问不同的数据库系统,然后由该接口把SAP的Open SQL自动转换为相应数据库的特定SQL语句。

Open SQL 包含Standard SQL的数据操作语言Data Manipulation Language (DML)部分,允许你读取和修改数据。

Data Definition Language (DDL) 和 Data Control Language (DCL) 部分使用ABAP Dictionary处理。

 

1.2 Native SQL 语法不会使用数据库接口进行转换,它直接访问数据库,所以一个SQL只能访问一个指定数据库,

且具有一定的安全风险,对SAP执行效率也会有较大影响,所以一般不推荐使用。

abap_08_data_interface

 

2. Open SQL 语句

Open SQL包含的DML語法有4种:SELECT, INSERT, UPDATE, DELETE, MODIFY

SELECT:  查询语法

INSERT:  插入数据语法

UPDATE: 更新数据语法

DELETE:  删除数据语法

MODIFY: 修改数据语法,相当于 INSERT 和 UPDATE

修改数据前会先在数据库查询是否存在该记录,如果存在则修改,不存在则插入新的数据

abap_08_Open_SQL

Open SQL执行成功后,会返回代码 SY-SUBRC = 0, 如果失败 SY-SUBRC <> 0

SELECT 以外的命令,其他都会涉及到数据的修改,要谨慎使用。

在系统标准表中,我们只允许用 SELECT 命令去查询数据,其他命令语句只能用于自建表,

如若要修改系统标准表,只能通过系统标准程序去操作。

 

3. SELECT

SELECT 命令包含如下从句:

SELECT: 需要查询资料库指定表的那些列,是一行还是多行

INTO: 查询的结果保存在哪里

FROM:  从哪些表查询数

WHERE: 指定查询条件

GROUP BY: 以哪些栏位进行分組

ORDER BY: 以哪些栏位进行排序.

 

3.1 SELECT SINGLE 命令

SELECT SINGLE 命令允许你查询一条记录 ,为了确保你查询的记录是唯一的,你必须在你的 WHERE 子句指定所有KEY值,

如若查询的记录不止一条,系统会返回代码 SY-SUBRC = 8,查询结果为空;

SELECT SINGLE <F1> <F2>  FROM <dbtab>

INTO <work area>

INTO (<f1>, <f2>, <f3> …  )

INTO     CORRESPONDING      FIELDS     OF <work area>

WHERE  <Key1> <op>  AND <Key2> <op> …

 

在INTO中使用 CORRESPONDING FIELDS OF,系统只填充与你的Work Area相同名称的栏位值;

执行成功返回代码 SY-SUBRC = 0,如果失敗SY-SUBRC <> 0。

示例:

1
2
3
4
5
6
7
8
TABLES: spfli.
DATA
wa_spfli LIKEspfli.
 
SELECT  SINGLE
  Carrid connid airpfrom airpto
  FROM spfli
  INTOCORRESPONDINGFIELDSOFwa_spfli
  WHERE carrid ='UA'ANDconnid ='3504'.

 

3.2 SELECT 查询多条记录

SELECT 查询多条记录有两种方式:

1.使用SELECT … ENDSELECT命令,进行循环处理;

2.一次性读取多笔记录到内表中,在 INTO 使用TABLE附加字

 

第一种方式语法格式:

SELECT <F1> … <Fn>  FROM <dbtab>

INTO <work area>

INTO (<f1>, <f2>, <f3> …  )

INTO CORRESPONDING FIELDS OF <work area>

WHERE  <tabfield> <operator> <value>.

ENDSELECT.

 

第二种方式语法格式:

SELECT  <f1> … <fn>  FROM <dbtab>

INTO TABLE <itab>

WHERE …

 

示例:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
DATA tab_spfli TYPE STANDARD TABLE OF spfli.
DATA wa_spfli  LIKE spfli.
 
SELECT carrid connid airpfrom airpto
   FROMapfli
   INTOwa_spfli
   WHEREcarrid ='LH' 
     ANDconnid ='400'.
ENDSELECT.
 
SELECT carrid connid airpfrom airpto
   FROMapfli
   INTOCORRESPONDINGTABLEOFtab_spfli
   WHEREcarrid ='LH'
     ANDconnid ='400'.

 

注意:使用 SELECT… ENDSELECT 语法中不能加入 SINGLE、INTO CORRESPONDING FIELDS 、TABLE等关键字,

中间可以使用 CHECK 语法来判断查询值。

 

3.3 SELECT 附加选项

SINGLE [FOR UPDATE]: 使用它会产生一个排他锁,其他程序不能查询此笔记录。

 

示例:

1
2
3
4
5
6
* 星号表示查询所有栏位
SELECT SINGLE FOR UPDATE*
   FROMSCARR
   WHEREcurrcode ='USD'.
 
WRITE : /  scarr-CARRID.

DISTINCT:查询非重复记录,需要使用ORDER BY排序

 
 

3.4 SELECT标准函数

在使用 SELECT 语句时,可以直接使用Open SQL提供的标准函数进行相关操作,常用的标准函数有以下几种:

1.COUNT():  统计查询记录总数

2.SUM(): 汇总某查询数字字段数量

3.AVG():计算某查询数字字段平均值

4.MAX():查询表中记录最大值

5.MIN():查询表中记录最小值

使用这些函数时,如果要包含其他栏位,必须使用GROUP BY命令

 

3.5  FROM 子句

1. FROM dbtab [AS  alias]  -  AS 附加字,用于对 Table另起别名

2. JOIN 联合查询

JOIN的联合查询有两种, INNER JOINLEFT/RIGHT [OUTER] JOIN

通过ON 语句关联2个或2个以上的表,且必须至少指定一个连接条件;在多个连接条件时,可以使用AND;

ON左右的条件只能使用 = (EQ) 进行连接。

示例:

1
2
3
SELECT SINGLE B~BUKRS
   FROMBSEGASB
   INNERJOINT001ASTONB~BUKRS = T~BUKRS.

 

其中,INNER JOINLEFT/RIGHT JOIN 的区别:

INNER JOIN的 ON 条件下,两个表数据必须完全匹配;

LEFT JOIN 的 ON 条件下,左边的表需满足,右边的表不用完全匹配。

3. BYPASSING BUFFER  - 绕过 Application Buffer,直接读取数据库。

4. UP TO n ROWS  - 查询n 笔记录,限制读取数据的条数,即只读取查询数据的前5条记录。

 
 

3.6 WHERE 子句

WHERE 关键字后,可带子句包括:

1. <field> OP g

OP包括:=, EQ, <>, NE, <, LT, >, GT, <, LE, >=, GE, <=, LE等关系操作符

2. <field> [NOT] BETWEEN g1 AND g2 : 包含 g1 和 g2

 

示例:

01
02
03
04
05
06
07
08
09
10
11
* Between 的演示
SELECT carrid
  INTOTABLEitab
  FROMscarr
  WHEREcarrid BETWEEN'AA' AND'AZ'.
 
LOOP AT ITAB.
 
   WRITE: / ITAB-CARRID.
 
ENDLOOP.

 

3. <field> [NOT] LIKE g :通过通配符(‘_’, ’%’)模糊查询

 

示例:

1
2
3
4
5
6
7
8
SELECT  *
   FROMmara  
   WHEREmatnrLIKE‘101-%’.
*  WHERE matnr LIKE ‘101-___’.
 
WRITE : / mara-matnr.
 
ENDSELECT.

 

这里强烈建议,尽量避免使用LIKE语法作为条件筛选,因为模糊查询的数据量多数时候会非常庞大;

这样会直接消耗系统资源,影响系统性能。

 

4. <field> [NOT]  IN ( g1, …,  gn ) : 多个组合作为筛选条件

5. <field> [NOT] IN itab  : 使用Range table作为筛选条件

6. <field> IS [NOT] NULL :筛选某字段是否为空

 
 

3.7 FOR ALL ENTRIESIN 语句

由于内表可以临时存储多条数据,而Open SQL允许将内表数据作为查询条件,故可以通过 FOR ALL ENTRIESIN语句参照内表作为条件查询。

相当于使用 INNER JOIN 连接两个表一样,然后在数据量庞大的时候,FOR ALL ENTRIESIN 语句会比INNER JOIN的查询快捷。

两者各有优缺点,视具体情况而定。

 

示例:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
* INNER JOIN 用法:
SELECT DISTINCT knb1~bukrs t001~butxt
    FROMknb1INNERJOINt001
    ONknb1~bukrs = t001~bukrs
    INTOCORRESPONDINGFIELDSOFTABLEtb_bukrs
    WHEREkunnrINrn_kunnr.
 
 
 
* FOR ALL ENTRIES IN用法:
SELECT DISTINCT bukrs
   INTOCORRESPONDINGFIELDSOFTABLEgt_knb1
   FROMknb1.
   
IF gt_knb1[] IS NOT INITIAL.
   SELECTDISTINCTbutxtFROMt001
      INTOCORRESPONDINGFIELDSOFTABLEgt_too1
      FORALLENTRIESINgt_knb1
      WHEREbukrs = gt_knb1-bukrs.
END IF.

 

注意事项:

1.使用该语句,对于最后得到的结果集,系统会自动删除重复行。

因此如果你要保留重复行记录时,记得在 SELECT 语句中添加足够键值项目(有必要时,增加全部键值项目),

以保证结果集中所需重复项目不会被删除。

(例如选取支付金额时,支付事件可能不同,但金额可能相同,此时一定要注意,以避免错误删除结果记录。)

2.FOR ALL ENTRIES IN 后面使用的内部表 itab 如果为空,系统将当前 CLIENT 下所有记录选出。

因此为避免无意义的检索,在使用该语句前一定要判断内部表 itab 是否为空,为空时不执行包含该语句的数据库检索处理。

3.由于 itab-f 实际上是作为占位符被替换,所以内部表 itab 中不要包含 HEADER 行(项目标识名称行),以免造成混淆,检索出错。

4.内部表itab中作为条件替换用项目的类型和长度,一定要和检索数据库中对应的项目相同,否则编译不能通过。

5.对于内部表 itab中 作为条件替换用项目,不能使用 LIKE,BETWEEN,IN 比较操作符。

6.使用该语句时,ORDER BY 语句和 HAVING 语句将不能使用。

7.使用该语句时,除COUNT( * )以外的所有标准合计函数(MAX,MIN,AVG,SUM)都不能使用。

 
 

4. INSERT 语句

INSERT语法结构:

INSERT INTO <dbtab> VALUES  wa.

INSERT <dbtab> FROM TABLE itab.

示例1:

01
02
03
04
05
06
07
08
09
10
11
TABLES scustom.
scustom-mandt      ='002'.
scustom-id         ='12400177'.
scustom-name       ='Robinson'.
scustom-postcode   ='69542'.
scustom-city       ='Heidelberg'.
scustom-custtype   ='P'.
scustom-discount   ='003'.
scustom-telephone  ='01234/56789'.
 
INSERT INTO scustom CLIENTSPECIFIEDVALUESscustom.

 

CLIENT SPECIFIED: 是否指定 CLIENT

如果指定CLIENT,则只插入指定CLIENT的相关数据;

如果用在WHERE语句,则是抽取指定CLIENT的相关数据;如若没有指定CLIENT,则抽取所有CLIENT的数据。

 

示例2:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
TABLES SPFLI.
DATA ITAB LIKE SPFLIOCCURS10WITHHEADERLINE.
 
ITAB-CARRID = 'UA'. ITAB-CONNID = '0011'. ITAB-CITYFROM = ..
APPEND ITAB.
 
ITAB-CARRID = 'LH'. ITAB-CONNID = '1245'. ITAB-CITYFROM = ..
APPEND ITAB.
 
ITAB-CARRID = 'AA'. ITAB-CONNID = '4574'. ITAB-CITYFROM = ..
APPEND ITAB.
 
................
 
INSERT SPFLI FROM TABLEITAB ACCEPTINGDUPLICATEKEYS
IF SY-SUBRC = 0.
 
   .....
 
ELSEIF-SUBRC = 4.
 
   .....
 
ENDIF.

 

5.UPDATE语句

1. UPDATE <dbtab> SET f1 … fn  [WHERE sql_cond] .

2. UPDATE <dbtab> FROM TABLE itab [WHERE sql_cond] .

示例:

01
02
03
04
05
06
07
08
09
10
11
UPDATE scustom SET: DISCOUNT  ='003',
                    TELEPHONE ='0621/444444'
       WHEREID ='00017777'.
 
TABLES scustom.
DATA wa LIKE scustom.
 
wa-id         = '12400177'.
wa-telephone  = '06201/44889'.
 
UPDATE scustom FROM wa.

 

6. MODIFY语句

1.MODIFY  <dbtab>.   (相当于INSERT 和UPDATE)

2.MODIFY  <dbtab> FROM TABLE itab.

示例:

01
02
03
04
05
06
07
08
09
10
TABLES scustom.
scustom-id         ='12400177'.
scustom-name       ='Robinson'.
scustom-postcode   ='69542'.
scustom-city       ='Heidelberg'.
scustom-custtype   ='P'.
scustom-discount   ='003'.
scustom-telephone  ='06201/44889'.
 
MODIFY scustom.

 

7. DELETE语句

1. DELETE FROM <dbtab> WHERE cond.

2. DELETE <dbtab> FROM TABLE itab.

 

Delete 最好有条件限定,谨慎使用,避免误删数据

1
DELETE FROM SBOOK WHERECARRID ='LH' ANDCONNID ='0400' AND  FLDATE ='19950228'.

 
 

相关文章

  • 2014-03-26 FOR ALL ENTRIES 优化
  • 2014-01-17 ABAP 开发系列文章
  • 2014-03-03 ABAP 开发系列(04): ABAP数据类型与数据对象
  • 2014-03-06 ABAP 开发系列(07): 模块化 – 子程序
  • 2014-03-14 ABAP Range Table
  • 2014-03-05 ABAP 开发系列(06): ABAP 控制语句
  • 2014-03-04 ABAP 开发系列(05): ABAP 内表与内表结构
  • 2014-03-12 ABAP 开发系列(10): Function Module
  • 2014-01-26 ABAP 开发系列(02): ABAP Development Workbench 介绍(下)- ABAP 调试器
  • 2014-11-14 FIELD SYMBOL和TYPE REF TO的用法和比较

0 0
原创粉丝点击