ABAP 数据库相关

一、ABAP与SQL

        ABAP编程环境中,SQL被广泛应用,特别是在需要对数据库进行查询、插入、更新或删除操作时,ABAP SQL Functions允许开发者在对数据库进行查询时使用SQL语言内置的函数,从而实现更加复杂和高效的数据处理。在ABAP中使用SQL时对于结构体内表也有大量使用,可以先进行了解。下面就通过具体例子来演示ABAP中对SQL的使用。

        由于博主也是初学者,有些不完善的地方后续会进行补充,不正确的地方还请留言。

二、例子中涉及到的表结构

若不知道怎么创建表,可以参考博文数据库表、数据元素、域创建

1、学生表ZVIA_STU

2、学校表ZVIA_SCH

3、考勤表ZVIA_CHE

三、查询数据-SELECT

1、基础语句

若只有一条数据INTO结构体就行,但是若有多条数据则INTO TABLE 内表,条件之间以OR/AND进行连接。

SELECT 字段名1 (字段名2 字段名3...) 
    FROM 表名
    INTO (TABLE) 内表名/结构体
    WHERE 条件1 (OR/AND 条件2 OR/AND 条件三...).  

举例,在学生表中找到gender = 'F' 的学生。很简单的查询语句,不做过多解释。

DATA : lt_stu TYPE TABLE OF zvia_stu."用表来定义结构

SELECT * FROM zvia_stu INTO TABLE lt_stu WHERE gender = 'F'."查询

cl_demo_output=>display( lt_stu )."输出内表

这里的 cl_demo_output=>display( 表名 ).用来输出,括号之中的表名前后需要留有空格,可以去了解其用法。 结果输出显示:

2、连表查询

与其他SQL一样,ABAP中的SQL也有内连接、外连接(左连接、右连接),下面通过几个例子来进行介绍。基础语法和演示用的表数据如下。也可以用 表名 AS 别名 的方式简化书写,可以自行尝试。

1)如果SELECT语句里面出现的字段在多个表中存在,则需要用表名~字段名的写法来指定是哪张表里面的字段,后续的代码中有演示。
2)每JOIN一张表后面都需要有ON条件,ON条件里面的字段也需要用表名1~字段名1=表名2~字段名2的写法来表示。
SELECT 字段名1 (字段名2 字段名3...) 
  FROM 表名1 JOIN 表名2 ON 连接字段条件
       表名x JOIN 表名y ON 连接字段条件
       ........
  INTO (TABLE) 内表名/结构体
  WHERE 条件1 (OR/AND 条件2 OR/AND 条件三...).  

 标红的数据在另一张表中没有匹配的数据。

a、内连接INNER JOIN

内连接只有当两个或多个表中的某一列或某些列的值相等时,相应的行才会出现在结果集中。不满足的不会出现在结果中。

在ABAP中,当使用Open SQL语句时,如果要在SQL语句中引用程序声明(非数据库层级)的变量,比如本地变量、工作区变量或内表等,这些变量名前需要加上@符号作为转义符。

*定义一个类型*
TYPES : BEGIN OF ty_stu,
          stuid   TYPE zde_via_stuid, "用数据元素来定义类型
          stuname TYPE zde_via_stuname,
          schid   TYPE zde_via_schid,
          schname TYPE zde_via_schname,
          gender  TYPE zde_via_gender,
        END OF ty_stu.

DATA : lt_stu TYPE TABLE OF ty_stu."定义用来存储数据的内表

SELECT stuid,stuname,zvia_stu~schid,schname,gender
  FROM zvia_stu INNER JOIN zvia_sch"内连接
  ON  zvia_stu~schid = zvia_sch~schid"JOIN的条件
  INTO TABLE @lt_stu.

cl_demo_output=>display( lt_stu )."输出显示

这段代码运行结果如下,可以看到SCHID为0003的大学没有显示,SCHID为0000的两个学生也没有出现在查询结果中。因为它们的匹配条件SCHID相等在对方表中没有匹配的项所以不会出现在结果中。

b、左连接LEFT (OUTER) JOIN

左连接会返回左表中的所有记录,以及右表中满足连接条件的记录。如果右表中没有满足连接条件的记录,则结果集中的这些记录对应的右表字段将包含NULL值。

同样的两个表,只修改连接方式为左连接,查看结果。

SELECT stuid,stuname,zvia_stu~schid,schname,gender
  FROM zvia_stu LEFT JOIN zvia_sch"左连接
  ON  zvia_stu~schid = zvia_sch~schid
  INTO TABLE @lt_stu.

运行结果如下,可以看到左连接时候,左表虽然SCHID在右表中没有对应数据,但是会显示出来NULL,保留在查询结果里。

c、右连接RIGHT (OUTER) JOIN (不常用,这种情况下一般主表会放在左边用左连接)

右连接会返回右表中的所有记录,以及左表中满足连接条件的记录。如果左表中没有满足连接条件的记录,则结果集中的这些记录对应的左表字段将包含NULL值。

同样的两个表,只修改连接方式为右连接,查看结果。

*这里为了查看结果,搜索的SCHID改成了学校表中的*
SELECT stuid,stuname,zvia_sch~schid,schname,gender
  FROM zvia_stu RIGHT JOIN zvia_sch"右连接
  ON  zvia_stu~schid = zvia_sch~schid
  INTO TABLE @lt_stu.

运行结果如下,可以看到右连接时候,虽然左表里面没有学生的SCHID为0003,但是还是会在查询结果里面将右表里面的0003进行保留

d、总结
1)内连接:根据条件进行匹配,两张表中都有的才加入查询结果。
2)左连接:根据条件进行匹配,如果有左表里面存在但在右表里没有匹配的数据也会进行保留。
3)右连接:根据条件进行匹配,如果有右表里面存在但在左表里没有匹配的数据也会进行保留。

四、插入数据-INSERT

1、插入一条数据

a、直接插入

INSERT INTO 表名 VALUES @( VALUE #( 字段名1 = 值1 字段名2 = 值2 字段名3 = 值3 字段名4 = 值4) ).

例子:

INSERT INTO zvia_stu VALUES @( VALUE #( stuid = 17 stuname = 'KJ' schid =  1  gender = 'M') ).
*判断插入数据结果*
IF sy-subrc <> 0.
  WRITE: / '插入失败.'.
ELSE.
  WRITE: / '插入成功.'.
ENDIF.

运行结果 :

b、通过结构体进行插入 

INSERT 表名 FROM 结构体.

*定义结构体类型*
TYPES : BEGIN OF ty_stu,
          mandt   TYPE mandt,"结构体类型定义时需要加上
          stuid   TYPE zde_via_stuid, "用数据元素来定义类型 
          stuname TYPE zde_via_stuname,
          schid   TYPE zde_via_schid,
          gender  TYPE zde_via_gender,
        END OF ty_stu.

DATA : ls_stu TYPE ty_stu.

*给结构体字段赋值*
ls_stu-stuid = 18.
ls_stu-stuname = 'LINDA'.
ls_stu-schid = 2.
ls_stu-gender = 'F'.

*插入数据*
INSERT zvia_stu FROM ls_stu.
*插入结果判断*
IF sy-subrc <> 0.
  WRITE: / '插入失败.'.
ELSE.
  WRITE: / '插入成功.'.
ENDIF.

2、插入多条数据

插入多条数据的时候可以通过内表进行。

INSERT 表名 FROM TABLE 内表名.

TYPES : BEGIN OF ty_stu,
          mandt   TYPE mandt, "结构体类型定义时需要加上
          stuid   TYPE zde_via_stuid, "用数据元素来定义类型
          stuname TYPE zde_via_stuname,
          schid   TYPE zde_via_schid,
          gender  TYPE zde_via_gender,
        END OF ty_stu.

DATA : ls_stu TYPE ty_stu,
       lt_stu TYPE TABLE OF ty_stu.

ls_stu-stuid = 19.
ls_stu-stuname = 'MIAO'.
ls_stu-schid = 4.
ls_stu-gender = 'F'.
APPEND ls_stu to lt_stu."数据添加至内表

ls_stu-stuid = 20.
ls_stu-stuname = 'WANG'.
ls_stu-schid = 2.
ls_stu-gender = 'M'.
APPEND ls_stu to lt_stu."数据添加至内表

*通过内表插入多条数据*
INSERT zvia_stu FROM TABLE lt_stu.
*插入结果判断*
IF sy-subrc <> 0.
  WRITE: / '插入失败.'.
ELSE.
  WRITE: / '插入成功.'.
ENDIF.

五、更新数据-UPDATE/MODIFY

1、总的过程

a、UPDATE:

判断是否存在数据->修改结构体中的数据->依据结构体来UPDATE表

UPDATE 表名 SET 字段名1=值1 字段名2=值2 .... (WHERE 条件).

b、MODIFY:不用进行判断,反正有则改没有则加。

2、更新的是主键的时候。在UPDATE的WHERE条件里面需要加上主键字段名 = 之前主键值的条件判断,否则会找不到数据,因为UPDATE是依据主键来查找数据修改的。

TYPES : BEGIN OF ty_stu,
          mandt   TYPE mandt, "结构体类型定义时需要加上
          stuid   TYPE zde_via_stuid, "用数据元素来定义类型
          stuname TYPE zde_via_stuname,
          schid   TYPE zde_via_schid,
          gender  TYPE zde_via_gender,
        END OF ty_stu.

*修改主键*
DATA : ls_stu TYPE ty_stu.
SELECT SINGLE *
  FROM zvia_stu
  INTO  ls_stu
  WHERE stuid = '0001'.
WRITE : / '修改前数据:',ls_stu.
IF sy-subrc <> 0."判断是否存在该数据
  WRITE : / '不存在该数据'.
ELSE.
  UPDATE zvia_stu
    SET stuid = '0099'
********主键条件判断********
    WHERE stuid = '0001'.
***************************
  IF sy-subrc = 0."判断UPDATE的结果
    WRITE : / '更新成功'.
  else.
    WRITE : / '更新失败'.
  ENDIF.
  SELECT SINGLE * from zvia_stu INTO ls_stu WHERE stuid = '0099'.
  WRITE : / '修改后数据:',ls_stu.
ENDIF.

3、更新的数据非主键。如果更新的数据不是主键,不一定需要加上主键 = 之前主键值的条件。但是请一定注意条件判断,否则将会修改很多数据!

下面的代码将姓名为JASMINE的学生姓名改成了LEO。

TYPES : BEGIN OF ty_stu,
          stuid   TYPE zde_via_stuid, "用数据元素来定义类型
          stuname TYPE zde_via_stuname,
          schid   TYPE zde_via_schid,
          gender  TYPE zde_via_gender,
        END OF ty_stu.

*修改的是非主键的时候*
DATA : ls_stu TYPE ty_stu.
SELECT SINGLE *
  FROM zvia_stu
  INTO  ls_stu
  WHERE stuname = 'JASMINE'.
WRITE : / '修改前数据:',ls_stu.
IF sy-subrc <> 0.
  WRITE : / '不存在该数据'.
ELSE.
  UPDATE zvia_stu
    SET stuname = 'LEO'
    WHERE stuname = 'JASMINE'.
  IF sy-subrc = 0.
    WRITE : / '更新成功'.
  else.
    WRITE : / '更新失败'.
  ENDIF.
  SELECT SINGLE * from zvia_stu INTO ls_stu WHERE stuname = 'LEO'.
  WRITE : / '修改后数据:',ls_stu.
ENDIF.

 运行结果:

4、MODIFY。与内表中的MODIFY一样,数据库语句里面的MODIFY也有有则改,没有则加的特性。

MODIFY 表名 FROM 结构体.

六、删除数据 

1、通过结构体进行删除。结构体定义里面必须包含有主键,才能够找到对应数据。

DELETE 表名 FROM 结构体名.

ls_stu-stuid = '0001'."主键
ls_stu-stuname = 'BETTY'.
ls_stu-schid = '0001'.
ls_stu-gender = 'F'.
*若使用结构体:ls_stu所定义的字段包含有主键,则可以删除,不然不可以删除,不知道删哪一个*
DELETE zvia_stu FROM ls_stu.
IF sy-subrc = 0 .
  WRITE : / '删除成功'.
ELSE.
  WRITE : / '删除失败'.
ENDIF.

2、通过WHERE条件删除,会删除所有符合条件的行。所以删除一条数据的时候最好选择主键作为条件进行删除。

DELETE FROM 表名 WHERE 条件1 AND/OR 条件2 ...

DELETE FROM zvia_stu WHERE schid = '0003'."主键
IF sy-subrc = 0 .
  WRITE : / '删除成功'.
ELSE.
  WRITE : / '删除失败'.
ENDIF.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值