您的位置:首页 > 数据库

ABAP-SQL基础知识

2016-08-05 14:41 344 查看
SQL语法

   我们在编写ABAP4程序的时候,经常需要从TABLE中根据某些条件读取数据,读取数据最常用的方法就是通过SQL语法实现的。ABAP/4中可以利用SQL语法创建或读取TABLE,SQL语法分为DDL(DATA DEFINE LANGUAGE)语言和DML(DATA MULTIPULATION LANGUAGE)语言,DDL语言是指数据定义语言,例如CREATE等, DML语言是数据操作语言,例如SELECT, INSERT等语句。SQL语句有OPEN SQL语句和NATIVE SQL语句。 OPEN SQL语句不是标准SQL语句,是ABAP/4语言,利用OPEN
SQL语句能在Databases 和 Command 之间产生一个BUFFER,所以它有一个语言转换的过程。而NATIVE SQL语句则是标准的SQL语句, 它直接针对Databases操作。

OPEN SQL

SELECT语句

语法格式:

SELECT <result> [INTO <target>] [FROM <source>] [WHERE <condition>]

               [GROUP BY <fields>] [ORDER BY <sort order>]

其中: <result>指定要抓取的栏位

      <target>将读取的记录存放在work area中

      <source>指定从那个TABLE中读取资料

      <condition>抓取资料的条件

      <fields>指定按那些栏位分组

      <sort order>排序的栏位及方式

相关的系统变量:

     SY-SUBRC = 0 表示读取数据成功

              <> 0 表示未找到符合条件的记录

     SY-DBLNT: 被处理过的记录的笔数.

相关的命令:

     EXIT. 退出循环.

     CHECK <logistic statement>.如果逻辑表达式成立,则继续执行,否则,开始下一次循环。

   

利用循环方式读取所有记录

SELECT ….ENDSELECT.是循环方式读取记录的。

     例如:

TABLES MARD. ''声明要使用的工作区

SELECT [DISTINCT] * FROM MARD WHERE MATNR = '3520421700'.

    <Statements>.

ENDSELECT.

(从MARD中抓取所有料号=3520421700的资料)

◆读取一笔资料

      Example:

               TABLES SPFLI.

               SELECT SINGLE * FROM SPFLI    

                     WHERE PLANT ='CHUNGLI' AND TEL='4526174'.

               WRITE: / SPFLI-COMPANY,SPFLI-PLANT,SPFLI-TEL.

◆将读取的记录放在work area中,并且加入Internal table 中.

格式有:

   ... INTO <work area>

   ... INTO CORRESPONDING FIELDS OF <work area> ''匹配赋值

   ... INTO (f1, ..., fn) 变量组.

   ... INTO TABLE <internal table>

   ... INTO CORRESPONDING FIELDS OF TABLE <internal table>

   ... APPENDING TABLE <internal table>

   ... APPENDING CORRESPONDING FIELDS OF TABLE <internal table>

举例一:

TABLES MARD. 

DATA: BEGIN OF ITAB OCCURS 10,

              MATNR LIKE MARD-MATNR,

              WERKS LIKE MARD-WERKS,

              LGORT LIKE MARD-LGORT,

              LABST LIKE MARD-LABST,

        END OF ITAB.

SELECT MATNR WERKS LGORT LABST 

              INTO CORRESPONDING FIELDS OF ITAB 

              FROM MARD

              WHERE MATNR = '3520421700'.

       APPEND ITAB.

       CLEAR ITAB.

ENDSELECT.

(将读取的结果放在Internal table ITAB中)

DATA: BEGIN OF WA, 

        LINE(240),

      END OF WA.

DATA NAME(10).

NAME = 'SPFLI'.

SELECT * FROM (NAME) INTO WA.

WRITE: / WA-LINE. 

ENDSELECT.

数据库表名称 SPFLI 被赋给字符字段 NAME。SELECT 语句将所有的行从 SPFLI 中读到目标区 WA 中。在该示例中,WA 与 SPFLI 的结构并不相同,每一行都将自动地转换成字符字段.

举例二.

TABLES MARD.

SELECT MATNR MTART MAKTX INTO (t_matnr, t_mtart, maktx) 

               FROM MARD

               WHERE MATNR = '3520421700'.

       <Statements>.

ENDSELECT.

(从MARD中抓取料号=3520421700的料号、类型和描述,放在变量t_matnr, t_mtart, maktx中)。

        Example:

                 TABLES SPFLI.

                 DATA WA LIKE TABLES.

                 SELECT * FROM SPFLI INTO WA.

                    WRITE: / WA-COMPANY,WA-PLANT.

                 ENDSELECT.

                 逐笔写入WA 工作区中

举例三.

将读取的资料写入 Initial Table 中

语法:

        SELECT .. INTO TABLE <itab>   

        Example:

        TABLES SPFLI.

        DATA ITAB LIKE SPFLI OCCURS 10 WITH HEADER LINE.

        SELECT * FROM SPFLI INTO ITAB.

        一次读10笔(Initial Table的长度)记录存入 ITAB 中

        

        SELECT .. INTO TABLE <itab> PACKAGE SIZE <n>

        一次读取 <n> 笔记录至 <itab>中

        Example:

           TABLES SPFLI.

           DATA ITAB LIKE SPFLI OCCURS 10 WITH HEADER LINE.

           SELECT * FROM SPFLI INTO ITAB PACKAGE SIZE 5. 

           一次读取 5 笔记录

exp :

TABLES SPFLI.

DATA: BEGIN OF WA,

         NUMBER TYPE I VALUE 1,

         CITYFROM LIKE SPFLI-CITYFROM,

         CITYTO   LIKE SPFLI-CITYTO,

      END OF WA.

SELECT * FROM SPFLI INTO CORRESPONDING FIELDS OF WA.

   WRITE: / WA-NUMBER, WA-CITYFROM, WA-CITYTO.

ENDSELECT.

输出如下所 示:

在该示例中,系统只将数据库表 SPFLI 中选定行的列 CITYFROM 和 CITYTO 传送到 WA 中。WA 中的组件 NUMBER 保持不变。

*-------------------------------------------------------------------------------------*

按指定的栏位排序

TABLES SBOOK.

SELECT * FROM SBOOK   WHERE CARRID = 'LH' AND

                            CONNID = '0400' AND

                            FLDATE = '19950228'

                            ORDER BY BOOKID ASCENDING.

   WRITE: / SBOOK-BOOKID,   SBOOK-CUSTOMID,

           SBOOK-CUSTTYPE, SBOOK-SMOKER,

           SBOOK-LUGGWEIGHT, SBOOK-WUNIT,

           SBOOK-INVOICE.

ENDSELECT.

(利用参数ORDER BY所指定的栏位排序)

*-------------------------------------------------------------------------------------*

◆ 抓取数据的条件关键字

(1) BETWEEN <g1> AND <g2>

例如: WHERE YEAR BETWEEN 1995 AND 2000.

(2) LIKE <g>

例如: WHERE NAME LIKE 'MIKE%'.

('%'是通配符号)

(3) IN (<g1>…<gn>)

是<g1>…<gn>里面的任意一个值即可.

例如: WHERE PLANT IN ('CHUNGLI', 'TAOYUAN','LIUTU').

(表示PLANT 只要是'CHUNGLI'或'TAOYUAN'或'LIUTU'都可以).

(4) ORDER BY 关键字

     指定排序的栏位或顺序

     (1). ..ORDER BY PRIMARY KEY.

        根据 PRIMARY KEY 递增排序

     (2)…ORDER BY <f1> [DESCENDING] <f2> [DESCENDING]

        Example:

                  SELECT * FROM IM ORDER BY PART .

*-------------------------------------------------------------------------------------*

INSERT 语句

◆从work area 加入到Internal Table中

格式: INSERT INTO <database> VALUES <work area>

例如: 

DATA: BEGIN OF WA,

              CODE(6) TYPE C,

              NAME(30) TYPE C,

        END OF WA.

DATA: VEN LIKE WA OCCURS 10.



WA-CODE = '530120'.

WA-NAME = 'XINGDA ELECTRONICS CO.,LTD'.

INSERT INTO VEN VALUES WA .

如果work area的名称就是internal table的名称,可以直接写成:

      INSERT <internal table>

例如:

DATA: BEGIN OF WA OCCURS 10,

              CODE(6) TYPE C,

              NAME(30) TYPE C,

        END OF WA.



WA-CODE = '530120'.

WA-NAME = 'XINGDA ELECTRONICS CO., LTD'.

INSERT WA.

◆从另外一个Internal table中INSERT 资料

格式:

INSERT <itab1> FROM TABLE <itab2> [ACCEPTING DUPLICATE KEY]

将<itab2>中非NULL的资料加入<itab1>中,加上[ACCEPTING DUPLICATE KEY]能限制相同PRIMARY KEY不重复加入.

   加入一笔记录至资料库

   1.自 Work Area 工作区

   语法:

        INSERT INTO <database> VALUES <wa>

        Example:

                 TABLES SPFLI.

                 DATA WA   LIKE SPFLI.

                 WA-NO = '34051920'.

                 WA-COMPANY='DELTA'.

                 INSERT SPFLI VALUES WA.

                 将 ITAB 资料加入 SPFLI中, 也可写成 INSERT SPFLI FROM ITAB.

           

                  SPFLI-NO='34299876'.

                  SPFLI-COMPANY='HP'.

                  INSERT SPFLI FROM SPFLI.

                  将Work Area SPFLI中的资料加入资料库档案 SPFLI中

                  因Work Area SPFLI的结构与资料档 SPFLI一样, 所以也可

                  写成 INSERT SPFLI.

   2.自 Internal Table

     语法:

           INSERT <database> FROM TABLE <itab> [ACCEPTING DUPLICATE KEY]

           将 <itab>中非 NULL的资料加入 <database>中, 加上 [ACCEPTING DUPLICATE

           KEY]能检查不加入有重覆primary key, 若有重覆则 SY-SUBRC 会传回 4

           Example:

                    TABLES SPFLI.

                    DATA ITAB LIKE SPFLI OCCURS 10 WITH HEADER LINE.

                    ITAB-NO = '34051920'.

                    ITAB-COMPANY = 'DELTA'.

                    APPEND ITAB.

                    ….

                    INSERT SPFLI FROM TABLE ITAB 

                             ACCEPTING DUPLICATE KEY.

*-------------------------------------------------------------------------------------*

UPDATE 指令

   异动已存在的记录内容

1.使用 Primary Key

语法: 

            UPDATE <database> FROM <wa>

            Example:

                     TABLES SPFLI.

                     DATA WA LIKE SPFLI.

                     WA-NO='34051920'.

                     WA-COMPANY='DELTA'.

                    UPDATE SPFLI FROM WA.

                    如 SPFLI 的 Primary Key是 NO, 则会找到 NO='34051920'的记录, 将其 COMPANY栏位异动为 DELTA

2.使用条件式

语法:

        UPDATE <database> SET < f1>=<values>… WHERE <condition>

        根据条件式异动符合条件式的记录

        Example:

                 UPDATE SPFLI SET NO ='34051920'

                                     COMPANY = 'DELTA'

                         WHERE TEL = '4526107'.

*-------------------------------------------------------------------------------------*

3.   MODIFY 语法

     MODIFY <internal table> [FROM <work area>].

根据 Primary Key 寻找资料档中符合的记录, 若找到则更新异动, 若找不到则新增记录

语法:

       MODIFY <database> FROM <wa>

       Example:

                WA-NO='34051920'.

                WA-COMPANY='DELTA'.

                MODIFY SPFLI FROM WA.

     

4.   DELETE 语法

     DELETE <internal table> [FROM <work area>].

或: DELETE <internal table> [WHERE <conditions>]

   删除资料档的记录

1.使用 Primary Key

语法: 

            DELETE <database> FROM <wa>

            Example:

                     TABLES SPFLI.

                     DATA WA LIKE SPFLI.

                     WA-NO='34051920'.

                     WA-COMPANY='DELTA'.

                     DELETE SPFLI FROM WA.

                     如 SPFLI 的 Primary Key是 NO, 则会找到 NO='34051920'的记录, 找到后将此笔删除

2.使用条件式

语法:

        DELETE FROM <database> WHERE <condition>

        根据条件式删除符合条件式的记录

        Example:

                 DELETE FROM SPFLI WHERE AREA = 'AMERICAN'.

                                        

*-------------------------------------------------------------------------------------*

5. DATABASE CURSOR

   Database Cursor是一个资料库暂存区, 将经SELECT指令读取的记录存放至此暂存区, 再由此暂存区放至Work Area中, 可减少资料库读取的次数.

1.开启 Database Cursor

语法:

        OPEN CURSOR <c> FOR SELECT … WHERE <condition>

        Example:

                TABLES SPFLI.

                DATA: WA LIKE SPFLI,

                        C1 TYPE CURSOR.

                OPEN CURSOR C1 FOR SELECT * FROM SPFLI 

                       WHERE AREA ='TAIWAN'.

2.读取 Database Cursor的资料存入 Work Area

语法:

      FETCH NEXT CURSOR <c> INTO <wa>

          Example:

                   FETCH NEXT CURSOR C1 INTO WA.

读取下一笔Cursor位置的资料存入WA, 如果已无资料可读, SY-SUBRC <>0. 

关闭 Database Cursor

语法:

      CLOSE CURSOR <c>

      Example:

               CLOSE CURSOR C1.

*-------------------------------------------------------------------------------------*

COMMIT WORK & ROLLBACK WORK

要确定资料成功写入资料库,可使用COMMIT WORK指令,如: 

   COMMIT WORK.

相反的,如果反悔要复原,可使用 ROLLBACK WORK, 可复原在上个COMMIT WORK指令之后的资料, 如:

   ROLLBACK WORK.

*-------------------------------------------------------------------------------------*

使用NATIVE SQL指令

语法格式:

EXEC SQL [PERFORMING <form>].

     <statements>

ENDEXEC.

举例一.

EXEC SQL.

CREATE TABLE AVERI_CLNT (

         CLIENT   CHAR(3) NOT NULL,

         ARG1     CHAR(3) NOT NULL,

         ARG2     CHAR(3) NOT NULL,

         FUNCTION CHAR(10) NOT NULL,

         PRIMARY KEY (CLIENT, ARG1, ARG2)

                          )

ENDEXEC.

举例二.

DATA: F1(3), F2(3), F3(3).

F3 = ' 1 '

EXEC SQL.

SELECT CLIENT, ARG1 INTO :F1, :F2 FROM AVERI_CLNT

         WHERE ARG2 = :F3

ENDEXEC

PERFORMING <form name>的使用:

如果NATIVE SQL的SELECT命令执行结果是抓到多笔记录,我们想要逐笔记录处理时,就用PERFORMING 参数,这个FORM能被逐次调用。如果想中止调用,就用EXIT FORM SQL结束调用。

例如:

DATA: F1(3), F2(3), F3(3).

F3 = '010'

EXEC SQL PERFORMING WRITE_AVERI_CLNT.

SELECT CLIENT, ARG1 INTO :F1, :F2 FROM AVERI_CLNT

         WHERE ARG2 = :F3

ENDEXEC.

FORM WRITE_AVERI_CLNT.

WRITE: / F1, F2.

ENDFORM.

                 DATA: BEGIN OF WA,

                        NAME(8),

                        AGE TYPE I,

                        END   OF WA.

                 DATA F1 TYPE I.

                 FI = 20.

                 EXEC SQL PERFORMING OUTPUT.

                    SELECT NAME,AGE INTO :WA FROM NAME_TABLE 

                             WHERE AGE >= :F1.

                 ENDEXEC..

                 FORM OUTPUT.

                   WRITE: / WA-NAME,WA-AGE.

                 ENDFORM.

注意:

a. NATIVE SQL把TABLE中的MANDT(client)栏位当作一般栏位使用,所以在抓取资料时必须指定特定的Client;

b. NATIVE SQL中的SELECT语句没有CHECK权限的功能;

c. 在登入SAP R/3系统时,我们已经自动与Database连接,所以在执行NATIVE SQL时并不需要CONNECT语句;

d. 一条NATIVE SQL语句可以以分号;结束,一般情况下是以句号.结束.

e. 某些数据库系统对TABLE名字和FIELD名字有大小写区别,要正确书写.

f. 在NATIVE SQL中,双引号"不表示注释.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: