SAP Open SQL详解编程语言

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

– 表现层(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执行效率也会有较大影响,所以一般不推荐使用。

SAP Open SQL详解编程语言

2. Open SQL 语句

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

SELECT:  查询语法

INSERT:  插入数据语法

UPDATE: 更新数据语法

DELETE:  删除数据语法

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

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

SAP 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'
.

原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/20111.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论