1. 程式人生 > >SAP Open SQL

SAP Open SQL

– 表現層(Presentation),應用層(Application),資料層(Database)

就發生在 Application 和 Database 之間;

SAP Application將傳送的請求,與Database進行匹配,轉換成接受的SQL語句,

DB再執行SQL,將結果返回給Application。

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。

示例:

12345678TABLES: spfli.
DATA
  wa_spfli LIKE spfli.SELECT  SINGLECarrid connid airpfrom airptoFROM spfliINTO CORRESPONDINGFIELDS OF wa_spfliWHERE carrid ='UA'ANDconnid ='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 …

示例:

010203040506070809101112131415DATA tab_spfli TYPE STANDARD TABLE OF spfli.DATA wa_spfli  LIKE spfli.SELECT carrid connid airpfrom airptoFROM spfliINTO wa_spfliWHERE carrid ='LH' ANDconnid ='400'.ENDSELECT.SELECT carrid connid airpfrom airptoFROM spfliINTO CORRESPONDING TABLE OF tab_spfliWHEREcarrid ='LH'AND connid ='400'.

注意:使用 SELECT… ENDSELECT 語法中不能加入 SINGLE、INTO CORRESPONDING FIELDS 、TABLE等關鍵字,

中間可以使用 CHECK 語法來判斷查詢值。

3.3 SELECT 附加選項

SINGLE [FOR UPDATE]: 使用它會產生一個排他鎖,其他程式不能查詢此筆記錄。

示例:

123456* 星號表示查詢所有欄位SELECT SINGLE FOR UPDATE*FROM SCARRWHEREcurrcode ='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) 進行連線。

示例:

123SELECT SINGLE B~BUKRSFROM BSEGASBINNERJOIN T001 AS TONB~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

示例:

0102030405060708091011* Between 的演示SELECT carridINTOTABLE itabFROMscarrWHERE carrid BETWEEN'AA'  AND 'AZ'.LOOP AT ITAB.WRITE: / ITAB-CARRID.ENDLOOP.

3. <field> [NOT] LIKE g :通過萬用字元(‘_’, ’%’)模糊查詢

示例:

12345678SELECT  *FROM mara  WHEREmatnr 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 :篩選某欄位是否為空

由於內表可以臨時儲存多條資料,而Open SQL允許將內表資料作為查詢條件,故可以通過 語句參照內表作為條件查詢。

相當於使用 INNER JOIN 連線兩個表一樣,然後在資料量龐大的時候,會比INNER JOIN的查詢快捷。

兩者各有優缺點,視具體情況而定。

示例:

0102030405060708091011121314151617181920* INNER JOIN 用法:SELECT DISTINCT knb1~bukrs t001~butxtFROM knb1 INNER JOINt001ONknb1~bukrs = t001~bukrsINTOCORRESPONDING FIELDSOF TABLE tb_bukrsWHERE kunnr IN rn_kunnr.* FOR ALL ENTRIES IN用法:SELECT DISTINCT bukrsINTOCORRESPONDING FIELDSOF TABLE gt_knb1FROM knb1.IF gt_knb1[] IS NOT INITIAL.SELECTDISTINCT butxt FROM t001INTO CORRESPONDING FIELDSOF TABLE gt_too1FOR ALLENTRIES IN gt_knb1WHEREbukrs = gt_knb1-bukrs.END IF.

注意事項:

1.使用該語句,對於最後得到的結果集,系統會自動刪除重複行。

因此如果你要保留重複行記錄時,記得在 SELECT 語句中新增足夠鍵值專案(有必要時,增加全部鍵值專案),

以保證結果集中所需重複專案不會被刪除。

(例如選取支付金額時,支付事件可能不同,但金額可能相同,此時一定要注意,以避免錯誤刪除結果記錄。)

2. 後面使用的內部表 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:

0102030405060708091011TABLES 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 SPECIFIEDVALUES scustom.

CLIENT SPECIFIED: 是否指定 CLIENT

如果指定CLIENT,則只插入指定CLIENT的相關資料;

如果用在WHERE語句,則是抽取指定CLIENT的相關資料;如若沒有指定CLIENT,則抽取所有CLIENT的資料。

示例2:

010203040506070809101112131415161718192021222324TABLES SPFLI.DATA ITAB LIKE SPFLIOCCURS10 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 TABLEITAB ACCEPTINGDUPLICATEKEYSIF 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] .

示例:

0102030405060708091011UPDATE scustom SET: DISCOUNT  ='003',TELEPHONE ='0621/444444'WHEREID ='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.

示例:

01020304050607080910TABLES 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 最好有條件限定,謹慎使用,避免誤刪資料

1DELETE FROM SBOOK WHERECARRID ='LH' ANDCONNID ='0400' AND  FLDATE ='19950228'.