zoukankan      html  css  js  c++  java
  • ABAP-SQL基础知识

     

    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中,双引号"不表示注释.

  • 相关阅读:
    Day3-spark基本认识
    团队冲刺第九天
    团队冲刺第八天
    团队冲刺第七天
    团队冲刺第六天
    团队冲刺第五天
    团队冲刺第四天
    团队冲刺第三天
    团队冲刺第二天
    团队冲刺第一天
  • 原文地址:https://www.cnblogs.com/jingli6174/p/5522548.html
Copyright © 2011-2022 走看看