SAP Open SQL

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

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

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

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

 

1.Open SQL 概述

ABAP程序中有两种方式访问数据库Open SQL 和Native 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  LIKE  spfli.
 
SELECT   SINGLE
   Carrid connid airpfrom airpto
   FROM  spfli
   INTO  CORRESPONDING FIELDS  OF  wa_spfli
   WHERE  carrid = 'UA' AND connid = '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
    FROM  spfli
    INTO  wa_spfli
    WHERE  carrid = 'LH' 
      AND connid = '400' .
ENDSELECT .
 
SELECT  carrid connid airpfrom airpto
    FROM  spfli
    INTO  CORRESPONDING  TABLE  OF  tab_spfli
    WHERE carrid = 'LH'
      AND  connid = '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 *
    FROM  SCARR
    WHERE currcode = '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 JOIN 和 LEFT/RIGHT [OUTER] JOIN

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

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

示例:

1
2
3
SELECT  SINGLE  B~BUKRS
    FROM  BSEG AS B
    INNER JOIN  T001  AS  T ON B~BUKRS = T~BUKRS.

 

其中,INNER JOIN 与 LEFT/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
   INTO TABLE  itab
   FROM scarr
   WHERE  carrid  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   *
    FROM  mara  
    WHERE matnr  LIKE ‘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
     FROM  knb1  INNER  JOIN t001
     ON knb1~bukrs = t001~bukrs
     INTO CORRESPONDING  FIELDS OF  TABLE  tb_bukrs
     WHERE  kunnr  IN  rn_kunnr.
 
 
 
* FOR ALL ENTRIES IN用法:
SELECT  DISTINCT  bukrs
    INTO CORRESPONDING  FIELDS OF  TABLE  gt_knb1
    FROM  knb1.
   
IF  gt_knb1[] IS  NOT  INITIAL .
    SELECT DISTINCT  butxt  FROM  t001
       INTO  CORRESPONDING  FIELDS OF  TABLE  gt_too1
       FOR A LL ENTRIES  IN  gt_knb1
       WHERE bukrs = 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  CLIENT  SPECIFIED VALUES  scustom.

 

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  SPFLI OCCURS 10  WITH  HEADER  LINE .
 
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  TABLE ITAB ACCEPTING DUPLICATE KEYS
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'
        WHERE ID  = '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  WHERE CARRID = 'LH'  AND CONNID = '0400'  AND   FLDATE = '19950228' .
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值