国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

Open SQL詳解

2019-11-08 20:33:47
字體:
供稿:網(wǎng)友

image185

只有標準SQL的DML有對應(yīng)的Open SQL,只有SELECT、INSERT, UPDATE, DELETE有對應(yīng)的Open SQL。

 

Native SQL不會用到緩存,會直接發(fā)送給數(shù)據(jù)庫,而不會經(jīng)過ABAP數(shù)據(jù)訪問層。除開DML,它一般用于DDL、DCL,主要用來維護數(shù)據(jù)庫表

 

ABAP中的Database Interface層負責(zé)將Open SQL轉(zhuǎn)換成相應(yīng)的數(shù)據(jù)庫所支持的Standard SQL

Open SQL

ABAP Dictionary屬于ABAP Workbench的一部分,可以用它來創(chuàng)建與管理數(shù)據(jù)庫表

Open SQL只能訪問那些通過ABAP Dictionary創(chuàng)建的表(通過ABAP Dictionary創(chuàng)建的表才會顯示在Dictionary里),而不能操作那些直接通過數(shù)據(jù)庫工具創(chuàng)建的表。ABAP Dictionary通過標準的DDL SQL創(chuàng)建與維護數(shù)據(jù)庫表。

 

Open SQL contains the following keyWords:

Keyword

Function

SELECT

讀取

INSERT

插入

UPDATE

修改

MODIFY

插入或修改

DELETE

刪除

OPENCURSOR,FETCH,CLOSE CURSOR

游標

COMMIT WORK, ROLLBACK WORK

 

 

 

SY-SUBRC:所有Open SQL在執(zhí)行成功時返回0,否則返回非0

SY-DBCNT:在執(zhí)行Open SQL語句后,返回受影響的數(shù)據(jù)條數(shù)

 

 

讀取數(shù)據(jù)SELECT

SELECT {SINGLE [FOR UPDATE]}|{[DISTINCT]{}} 

* | { {col1|{ MAX( [DISTINCT] col )| MIN( [DISTINCT] col ) | AVG( [DISTINCT] col ) | SUM( [DISTINCT] col ) | COUNT( DISTINCT col ) | COUNT( * ) } } [AS a1]... } | (column_syntax)

FROM { {dbtab [AS tabalias]}

| [(] { {dbtab_left [AS tabalias_left]} | join_exPRession_即兩個或兩個以上的表前部分JOIN表達式}          {[INNER] JOIN}|{LEFT [OUTER] JOIN}            {dbtab_right [AS tabalias_right] ON join_cond} [)]

|{(dbtab_syntax) [AS tabalias]} } [CLIENT SPECIFIED] [UP TO n ROWS] [BYPASSING BUFFER]

{ INTO {{[CORRESPONDING FIELDS OF] wa}|(dobj1, dobj2, ...)} } 

| { INTO|APPENDING [CORRESPONDING FIELDS OF] TABLE itab [PACKAGE SIZE n] }

[[FOR ALL ENTRIES IN itab]WHERE [... col {=|EQ|<>|NE|>|GT|<|LT|>=|GE|<=|LE}itab-comp... ]

{ { col1 {=|EQ|<>|NE|>|GT|<|LT|>=|GE|<=|LE}

{ {dobj}|{col2}|{[ALL|ANY|SOME] (select … from …)} } }| {col [NOT] BETWEENdobj1 AND dobj2} | {col [NOT] LIKEdobj [ESCAPE esc]} | {col [NOT] IN(dobj1,dobj2 ...)} | {col [NOT] INseltab} | {col IS [NOT] NULL} | {(cond_syntax)} | {[NOT] EXISTS (select … from …)} | {col [NOT] IN (select … from …)} }]

[GROUP BY { {col1 col2...} | (column_syntax) }][HAVING sql_cond][ORDER BY { {PRIMARY KEY}| { col1 [ASCENDING|DESCENDING]col2 [ASCENDING|DESCENDING]...} | (column_syntax) }].... [ENDSELECT].

sy-subrc

Meaning

0

查詢到數(shù)據(jù)

4

沒有查詢到數(shù)據(jù)。聚合函數(shù)規(guī)則特殊,請參見

8

如果有WHERE從句后沒有完全指定主鍵字段條件,F(xiàn)OR UPDATE時

sy-dbcnt 為查詢到的記錄條數(shù)

如果從數(shù)據(jù)庫讀出來的數(shù)據(jù)存在重復(fù)時,是不能存儲到Unique內(nèi)表中去的——如Unique的排序表與哈希表

讀取單行

SELECT SINGLE [FOR UPDATE] <cols>... INTO [CORRESPONDING FIELDS OF] waWHERE ...SELECT SINGLE [FOR UPDATE] <cols>... INTO (dobj1,dobj2, ...) WHERE ...

 

SINGLE 選項不能用在子查詢中

如果有多條,則返回第一條數(shù)據(jù)

不能使用APPENDING,并且INTO后面不能接內(nèi)表

為了確保只讀到一條數(shù)據(jù),必須在WHERE語句后面指定所有的primary key,否則語法檢查時會警告

FOR UPDATE只能與SINGLE一起使用,即只能對一條數(shù)據(jù)進行加exclusive lock鎖。如果產(chǎn)生死鎖,會拋異常

FOR UPDATE會繞過數(shù)據(jù)庫緩存

 

DATA wa TYPE spfli. SELECT SINGLE *       FROM spfli        INTO CORRESPONDING FIELDS OF wa       WHERE carrid = 'LH' AND connid = '0400'.

 

 

注:一般使用SINGLE是表示根據(jù)表的關(guān)鍵字來查詢,這樣才能確保只有一條數(shù)據(jù),所以當(dāng)使用SINGLE時,不能再使用ORDER BY語句(因為沒有必要了),如果查詢時不能根據(jù)關(guān)鍵字來查詢,但要求在查詢時先排序再取第一條時,我們只能使用另一種語法(其實更好的方式是請參考UP TO n ROWS):

SELECT ... UP TO 1 ROWS ... ORDER BY

...

ENDSELECT.

DISTINCT

If DISTINCT is used, the SELECT statement bypasses SAP buffering

讀取多行

兩種選擇:選擇至內(nèi)表與循環(huán)選擇

 

選擇至內(nèi)表:

SELECT [DISTINCT] <cols> ... WHERE ...

 

循環(huán)選擇的語法:

SELECT [DISTINCT]<cols> ...INTO CORRESPONDING FIELDS OF <wa>WHERE ...

...

ENDSELECT.

循環(huán)發(fā)送SQL語句,每次讀取的結(jié)果INTO到一個結(jié)構(gòu)對象里,而不是內(nèi)表里。.

 

如果至少讀取到一條數(shù)據(jù),在讀取后(以及循環(huán)讀取后)SY-SUBRC為0,否則設(shè)置為4。讀取到的行會存儲在SY-DBCNT里,如果在SELECT…ENDSELECT循環(huán)里,每執(zhí)行一次 SELECT 語句,SY-DBCNT 都加 1

 

從技術(shù)角度SELECT loops里可以嵌套SELECT loops,但出于性能考慮,一般使用a join in the FROM clause or a subquery in the WHERE clause

 

DATA wa TYPE spfli.SELECT *INTO CORRESPONDINGFIELDS OF waFROM spfliWHERE carridEQ 'LH'.  WRITE: / sy-dbcnt,wa-carrid, wa-connid, wa-cityfrom, wa-cityto.ENDSELECT.

列別名

SELECT col1 [AS <a1>] col2 [AS <a2>] ...

col可以是數(shù)據(jù)庫表里的字段名,但如果從多個表里聯(lián)合查詢時,會有重名的字段,此時只能使用別名[AS <a1>]選項了

col可以是數(shù)據(jù)庫表里的字段名dbtab~col1 dbtab~col2,這種主要用在多個表查詢同名字段時使用,否則編譯出錯

col還可以是tabalias~col形式,tabalias為數(shù)據(jù)庫表的別名,需在FROM從句定義

注:使用別名后,別名將會替代INTO 與 ORDERBY 從句中原字段名使用

存儲到指定變量中

SELECT ... INTO (<f1>, <f2>, ...). ...

此情況下要求SELECT從句后面的選擇字段個數(shù)與 INTO從句后面的字段列表個數(shù)相同(與名稱無關(guān),只與類型相關(guān))

 

在選擇多個字段時,我們也可以將這些字段一個個插入到簡單變量中,而不存儲到一個結(jié)構(gòu)體中,并且如果要存儲到多個變量中,則需要將這些對象放在括號中:DATA: wa_carrid TYPE spfli-carrid,      wa_connid TYPE spfli-connid.SELECT SINGLE carrid connidFROM spfli  INTO (wa_carrid , wa_connid )  WHERE cityfrom = 'NEW YORK' AND cityto = 'SAN FRANCISCO'.WRITE: wa_carrid,wa_connid.

注意使用種形式中,INTO后面的左括號與變量名之間不能有空格,其他可以有。

 

 

DATA:average TYPE p DECIMALS 2,          sum TYPE p DECIMALS 2.SELECT AVG( luggweight ) SUM(luggweight ) INTO(average, sum) FROM sbook.

也可這樣:

DATA:BEGIN OF luggage,          average TYPE p DECIMALS 2,          sum TYPE p DECIMALS 2,END OF luggage.SELECT AVG( luggweight ) AS average SUM( luggweight ) AS sum INTO CORRESPONDING FIELDS OFluggage FROM sbook.

 

 

SELECT * INTO…

DATA wa TYPE spfli.   "定義成與數(shù)據(jù)庫表結(jié)構(gòu)相同的結(jié)構(gòu)SELECT * INTO wa FROM spfli.  WRITE: / wa-carrid...ENDSELECT.

 

注:下面兩種省略INTO時,SELECT從句后面只能是星號*,否則編譯不通過

DATA spfli TYPE spfli.SELECT * FROM spfli.  "如果表名與存儲區(qū)結(jié)構(gòu)同名,還可以省略  WRITE: / spfli-carrid...ENDSELECT.

 

TABLES spfli."也可直接使用TABLES語句定義與數(shù)據(jù)庫表同名的結(jié)構(gòu)SELECT * FROM spfli.  WRITE: / spfli-carrid...ENDSELECT.

追加讀取APPENDING

SELECT ... INTO|APPENDING [CORRESPONDING FIELDS OF] TABLE <itab>…

 

CORRESPONDING  FIELDS  OF  [WA/TABLE]…

 

SELECT ... INTO [CORRESPONDING FIELDS OF] <wa> ...

該語句讀取一條數(shù)據(jù)到結(jié)構(gòu)<wa>中。只能使用SINGLE選項或與ENDSELECT一起使用

如果沒有[CORRESPONDING FIELDS OF]選項,<wa>結(jié)構(gòu)至少要大小或等于SELECT語句選擇所有字段長度,但此時從數(shù)據(jù)庫中查詢出來的數(shù)據(jù)存儲到結(jié)構(gòu)<wa>時,與結(jié)構(gòu)中的名稱無關(guān),它會將查詢出來的字段從左到右存儲到到<wa>結(jié)構(gòu)中,WA尾部以前的內(nèi)容可能不會被修改

 

如果加上了[CORRESPONDING FIELDS OF]選項選擇,則會將從數(shù)據(jù)庫查詢出來的字段值存儲到<wa>結(jié)構(gòu)中同名字段中,此種情況是根據(jù)SELECT從句選擇字段名與結(jié)構(gòu)<wa>中組件字段名來映射的,SELECT從句所選擇字段個數(shù)可以大于或小于、等于<wa>結(jié)構(gòu)中的字段個數(shù)。

 

如果查詢出來的結(jié)果只有一列,則WA可以直接是基本類型的無列名的結(jié)構(gòu)

 

SELECT ... INTO (dobj1, dobj2, ...)

將SELECT后面列按順序依次存入dobj1, dobj2, ...中

DATA wa TYPE spfli. SELECT carrid connid cityfrom cityto        FROM spfli        INTO (wa-carrid, wa-connid, wa-cityfrom, wa-cityto).  WRITE: / wa-carrid, wa-connid, wa-cityfrom, wa-cityto.ENDSELECT.

 

SELECT ... INTO|APPENDING[CORRESPONDING FIELDS OF] TABLE<itab>...

 

 

從左到右存儲,或者根據(jù)名稱映射存儲:

DATA:BEGIN OFstrc OCCURS 10,  mandt LIKE mara-mandt,  matnr1 LIKE mara-matnr,  END OF strc."運行時出錯,因為Select了三個字段,但strc只有兩個"select SINGLE ersda matnr mandt FROM mara INTO  strc ."即使Select了三個字段,strc只有兩個這里不會報錯。結(jié)果只將mandt儲存到strc中,因為使用了CORRESPONDING選項select SINGLE ersda matnr mandt FROM mara INTO CORRESPONDING FIELDS OFstrc .CLEAR strc."結(jié)果是matnr存儲到 strc-mandt,mandt存儲到 strc-matnr1中,規(guī)則是Select的順序與strc中字段聲明順序?qū)?yīng)起來(從左到右,與名稱無關(guān))select SINGLE matnr mandt  FROM mara INTO strc .

使用CORRESPONDING FIELDS選項,只是將同名字段進行存儲:

DATA wa_spfli TYPE spfli.SELECT SINGLE carrid connid  FROM  spfli  INTO CORRESPONDING FIELDS OF wa_spfli    WHERE cityfrom = 'NEW YORK' AND cityto = 'SAN FRANCISCO'.WRITE:wa_spfli-carrid,wa_spfli-connid.

 

 

將數(shù)據(jù)一次性存儲到內(nèi)表中:

DATA: itab TYPE STANDARD TABLE OF spfli,waLIKE LINE OF itab.SELECT carrid connid cityfrom citytoINTO CORRESPONDING FIELDS OF TABLEitabFROM spfliWHERE carrid EQ 'LH'.

]">[PACKAGE SIZE <n>] ...

只能用在SELECT ... ENDSELECT語句間。其作用是防止一次性將大量數(shù)據(jù)寫入內(nèi)表時,發(fā)生內(nèi)存溢出問題,所以可以分批來讀取,此種情況下不適使用APPENDING選項

 

如果使用FOR ALL ENTRIES選項,則可能還是會出現(xiàn)從數(shù)據(jù)庫中讀取大量數(shù)據(jù)時出現(xiàn)內(nèi)存溢出的情況,因為FOR ALL ENTRIES的過程是這樣的:先將所有數(shù)據(jù)從數(shù)據(jù)庫中讀取并臨時存儲到了個系統(tǒng)內(nèi)表中,而PACKAGE SIZE只用于將數(shù)據(jù)從系統(tǒng)內(nèi)表中分批讀取出來存儲到目標內(nèi)表中,所以使用FOR ALL ENTRIES還是可能會出現(xiàn)內(nèi)存溢出的問題

 

DATA:wa TYPE spfli,          itab TYPE SORTED TABLE OF spfli WITH UNIQUE KEY carrid connid.SELECT carrid connid            FROM spfli            INTO CORRESPONDING FIELDS OF TABLEitab            PACKAGE SIZE 3.  LOOP AT itab INTOwa.    WRITE: / wa-carrid, wa-connid.  ENDLOOP.  SKip 1.ENDSELECT.

image186

SQL查詢條件

Operator比較操作符

SELECT ... WHERE <s><operator><f>...

<f>可能是FROM從句中的某個表的表字段,也可以是數(shù)據(jù)變量或常量值,或者是具有返回值的子查詢,<operator>比較操作符可以是以下這些:

image187

BETWEEN

... col [NOTBETWEEN dobj1 AND dobj2 ...

SELECT carrid connid fldate       FROM sflight        INTO CORRESPONDING FIELDS OF TABLE sflight_tab       WHERE fldate BETWEEN sy-datumAND date.

LIKE

SELECT ... WHERE <s>[NOT] LIKE <f> [ESCAPE <h>] ...

“_”用于替代單個字符,“%”用于替代任意字符串,包括空字符串。

可以使用ESCAPE選項指定一個忽略符號h,如果通配符“_”、“%”前面有符號<h>,那么通配符失去了它在模式中的功能,而指字符本身了:

... WHERE FUNCNAME LIKE 'EDIT#_%' ESCAPE '#'.

以“EDIT_”開頭的字符串

IN

SELECT ... WHERE <s>[NOT] IN (<f1>, ......, <fn>) ...

... WHERE CITY IN ('BERLIN', 'NEW YORK', 'LONDON').

如果CITY為IN后面列表中的任何一個時返回true

 

SELECT ... WHERE <s>[NOT] IN <seltab>...

<seltab>為選擇屏幕中的條件選擇內(nèi)表

 

如果選擇內(nèi)表內(nèi)容如下(順序不重要):

SIGN  OPTION  LOW              HIGH

----------------------------------------------------------------------

I     EQ      01104711

I     BT      10000000         19999999

I     GE      90000000

E     EQ      10000911

E     BT      10000810         10000815

E     CP      1%2##3#+4++5*

則會生成如下的WHERE 語句:

... ( ID = '01104711' OR ID BETWEEN '10000000' AND '19999999' OR ID >= '90000000' )                     AND ID <> '10000911'                         AND ID NOT BETWEEN '10000810' AND '10000815' AND ID NOT LIKE '1#%2##3+4__5%' ESCAPE '#'...

seltab條件內(nèi)表生成WHERE條件語句的詳細規(guī)則可以參考《User Dialogs.docx》中的“SELECT-OPTIONS ---- 選擇內(nèi)表多條件組合規(guī)則”章節(jié)。

DATA spfli_wa TYPE spfli. SELECT-OPTIONS: s_carridFOR spfli_wa-carrid ,                 s_connid FOR spfli_wa-connid .SELECT SINGLE *       FROM spfli        INTO spfli_wa        WHERE carrid IN s_carridAND              connid IN s_connid.

 

 

SELECT ... WHERE <s>[NOT] IN <subquery>...

子查詢返回的某列的多個值

NOT

SELECT ... WHERE NOT <cond>...

... WHERE ( NUMBER = '0001' OR NUMBER = '0002' ) ANDNOT ( COUNTRY = 'F' OR COUNTRY = 'USA' ).

NULL

SELECT ... WHERE <s> IS [NOT] NULL ...

在數(shù)據(jù)庫中,有一種字段值為空值(NULL),表示該數(shù)據(jù)沒有任何數(shù)據(jù)內(nèi)容,然而在ABAP中,特定的數(shù)據(jù)對象都具有初始值,這些初始值可能是一串0或空格等,但不等同與數(shù)據(jù)庫中的NULL值,因而,在使用ABAP語句向數(shù)據(jù)庫表中插入數(shù)據(jù)時,所有的數(shù)據(jù)字段都不可能是NULL值。但是,在ABAP數(shù)據(jù)詞典里仍有可能出現(xiàn)空值字段,因為在程序中可以使用Native SQL進行空值設(shè)定,用數(shù)據(jù)詞典工具添加數(shù)據(jù)條目時也可能出現(xiàn)NULL,但在數(shù)據(jù)查詢過程中,如果將NULL字段的值讀入到程序變量中,會轉(zhuǎn)化為ABAP中相應(yīng)字段的初始值,NULL值會使用以下值替換(更多關(guān)于ABAP數(shù)據(jù)庫表的“空”、“NULL”與“Initial Values”請參考《ABAP Work Note.docx》中的“表字段中的Initial Values”與“關(guān)于ABAP中空的概念”章節(jié)):

DATENTYP         INITIALWERT_______________________________________________ACCP             ' ' blankCHAR            ' ' blankCLNT             000CUKY            ' ' blankCURR              0DATS             00000000DEC             0FLTP              0INT1              0INT2              0INT4             0LANG            ' ' blankNUMC            0000...  for field lenth <= 32                No initial value for field length > 32QUAN             0RAW             No initial value providedTIMS             000000UNIT            ' ' blankVARC            No initial value,                since VARC not supported from 3.0 onwardsLRAW            No initial value providedLCHR            No initial value provided

 

 

使用RANG條件內(nèi)表進行查詢

條件內(nèi)表過時定義法:

RANGES seltab FOR dobj [OCCURS n].

其中dobj為已定義的某個變量

 

新的語法:

DATA: BEGIN OF seltab OCCURS 0,        sign   TYPE c LENGTH1,         option TYPE c LENGTH2,         low    LIKE dobj,         high   LIKE dobj,       END OF rtab.

另外,選擇屏幕上SELECT-OPTIONS語句定義的參數(shù)就是一個RANG條件內(nèi)表,可以直接使用在下面WHERE從句中。

通過以上定義RANG條件內(nèi)表后可以在WHERE語句中如下直接使用:

WHERE … field[NOT] IN seltab …

如果RANG條件內(nèi)表為空,則INseltab邏輯表達試恒為真

動態(tài)指定查詢列

SELECT … (column_syntax) ...

column_syntax可以是character-like data object,或者是標準內(nèi)表,不區(qū)分大小寫

如果column_syntax為initial,則相當(dāng)于*,會查詢所有列

如果column_syntax是一個帶有表的內(nèi)表,則語句中的column_syntax還是代表的為表體而不是表頭

 

DATA: itab TYPE STANDARD TABLE OF spfliWITH HEADER LINE.DATA: line(72)TYPE c,      list LIKE TABLE OF line.line = 'CARRID'.APPEND line TO list.line = 'CITYFROM CITYTO'.APPEND line TO list."以內(nèi)表作為動態(tài)列SELECT DISTINCT (list)INTO CORRESPONDING FIELDS OF TABLE itabFROM spfli UP TO 2 ROWS.LOOP AT itab.  WRITE: / itab-cityfrom, itab-cityto,itab-carrid.ENDLOOP.CLEAR: itab[],itab."以字符串作為動態(tài)列SELECT DISTINCT (line)INTO CORRESPONDING FIELDS OF TABLE itabFROM spfli UP TO 2 ROWS.SKIP.LOOP AT itab.  WRITE: / itab-cityfrom, itab-cityto,itab-carrid.ENDLOOP.

NEW YORK             SAN FRANCISCO        DL

FRANKFURT            BERLIN               LH

 

BERLIN               FRANKFURT

FRANKFURT            BERLIN

 

動態(tài)查詢表中指定的某列:

"表中的某列的列名PARAMETERS comp LENGTH 20.DATA: dref TYPE REF TO data,      long_name TYPE string,      ftab      TYPE TABLE OF string.FIELD-SYMBOLS <fs>.long_name = 'spfli-' && comp."根據(jù)詞典中的類型動態(tài)創(chuàng)建數(shù)據(jù)對象CREATE DATA drefTYPE (long_name)."動態(tài)創(chuàng)建出來的數(shù)據(jù)對象需解引用并分配給字段符號才能使用ASSIGN dref->* TO <fs>.APPEND comp TO ftab."動態(tài)列放在內(nèi)表中SELECT DISTINCT (ftab)INTO <fs> FROM spfliWHERE carrid = 'LH'.  WRITE: / <fs>.ENDSELECT.

動態(tài)指定表

SELECT ... FROM (dbtab_syntax)...

column_syntax可以是character-like data object,或者是標準內(nèi)表,不區(qū)分大小寫

如果column_syntax是一個帶有表的內(nèi)表,則語句中的column_syntax還是代表的為表體而不是表頭

 

DATA wa TYPE scarr.DATA name(10)VALUE 'SCARR'.SELECT * INTO wa FROM (name) CLIENT SPECIFIED WHEREmandt = '000'.  WRITE: / wa-carrid,wa-carrname.ENDSELECT.

 

 

PARAMETERS: p_cityfr TYPE spfli-cityfrom,            p_cityto TYPE spfli-cityto.DATA: BEGIN OF wa,         fldate TYPE sflight-fldate,         carrname TYPE scarr-carrname,         connid   TYPE spfli-connid,       END OF wa.DATA itab LIKE SORTED TABLE OF wa               WITH UNIQUE KEY fldate carrname connid.DATA: column_syntax TYPE string,      dbtab_syntax TYPE string.column_syntax = `c~carrname p~connid f~fldate`.dbtab_syntax = `( ( scarr AS c `  & ` INNER JOIN spfli AS p ON p~carrid  = c~carrid`  & ` AND p~cityfrom = p_cityfr`  & ` AND p~cityto   = p_cityto )`  & ` INNER JOIN sflight AS f ON f~carrid = p~carrid `  & ` AND f~connid = p~connid )`.SELECT (column_syntax)       FROM (dbtab_syntax)       INTO CORRESPONDING FIELDS OF TABLE itab.

動態(tài)指定查詢條件

SELECT ... WHERE (cond_syntax) ...

 

SELECT ... WHERE <cond>AND (cond_syntax) ...

 

cond_syntax可以是character-like data object,或者是標準內(nèi)表。如果為初始值initial,則返回結(jié)果為真

如果cond _syntax是一個帶有表的內(nèi)表,則語句中的cond _syntax還是代表的為表體而不是表頭

 

動態(tài)的條件只能用在WHERE從句中,不能用在ON

 

下面程序中,內(nèi)表itab僅包含一個類型C組件且最大長度為72的字段,內(nèi)表名稱必須在括號中指定。可以將各種邏輯表達式(但除上面的RANG條件內(nèi)表外)添加到內(nèi)表行中,且在內(nèi)表行中的邏輯表達式里只能使用文字不能再使用變量:

DATA: cond(72)TYPE c,      itab LIKE TABLE OF cond,      city1(10) VALUE 'NEW YORK',      city2(13) VALUE 'SAN FRANCISCO',      itab_spfli LIKE TABLE OF spfliWITH HEADER LINE.CONCATENATE 'cityfrom = ''' city1'''' INTO cond.APPEND cond TO itab.CONCATENATE 'or cityfrom = ''' city2'''' INTO cond.APPEND cond TO itab.SELECT * INTO TABLE itab_spfliFROM spfli WHERE (itab).LOOP AT itab_spfli.  WRITE: / itab_spfli-carrid, itab_spfli-connid.ENDLOOP.

 

另外,WHERE后面也可以使用一個或多個拼接好的查詢條件字符串:

DATA: cond1(72)TYPE c,      cond2(72) TYPE c,      city1(10) VALUE 'NEW YORK',      city2(13) VALUE 'SAN FRANCISCO',      itab_spfli LIKE TABLE OF spfliWITH HEADER LINE.CONCATENATE 'cityfrom = ''' city1'''' INTO cond1.CONCATENATE 'cityfrom = ''' city2'''' INTO cond2.SELECT * INTO TABLE itab_spfliFROM spfli WHERE (cond1)OR (cond2).

也可以是一部分是拼接好的查詢條件字符串,一部分是條件table:

DATA: cond(72)TYPE c,      cond1(72) TYPE c,      itab LIKE TABLE OF cond,      city1(10) VALUE 'NEW YORK',      city2(13) VALUE 'SAN FRANCISCO',      itab_spfli LIKE TABLE OF spfliWITH HEADER LINE.CONCATENATE 'cityfrom = ''' city1'''' INTO cond1.CONCATENATE 'cityfrom = ''' city2'''' INTO cond.APPEND cond TO itab.SELECT * INTO TABLE itab_spfliFROM spfli WHERE (itab)or (cond1).

 

也可以部分是動態(tài)的條件:

DATA: cond(72)TYPE c,      itab LIKE TABLE OF cond,      city1(10) VALUE 'NEW YORK',      city2(13) VALUE 'SAN FRANCISCO',      itab_spfli LIKE TABLE OF spfliWITH HEADER LINE.CONCATENATE 'cityfrom = ''' city2'''' INTO cond.APPEND cond TO itab.SELECT * INTO TABLE itab_spfliFROM spfli WHERE (itab)or cityfrom = city1.

指定集團CLIENT SPECIFIED ...

一般的SAP數(shù)據(jù)庫表在創(chuàng)建時,屬于特定集團的表都由系統(tǒng)自動生成一個默認的字段MANDT,用于指定數(shù)據(jù)屬于哪個集團。該字段也是關(guān)鍵字段之一。有些系統(tǒng)通用表是與集團無關(guān)的。

一般情況下,OPENSQL操作時,系統(tǒng)會自動進行集團處理,系統(tǒng)只從當(dāng)前集團提取數(shù)據(jù),在程序中不能指定MANDT字段,否則出錯。

如果確實需要在程序中指明需要操作的特定集團,則需要使用CLIENT SPECIFIED取消系統(tǒng)的自動處理功能:

 

SELECT|UPDATE ... <tables>CLIENT SPECIFIED ...

 

該選項必須跟在數(shù)據(jù)庫表名稱之后。關(guān)閉了系統(tǒng)自動集團處理后,就可以就可以在WHERE條件子句中指定集團字段了。

TABLES spfli.SELECT SINGLE *FROM  spfli CLIENT SPECIFIED WHERE mandt BETWEEN '100' AND'999'.WRITE spfli-cityto.

禁止使用緩沖BYPASSING BUFFER ...

可以在數(shù)據(jù)字典Technical settings中進行設(shè)定。如果對已經(jīng)進行了緩沖設(shè)定的數(shù)據(jù)庫表,系統(tǒng)將在首次數(shù)據(jù)查詢操作的同時進行數(shù)據(jù)緩沖。不同的緩沖之間或緩沖與數(shù)據(jù)庫表本身間的同步過程則數(shù)據(jù)接口完成。

 

SELECT語句中的FROM子句的BYPASSING BUFFER附加項,可以用于在特殊情況下禁止緩沖。此外,DISTINCT附加項與聯(lián)合查詢、總計選擇、IS NULL條件、子查詢,以及GROUPBY和ORDER BY同時使用時,也將自動忽略緩沖設(shè)定。

 

SELECT ... FROM <tables>BYPASSING BUFFER ...

 

">限定選擇行數(shù)UP TO n ROWS ...

SELECT ... FROM <tables>UP TO <n> ROWS ...

如果n為正數(shù),系統(tǒng)最多選擇n行到程序中,如果n為0,則還是選擇所有滿足條件的數(shù)據(jù)。如果同時使用ORDER BY 選項,則系統(tǒng)首先選出所有滿足條件的數(shù)據(jù),并排序,然后將頭n行作為選擇結(jié)果。

 

注:一般使用SINGLE是表示根據(jù)表的關(guān)鍵字來查詢,這樣才能確保只有一條數(shù)據(jù),所以當(dāng)使用SINGLE時,不能再使用ORDER BY語句(因為也沒有必要了),如果查詢時不是根據(jù)關(guān)鍵字來查詢,且查詢時先排序再取一條時,我們只能使用另一種語法:

   SELECT * FROM  tj02t  INTO CORRESPONDING FIELDS OF TABLEgt_result UP TO 1ROWS  WHERE SPRAS= 'E'

ORDER BY ISTAT.

SELECT語句嵌套

DATA: wa_carrid TYPE spfli-carrid,      wa_connid TYPE spfli-connid,      wa_carrname TYPE scarr-carrname.SELECT carrid connid FROM spfli INTO (wa_carrid, wa_connid) WHEREcityfrom = 'NEW YORK'.  SELECT carrname FROM scarr INTO wa_carrname    WHERE carrid = wa_carrid.    WRITE wa_carrname.  ENDSELECT.ENDSELECT.

每當(dāng)在表SPFLI中查詢到一個符合條件值,系統(tǒng)就重新對SCARR進行一次查詢,這與標準SQL相關(guān)子查詢類似。

FOR ALL ENTRIES選項

SELECT ... FOR ALL ENTRIES IN <itab> WHERE <cond>...

該選項拿<itab>每一條數(shù)據(jù)到數(shù)據(jù)庫表中查詢,并且將查詢出來的結(jié)果集使用合并并返回。重復(fù)的數(shù)據(jù)會自動剔除。如果<itab>為空,則會忽略該條件(即使Where后面還有其它條件,所有的條件都會忽略),即查詢出所有數(shù)據(jù)。<cond>條件語句中不能使用LIKEBETWEENIN這些操作符,只能使用比較操作符

該選項的作用與Selection Options是類似的

 

為了避免多次重復(fù)數(shù)據(jù)查詢(嵌套查詢效率很低),可以先將SPFLI中符合條件的數(shù)據(jù)選進一個內(nèi)表,然后僅根據(jù)該內(nèi)表中包含的carrid字段繼續(xù)查詢表scarr,這樣最多只發(fā)送兩次查詢,而不是1+N次查詢。

選出符合已存在內(nèi)表中所有滿足條件的數(shù)據(jù)值:

 

FOR ALL ENTRIES對于以下兩種情況會忽略SAP bufferung:

l  Tables with single record buffering.

l  Tables with generic buffering if the condition after FOR ALL ENTRIES prevents precisely one generic area from being specified exactly.

1、使用該選項后,對于最后得出的結(jié)果集系統(tǒng)會自動刪除重復(fù)行(具有DISTINCT選項的作用,但與DISTINCT不同的是,這個去除重復(fù)的動作是在將所有數(shù)據(jù)從數(shù)據(jù)庫中講到到SAP應(yīng)用服務(wù)器后進行刪除的,而不是在數(shù)據(jù)庫系統(tǒng)里去除的,這是因為FOR ALL ENTRIES在執(zhí)行查詢時,可能會分成多個SQL語句,所以只能將多次讀取的數(shù)據(jù)合并后進行去除)。因此如果你要保留重復(fù)行記錄時,記得在SELECT語句中添加足夠鍵值項目(有必要時,增加所有所查表的所有主鍵),以保證結(jié)果集中所需重復(fù)項目不會被刪除。

2、FOR ALL ENTRIES IN后面使用的內(nèi)部表itab如果為空,系統(tǒng)將視為無條件選取(即忽略WHERE語句),將當(dāng)前CLIENT下所有記錄選出,因此為避免無意義的全件檢索,在使用該語句前一定要判斷內(nèi)部表itab是否為空,為空時不執(zhí)行包含該語句的數(shù)據(jù)庫檢索處理

3、由于itab-f實際上是作為占位符被替換,所以內(nèi)部表itab中不要帶HEADER行,以免造成混淆,檢索出錯

4、內(nèi)表中的條件字段不能使用LIKE,BETWEEN,IN比較操作符。因為這些比較操作符都是不確定比較操作符(將選擇條件設(shè)定在一個范圍內(nèi)),而FOR ALL ENTRIES IN語句的作用相當(dāng)于將選擇條件塊全部并列開來,用OR連接,如果每個OR分支中又是不確定的范圍,那么系統(tǒng)性能將大大降低,因此R/3系統(tǒng)在使用該語句時禁止使用不確定比較操作符。

5、使用該語句時,ORDER BY語句和HAVING語句將不能使用。

6、使用該語句時,除COUNT( * )(并且如果有了COUNT函數(shù),則不能再選擇其他字段,只能使用在Select ... ENDSelect語句中了)以外的所有合計函數(shù)(MAX,MIN,AVG,SUM)都不能使用。

DATA:tab_spfli TYPE TABLE OF spfli,      tab_sflight TYPE SORTED TABLE OF sflightWITH UNIQUE KEY TABLE LINE,      wa LIKE LINE OF tab_sflight.SELECT carrid connid    INTO CORRESPONDING FIELDS OF TABLE tab_spfli    FROM spfli    WHERE cityfrom = 'NEW YORK'.SELECT carrid connid fldate    INTO CORRESPONDING FIELDS OF TABLE tab_sflight    FROM sflight    FOR ALL ENTRIES IN tab_spfli    WHERE carrid =tab_spfli-carrid AND connid = tab_spfli-connid.LOOP AT tab_sflight INTO wa.  AT NEW connid.    WRITE: / wa-carrid, wa-connid.  ENDAT.  WRITE: / wa-fldate.ENDLOOP.

 

注意:FOR ALL ENTRIES所使用的內(nèi)表里一定要有數(shù)據(jù),否則查詢時會將表中的所有數(shù)據(jù)都查詢出來,即使Where后面還有其它條件,所有的條件都會忽略:

  SELECT vbeln posnr pstyv werks matnr arktx lgort waerk kwmeng    FROM vbap    INTO TABLE gt_so    FOR ALL ENTRIES IN lt_matnr    WHERE matnr = lt_matnr-matnr AND vbeln IN s_vbeln AND posnr IN s_posnr.

如果上面的lt_matnr為空,則“AND  vbeln IN s_vbeln AND posnr IN s_posnr”條件也會忽略掉,即整個Where都會被忽略掉。

 

 

TABLES:mara.DATA: BEGIN OFstrc OCCURS 0,  matnr LIKE mara-matnr,  lvorm LIKE mara-lvorm,  END OF strc.SELECT-OPTIONS:s_matnr FOR mara-matnr.START-OF-SELECTION.  SELECT  matnr FROMmara    INTO CORRESPONDING FIELDS OF TABLE strc    FOR ALL ENTRIES IN strc WHERE matnr =  strc-matnr .

當(dāng)內(nèi)表strc為空時,上面Select語句生成的標準SQL如下:

SELECT

  "MATNR"

FROM

  "MARA"

WHERE"MANDT" = '210'

 

內(nèi)表strc不為空時,生成的SQL如下:

strc-matnr = '000000000000000101'.APPEND strc.strc-matnr = '000000000000000103'.APPEND strc.strc-matnr = '000000000000000104'.APPEND strc.START-OF-SELECTION.  SELECT  matnr FROMmara    INTO CORRESPONDING FIELDS OF TABLE strc    FOR ALL ENTRIES IN strc WHERE matnr = strc-matnr .

SELECT

  "MATNR"

FROM

  "MARA"

WHERE "MANDT" = '210' AND "MATNR" IN ( '000000000000000101' , '000000000000000103' , '000000000000000104' )

 

注:這里看上去FOR ALL ENTRIES使用 IN 表達式來代替了,這是只有使用到內(nèi)表中一個條件是這樣的,如果使用多個條件時,不會使用In表達式,而是使用OR連接,像這樣:

image188

image189

 

另外,在使用FOR ALL ENTRIES時,不管使用了條件內(nèi)表中的一個還是多個條件字段,都會以5個值為單位進行SQL發(fā)送,但RANGE可以達到3000左右

 

內(nèi)表strc不為空時,且在Where后面加上了另外的條件:

strc-matnr = '000000000000000101'.APPEND strc.strc-matnr = '000000000000000103'.APPEND strc.strc-matnr = '000000000000000104'.APPEND strc.START-OF-SELECTION.  SELECT  matnr FROMmara    INTO CORRESPONDING FIELDS OF TABLE strc    FOR ALL ENTRIES IN strc WHERE matnr = strc-matnr and  ERNAM = 'XUJIJING'.

SELECT

  "MATNR"

FROM

  "MARA"

WHERE "MANDT" = '210' AND "MATNR" IN ( '000000000000000101' , '000000000000000103' , '000000000000000104' ) AND "ERNAM" = 'XUJIJING'

 

內(nèi)表strc為空時,且在Where后面加上了另外的條件:

SELECT

  "MATNR"

FROM

  "MARA"

WHERE "MANDT" = '210'

聯(lián)合查詢

使用JOIN時,會繞過SAP緩存,可以使用FOR ALL ENTRIES來代替

 

ON后面的條件與Where條件類似,但有以下不同:

ü  必需要有ON,也就是說必須要有一個條件,且多個條件之間只能使用AND連接

ü  所有條件表達式中兩個操作數(shù)之間必須有一個是來自于JOIN右邊表dbtab_right的某個字段

ü  不能使用NOT, LIKE, IN(但如果是 INNER JOIN,則>、<、BETWEEN …AND、<>都可用)

ü  如果是INNER JOIN,也可把ON從句中的<cond>條件置于WHERE子句中(Left Outer Join是有所區(qū)別的,請參見后面),因為二者效果一樣

ü  如果是LEFT OUTER JOIN,則只能使用等號操作符:(=, EQ)

ü  如果是LEFT OUTER JOIN,則至少有一個條件表達式的兩個操作數(shù)一個是來自于左邊表dbtab_left,另一個來自右邊表dbtab_right

ü  如果是LEFT OUTER JOIN,則只能與同一個表進行連接(關(guān)聯(lián)),即每個條件表達式兩個操作數(shù)中除了一個已固定來自于右邊表dbtab_right外(不管是Inner,還是Left,因為所有ON后面每個條件中必須要有一個是來自于右邊表dbtab_right中的字段),所有條件表達式中另外一個操作數(shù)(在另一操作數(shù)非dbtab_right字段的情況下,如果另一操作數(shù)就是dbtab_right某個字段或某個常量時,就另當(dāng)別論了)必須來自于同一個左邊表dbtab_left,即LEFT OUTER JOIN只能與一個dbtab_left發(fā)生關(guān)聯(lián)關(guān)系(即在ON條件中所有表達試中的左表只能出現(xiàn)同一個,不能出現(xiàn)第二個,如下所示:)

image190

ü  如果是LEFT OUTER JOIN,同一右表dbtab_right不能出現(xiàn)在不同的LEFT OUTER JOIN(在一個Select語句中LEFT JOIN可以多次出現(xiàn),關(guān)聯(lián)不同的表)的條件表達式中:

image191

ü  LEFT OUTER JOIN右邊表dbtab_right的所有字段不能出現(xiàn)在WHERE中(如果出現(xiàn)在WHERE從句好像沒有什么意義了,此時與INNER JOIN相當(dāng)),只能出現(xiàn)在ON條件從句中(可以將從表的條件寫在On后面而不是Where后面來解除這個限制,但是,Left join的條件放在on 與 where后面是不一樣的,請看后面的示例)

 

SELECT ...FROM <tab> [INNER] JOIN <dbtab> [AS <alias>] ON <cond>

DATA:BEGIN OF wa,          carrid TYPE spfli-carrid,          connid TYPE spfli-connid,          fldate TYPE sflight-fldate,          bookid TYPE sbook-bookid,END OF wa,       itab LIKE SORTED TABLE OF wa WITH UNIQUE KEY carrid connid fldate bookid.SELECT p~carrid p~connid f~fldate b~bookid  INTO CORRESPONDING FIELDS OF TABLEitab  FROM ( ( spfli AS p  INNER JOIN sflight AS f ON p~carrid = f~carrid AND p~connid = f~connid )  INNER JOIN sbook AS b ON b~carrid = f~carrid AND b~connid = f~connid AND b~fldate = f~fldate        )  WHERE p~cityfrom= 'FRANKFURT' AND p~cityto= 'NEW YORK' AND f~seatsmax > f~seatsocc.

 

 

SELECT ...FROM <tab> LEFT [OUTER] JOIN <dbtab> [AS <alias>] ON <cond>

DATA:BEGIN OF wa,          carrid TYPE scarr-carrid,          carrname TYPE scarr-carrname,          connid TYPE spfli-connid,END OF wa,        itab LIKE SORTED TABLE OF wa WITH NON-UNIQUE KEY carrid.SELECT s~carrid s~carrname p~connid  INTO CORRESPONDING FIELDS OF TABLE itab  FROM scarr AS s  LEFT OUTER JOIN spfli AS p ON s~carrid = p~carrid AND p~cityfrom = 'FRANKFURT'.

 

數(shù)據(jù)庫在通過連接兩張或多張表來返回記錄時,都會生成一張中間的臨時表,然后再將這張臨時表返回給用戶。在使用left jion時,on和where條件的區(qū)別如下:

1、on條件是在生成臨時表時使用的條件,它不管on中的條件是否為真,都會返回左邊表中的記錄。

2、where條件是在臨時表生成好后,再對臨時表進行過濾的條件。這時已經(jīng)沒有l(wèi)eft join的含義(必須返回左邊表的記錄)了,條件不為真的就全部過濾掉。

假設(shè)有兩張表:

表1:tab1

id

size

1

10

2

20

3

30

表2:tab2

size

name

10

AAA

20

BBB

20

CCC

兩條SQL:1、select * form tab1 left join tab2 on (tab1.size = tab2.size) where tab2.name=’AAA’2、select * form tab1 left join tab2 on (tab1.size = tab2.size and tab2.name=’AAA’)

第一條SQL的過程:

1、中間表on條件: tab1.size = tab2.size

tab1.id

tab1.size

tab2.size

tab2.name

1

10

10

AAA

2

20

20

BBB

2

20

20

CCC

3

30

(null)

(null)

  

2、再對中間表過濾where條件:tab2.name=’AAA’

tab1.id

tab1.size

tab2.size

tab2.name

1

10

10

AAA

  

第二條SQL的過程:

1、中間表on條件: tab1.size = tab2.size and tab2.name=’AAA’(條件不為真也會返回左表中的記錄)

tab1.id

tab1.size

tab2.size

tab2.name

1

10

10

AAA

2

20

(null)

(null)

3

30

(null)

(null)

其實以上結(jié)果的關(guān)鍵原因就是left join,right join,full join的特殊性,不管on上的條件是否為真都會返回left或right表中的記錄,full則具有l(wèi)eft和right的特性的并集。而inner join沒這個特殊性,則條件放在on中和where中,返回的結(jié)果集是相同的(但放在ON后面的效率會高一些)。

子查詢

使用子查詢時會繞過SAP buffering

 

有時只需從一個表中選擇數(shù)據(jù),但這些數(shù)據(jù)與其他表中的數(shù)據(jù)字段內(nèi)容相關(guān)聯(lián),但又不需將其它表中相關(guān)的數(shù)據(jù)查出來,類似操作可通過子查詢進行。子查詢是沒有SINGLEINTO, and ORDER BY的查詢語句,通過col operator [ALL|ANY|SOME] 、EXISTS、IN連接至WHERE從句與HAVING從句中(但不能出現(xiàn)在ON從句中):

l  col operator [ALL|ANY|SOME] ( SELECT …FROM … )

l  [NOTEXISTS ( SELECT …FROM … )

l  [NOTIN ( SELECT …FROM … )

 

子查詢可以嵌套,但不能用于pool tables 、cluster tables兩種表

 

ALL、ANY、SOME子查詢

這種子查詢的SELECT從句中只有一個表字段或者是一個統(tǒng)計列

 

... <s><operator><subquery> ...

要求子查詢只能返回一條數(shù)據(jù)(否則運行時出錯),所以<subquery>一般是一個SELECT SINGLE的子查詢。

如果子查詢的結(jié)果只有一條數(shù)據(jù)時,可以省略[ALL|ANY|SOME]選項:

DATA wa_sflight TYPE sflight. SELECT *        FROM sflight        INTO wa_sflight        WHERE seatsocc = (SELECT MAX( seatsocc )FROM sflight ). ENDSELECT.

如果子查詢返回的是多條,則可以使用以下子查詢:

... <s><operator>ALL|ANY|SOME <subquery> ...

l  如果使用ALL,則如果子查詢返回的所有行都滿足<operator>比較條件時,才為真

l  如果使用ANY|SOME,則如果子查詢返回的所有行中只要有一條滿足<operator>比較條件時,就會為真

l  比較操作符(= or EQ)與ANY|SOME一起使用時,與IN操作符具有一樣的效果

 

DATA: id  TYPE sbook-customid,       cnt TYPE i.SELECT customid COUNT( * )       FROM sbook        INTO (id, cnt)        GROUP BY customid       HAVING COUNT( * )>= ALL ( SELECT COUNT( * )                                          FROM sbook                                         GROUP BY customid ).ENDSELECT.

[NOT] IN子查詢

此類子查詢SELECT從句中也只有單獨的一列選擇列,但查詢出的結(jié)果可能有多個。與[NOT] IN一起使用

 

DATA: carr_id TYPE spfli-carrid VALUE 'LH',      conn_id TYPE spfli-connid VALUE '0400'.DATA: city TYPE sgeocity-city,      lati TYPE p DECIMALS 2,      longi TYPE p DECIMALS 2.SELECT SINGLE city latitude longitude  INTO (city, lati, longi)  FROM sgeocity  WHERE city IN ( SELECT cityfrom FROM spfli                    WHERE carrid = carr_id                    AND   connid = conn_id ).WRITE: city, lati, longi.

[NOT] EXISTS子查詢

這類子查詢沒有返回值,也不要求SELECT從句中只有一個選擇列,選擇列可以任意個數(shù),WHERE or HAVING從句來根據(jù)該子查詢的是否查詢到數(shù)據(jù)來決定外層主查詢語句來選擇相應(yīng)數(shù)據(jù)

該類子查詢只能與[NOT] EXISTS一起使用:

DATA: name_tab TYPE TABLE OF scarr-carrname,      name LIKE LINE OF name_tab.SELECT carrname INTO TABLE name_tabFROM scarr  WHERE EXISTS (SELECT * FROM spfli                    WHERE carrid = scarr~carrid                    AND cityfrom = 'NEW YORK' ).LOOP AT name_tabINTO name.  WRITE: / name.ENDLOOP.

此子查詢又為相關(guān)子查詢

如果某個子查的WHERE條件中引用了外層查詢語句的列,則稱此子查詢?yōu)橄嚓P(guān)子查詢。相關(guān)子查詢對外層查詢結(jié)果集中的每條記錄都會執(zhí)行一次,所以盡量少用相關(guān)子查詢

統(tǒng)計函數(shù)

SELECT <lines><agg>( [DISTINCT] <s1> ) [AS <a1>]<agg>( [DISTINCT] <s2> ) [AS <a2>] ...

 

MAX、MIN、AVG、SUM、COUNT

 

聚合函數(shù)都可以加上DISTINCT選項

 

MAX, MIN, or SUM計算的結(jié)果類型為相應(yīng)表字段的類型

AVG計算的結(jié)果類型為數(shù)據(jù)詞典類型FLTP,在ABAP程序里可以使用F類型來接收

COUNT have the Dictionary type INT4.

 

DATA: BEGIN OF luggage,  average TYPE p DECIMALS 2,  sum TYPE pDECIMALS 2,END OF luggage.SELECT AVG( luggweight )AS average SUM( luggweight )AS sum  INTO CORRESPONDING FIELDS OF luggage  FROM sbook.

 

SELECT carrid connid SUM( seatsocc )  FROM sflight  INTO (wa_carrid, wa_connid, sum_seat)  WHERE spfli~cityform = `sing`

分組

SELECT <lines><s1> [AS <a1>] <s2> [AS <a2>] ...

<agg><sm> [AS <am>] <agg><sn> [AS <an>] ...

...

GROUP BY <s1><s2> ....

 

GROUP BY后面還可以是動態(tài)指:... GROUP BY (<itab>) ...這里的<itab>是一個具有列寬為72 C Type的內(nèi)表,只有一個字段,且存儲了分組的字段名,如上面的<s1><s2>

 

如果將統(tǒng)計函數(shù)與GROUP BY子句一起使用,那么Select語句中未出現(xiàn)在統(tǒng)計函數(shù)的數(shù)據(jù)庫字段都必須在GROUP BY子句中出現(xiàn)(如這里的<s1>、<s2>)。如果使用INTO CORRESPONDING FIELDS項,則需要在Select語句中通過AS后面的別名將統(tǒng)計結(jié)果存放到與之相應(yīng)同名的內(nèi)表字段中。

 

 

DATA : carrid TYPE sflight-carrid,      minimum TYPE p DECIMALS 2,      maximum TYPE p DECIMALS 2.WRITE: / `Carrier ID`,  AT  15 `Minimum Price`,  AT 30 `Maximum Price`.SELECT carrid MIN( price )MAX( price )  INTO (carrid,minimum,maximum)  FROM sflight  GROUP BY carrid.    WRITE: / carrid, minimum, maximum.ENDSELECT.

Carrier ID    Minimum Price  Maximum Price

LH            899.00          6,000.00

SQ            849.00            849.00

分組過濾

只有使用GROUP BY子句時,才能出現(xiàn)HAVING。

SELECT <lines><s1> [AS <a1>] <s2> [AS <a2>] ...

<agg><sm> [AS <am>] <agg><sn> [AS <an>] ...

...

GROUP BY <s1><s2> ....

HAVING <cond>.

像WHERE動態(tài)條件從句一樣,也可以使用動態(tài)的條件

 

SELECT carrid min( price ) as m max( price )  INTO (carrid, minimum, maximum)  from sflight  group by carrid  HAVING MAX( price )  >10.   WRITE: / carrid, minimum, maximum.ENDSELECT.

排序

注:SELECT SIGLE不能與ORDER BY一起使用

 

根據(jù)關(guān)鍵字排序:

SELECT  *

...

... ORDER BY PRIMARY KEY.

注:... ORDER BY PRIMARY KEY只能用在從單表中查詢時使用

 

指定排序字段,默認為升序:

SELECT ...

...

ORDER BY <s1> [ASCENDING|DESCENDING]

<s2> [ASCENDING|DESCENDING] ...

 

動態(tài)指定排序列:

SELECT ...

...

ORDER BY (column_syntax).

column_syntax為Initial時,則會忽略

 

DATA:BEGIN OF wa,  carrid TYPE sflight-carrid,  connid TYPE sflight-connid,  min TYPE i,END OF wa.SELECT carrid connid MIN( seatsocc ) AS min  INTO CORRESPONDING FIELDS OF wa  FROM sflight  GROUP BY carrid connid  ORDER BY carrid min DESCENDING.    WRITE: / wa-carrid, wa-connid, wa-min.ENDSELECT.

 

通過游標讀取數(shù)據(jù)

在通常的SELECT語句中,滿足查詢條件的所有數(shù)據(jù)都是一次性從數(shù)據(jù)庫中讀取出來放在INTO子句指定的目標區(qū)域中,這樣做會帶來一個問題:這些數(shù)據(jù)從數(shù)據(jù)庫讀取出來然后一條條APPEND到內(nèi)表中,這一過程也需要花費時間。如果使用游標,則會解決SELECT語句的一些處理開銷,使用游標時,可以將數(shù)據(jù)行直接放到一個扁平的結(jié)構(gòu)體對象中。

 

1.         打開游標

OPEN CURSOR [WITH HOLD] <c>FOR SELECT <result>

FROM <source>

[WHERE <condition>]

[GROUP BY <fields>]

[HAVING <cond>]

[ORDER BY <fields>].

 

游標不能用于SINGLE選項的SELECT語句。在數(shù)據(jù)庫提交時,系統(tǒng)將自動關(guān)閉光標,一個例外情況是如果在OPEN CURSOR語句中使用了WITH HOLD選項時,則Native SQL數(shù)據(jù)庫提交將不會關(guān)閉光標。

 

<C>必須是一個使用DATA語句定義的具有CURSOR類型的變量

 

2.         讀取數(shù)據(jù)

FETCH NEXT CURSOR<c> INTO <target>.

<target>為扁平的結(jié)構(gòu)對象

如果讀取到數(shù)據(jù),則SY-SUBRC to 0, otherwise to 4. After a FETCH statement, the system field SY-DBCNT contains the number of lines already read by the current cursor.

 

3.         關(guān)閉游標

CLOSE CURSOR <c>.

 

DATA: c TYPE cursor.DATA: wa TYPE spfli."1打開游標OPEN CURSOR:c FOR SELECT carrid connid    FROM spfli    WHERE carrid = 'LH'.DO.  "2、讀取數(shù)據(jù)  FETCH NEXT CURSOR c INTO CORRESPONDING FIELDS OF wa.  IF sy-subrc <> 0.    "3、關(guān)閉游標    CLOSE CURSOR c.    EXIT.  ELSE.    WRITE: / wa-carrid, wa-connid.  ENDIF.ENDDO.

更新數(shù)據(jù)

INSERT

INSERT

{INTO {dbtab|(dbtab_syntax)} [CLIENT SPECIFIED]VALUES wa}

| {{dbtab|(dbtab_syntax)} [CLIENT SPECIFIED]FROM wa|{TABLE itab [ACCEPTING DUPLICATE KEYS]}}

 

插入單條:

INSERT INTO <tabname> VALUES <wa>.

INSERT <tabname> FROM <wa>.

INSERT <tabname>.

在插入時是按照數(shù)據(jù)庫表結(jié)構(gòu)來解析<wa>結(jié)構(gòu),與<wa>中的字段名無關(guān),所以<wa>的長度只少要等于或大于所對應(yīng)表結(jié)構(gòu)總長度

工作區(qū)wa是與數(shù)據(jù)表具有相同結(jié)構(gòu)的數(shù)據(jù)對象,一般直接基于數(shù)據(jù)表結(jié)構(gòu)聲明。FROM這種格式在以下這種情況下可以省略(此方式下不允許使用動態(tài)指定表):

TABLES:mard.INSERT mard.

 

如果插入成功,SY-SUBRC為0,否則為4

 

TABLES spfli.DATA wa TYPE spfli.wa-carrid = 'LH'.wa-cityfrom = 'WASHINGTON'.INSERT INTO spfli VALUES wa.

wa-carrid = 'UA'.wa-cityfrom = 'LONDON'.INSERT spfli FROM wa.

spfli-carrid = 'LH'.spfli-cityfrom = 'BERLIN'.INSERT spfli.

 

插入多行:

INSERT dbtab FROM TABLE itab.

其中內(nèi)表itab中包含希望插入的數(shù)據(jù)條目,該內(nèi)表的行結(jié)構(gòu)也必須和數(shù)據(jù)庫表的行結(jié)構(gòu)一致。如果所有數(shù)據(jù)都插入成功,則SY-SUBRC返回0,如果有一條不成功,則所有數(shù)據(jù)都不會插入,但使用下面的插入語句可以避免部分不成功的問題:

 

INSERT<tabname>FROM TABLE <itab> [ACCEPTING DUPLICATE KEYS].

 

其中ACCEPTING DUPLICATE KEYS選項的效果是:如果現(xiàn)出關(guān)鍵字相同條目,系統(tǒng)將SY-SUBRC返回4,并跳過該條目,但其他數(shù)據(jù)會插入進去。

 

SY-DBCNT存儲了插入成功的條數(shù),而不管SY-SUBRC的值是什么

 

DATA:itab TYPE HASHED TABLE OF spfli WITH UNIQUE KEY carrid connid,      wa LIKE LINE OF itab.."假設(shè)下面兩條數(shù)據(jù)在數(shù)據(jù)庫中都不存在wa-carrid = 'UD'.wa-connid = '0011'.wa-cityfrom = 'ZH'.INSERT wa INTO TABLEitab.INSERT spfli FROM TABLEitab.WRITE:/ sy-subrc,sy-dbcnt.wa-carrid = 'AD'.wa-connid = '4574'.wa-cityfrom = 'EN'.INSERT wa INTO TABLEitab.INSERT spfli FROM TABLEitab ACCEPTING DUPLICATE KEYS.WRITE:/ sy-subrc,sy-dbcnt.

image192

UPDATE

UPDATE {dbtab|(dbtab_syntax)} [CLIENT SPECIFIED]{ {SET [col1 = f1 col2 = f2 ... ][col1 = col1 + f1 col2 = col2 + f2 ...] [col1 = col1 - f1 col2 = col2 - f2 ...] [(expr_syntax1) (expr_syntax2) ...] [WHERE sql_cond]} | {FROM wa|{TABLE itab}} }

 

expr_syntax1:動態(tài)指定修改表達式,可以是character-like data object or a standard table,如果為Initail則忽略

sql_cond:請參考SELECT語句中的WHERE從句用法(但不適用FOR ALL ENTRIES條件)

 

更新單條:

UPDATE dbtab FROM wa.

系統(tǒng)將根據(jù)工作區(qū)中表關(guān)鍵字段primary key(而不是內(nèi)表行的關(guān)鍵字段)的值定位數(shù)據(jù)行,并使用所有非關(guān)鍵字段的值將該行進行更新。

工作區(qū)wa的寬度必須大于或等于數(shù)據(jù)庫表寬度,會按照數(shù)據(jù)庫表結(jié)構(gòu)從前往后來解析wa各字段,與名稱無關(guān)

如果數(shù)據(jù)庫中有一個wa中primary key相同的數(shù)據(jù),則SY-SUBRC為0,否則SY-SUBRC為4

 

或者:

TABLES:mard.UPDATE mard.

注:此方式不能動態(tài)指定表名

 

"CARRID 與 CONNID為spfli的主鍵

DATA wa TYPE spfli.MOVE 'AA' TOwa-carrid.MOVE '0064' TO wa-connid.MOVE 'WASHINGTON' TO wa-cityfrom.UPDATE spfli FROM wa.TABLES spfli.MOVE 'LH' TOspfli-carrid.MOVE '0017' TO spfli-connid.MOVE 'BERLIN' TO spfli-cityfrom.UPDATE spfli.

 

 

更新多行:

UPDATE dbtab FROM TABLE itab.

對于每一個內(nèi)表行,都根據(jù)表關(guān)鍵字段要更改的數(shù)據(jù),并更改其他非關(guān)鍵字段的值,如果所有內(nèi)表行都更新成功,SY-SUBRC返回0,只要有一條未成功,則返回4(但沒有問題的數(shù)據(jù)行還是會被更新)。SY-DBCNT存儲了被修改的行數(shù)。如果內(nèi)表itab為空,則SY-SUBRC and SY-DBCNT都會為0。

 

"CARRID 與 CONNID為spfli的主鍵

DATA:itab TYPE HASHED TABLE OF spfli WITH UNIQUE KEY carrid connid,      wa LIKE LINE OF itab.wa-carrid = 'UA'.wa-connid = '0011'.wa-cityfrom = 'ZH'.INSERT wa INTO TABLEitab.wa-carrid = 'LH'.wa-connid = '1245'.wa-cityfrom = 'EN'.INSERT wa INTO TABLEitab.UPDATE spfli FROM TABLEitab.

 

更新指定列:

UPDATE dbtab SET f1 = g1 … fi = gi WHERE<conditions>.

WHERE子句后面可以是所有表關(guān)鍵字段,也可以不是,但如果只是更新一條,則條件需要使用所有表關(guān)鍵字段。SET子句中只能為非關(guān)鍵字段。對于數(shù)據(jù)字段,除 f = g 外,還可以使用 f = f + g、f = f - g兩種形式在該字段原有值基礎(chǔ)上增減。如果至少有一條數(shù)據(jù)被更新,則SY-SUBRC返回0,否則返回4。SY-DBCNT中存儲了修改的行數(shù)

 

注:此種方式不能動態(tài)指定表

UPDATE sflight  SET planetype = 'A310' price = price - '100.00'  WHERE carrid = 'LH' AND connid= '0402'.

DELETE

DELETE { {FROM {dbtab|(dbtab_syntax)} [CLIENT SPECIFIED] [WHERE sql_cond]} 

|{{dbtab|(dbtab_syntax)} [CLIENT SPECIFIED]FROM wa|{TABLE itab}} }.

 

sql_cond:請參考SELECT語句中的WHERE從句用法(但不適用FOR ALL ENTRIES條件)

 

刪除單行

DELETEdbtab FROM wa.

從數(shù)據(jù)庫表中刪除表關(guān)鍵字段與工作區(qū)wa中相應(yīng)字段相同的行。工作區(qū)的長度至少要等于數(shù)據(jù)庫表的產(chǎn)關(guān)鍵字段長度。

如果數(shù)據(jù)庫中存在這樣的數(shù)據(jù),則SY-SUBRC為0,否則SY-SUBRC為4

 

或者省略wa:

TABLES:mard.DELETE mard.

注:此方式不能動態(tài)指定表名

 

"CARRID 與 CONNID為spfli的主鍵DATA: BEGIN OFwa,  carrid TYPE spfli-carrid,  connid TYPE spfli-connid,END OF wa.MOVE 'AA' TOwa-carrid.MOVE '0064' TO wa-connid.DELETE spfli FROM wa.TABLES spfli.MOVE 'LH' TOspfli-carrid.MOVE '0017' TO spfli-connid.DELETE spfli.

 

刪除多行

DELETE dbtab FROM TABLE itab.

根據(jù)表主鍵來刪除itab中相同的數(shù)據(jù)行

如果所有行都被刪除,SY-SUBRC為0,否則為4。SY-DBCNT存儲了被刪除的條數(shù)。如果內(nèi)表itab為空,則SY-SUBRC 與 SY-DBCNT都為0。

"CARRID 與 CONNID為spfli的主鍵DATA: BEGIN OFwa,  carrid TYPE spfli-carrid,  connid TYPE spfli-connid,END OF wa,  itab LIKE HASHED TABLE OF wa WITH UNIQUE KEY carrid connid.wa-carrid = 'UA'. wa-connid = '0011'.INSERT wa INTO TABLEitab.wa-carrid = 'LH'. wa-connid = '1245'.INSERT wa INTO TABLEitab.DELETE spfli FROM TABLEitab.

 

刪除單行或多行

DELETE FROM dbtab WHERE<conditions>.

If at least one line is deleted, the system sets SY-SUBRC to 0, otherwise to 4. SY-DBCNTcontains the number of lines deleted.

 

DELETE FROM sflight WHERE planetype = 'A310'AND carrid = 'LH'.

MODIFY(插入或修改)

MODIFY {dbtab|(dbtab_syntax)} [CLIENT SPECIFIED]FROM wa|{TABLE itab}.

MODIFY相當(dāng)于INSERT與UPDATE的結(jié)合。當(dāng)使用MODIFY語句操作數(shù)據(jù)庫時,如果程序中指定的數(shù)據(jù)行已經(jīng)存在數(shù)據(jù)庫中(根據(jù)表關(guān)鍵字判斷)則對其進行更新操作,如果不存在,則進行插入操作。

 

插入或更新單行

MODIFY dbtabFROM wa.

根據(jù)工作區(qū)wa中的表關(guān)鍵字段來定位要修改的數(shù)據(jù),如果不存在,則插入。工作區(qū)wa的寬度也要大于或等于表結(jié)構(gòu)的所有字段表寬度

 

MODIFY<dbtab>.

SY-SUBRC總是為0

 

 

插入或更新多行

MODIFY dbtab FROM TABLE itab.

根據(jù)內(nèi)表中的每一行表關(guān)鍵字段來查找數(shù)據(jù)是否存在,如果不存,則會插入。

SY-SUBRC總是為0,SY-DBCNT為內(nèi)表行數(shù)

其他技術(shù)

使用表工作區(qū)Interface work areas

表工作區(qū)是接口工作區(qū)的一種,使用TABLES語句聲明:

TABLES dbtab.

該語句會根據(jù)數(shù)據(jù)庫中(或視圖、或ABAP Dictionary中定義的structure)名為dbtab的表來創(chuàng)建一個同名的結(jié)構(gòu),組成該結(jié)構(gòu)的內(nèi)表字段類型與參考的表(或視圖、structure)相同。

在4.0版以前,使用Open SQL訪問表時,一定要先使用該語句來聲明Interface work areas,現(xiàn)在不需要了,但是,你仍然需要使用該語句來使屏幕input/output字段參考相應(yīng)的數(shù)據(jù)庫表,在PBO事件里,ABAP程序會將字段內(nèi)容傳遞到相應(yīng)的屏幕字段中,在PAI事件時,屏幕上的字段會存儲到ABAP程序中對應(yīng)Interface work areas中的相應(yīng)字段中(具體可以參照《User Dialogs.docx》中的<示例:屏幕元素自動參考數(shù)據(jù)詞典>章節(jié))。

image193

 

在指定了表工作區(qū)之后,在使用SELECTSINGLE語句時可以省略INTO子句(INTO到TABLE時不能省略),系統(tǒng)默認將數(shù)據(jù)行讀取到同名變量的表工作區(qū)中。

TABLES spfli.SELECT SINGLE *FROM  spfli WHERE cityfrom ='NEW YORK'.WRITE: spfli-cityto.

操作時間分析(類似System.currentTimeMillis()方法)

GET RUN TIME FIELD <f>.

其中f應(yīng)為I類型的字段,系統(tǒng)返回從程序開始后的毫秒數(shù)。

DATA: t1 TYPE i,      t2 TYPE i,      t TYPE i.GET RUN TIME FIELD t1.TABLES: spfli.SELECT SINGLE *FROM  spfli CLIENT SPECIFIED WHERE mandtBETWEEN '100' AND '999'.GET RUN TIME FIELD t2.t = t2 - t1.WRITE: / t.

 

如果需要全面性能分析,可以使用SE30

數(shù)據(jù)庫優(yōu)化

1、 優(yōu)先使用多表聯(lián)接,不使用內(nèi)嵌Select

2、 Joins方式聯(lián)合查詢不會使用到緩存,所以盡量少用,可以使用ABAP Dictionary view來替換。創(chuàng)建ABAP Dictionary view來代替從物理表中讀取

3、 使用內(nèi)表FOR ALL ENTRIES查詢選項代替內(nèi)嵌Select。FOR ALL ENTRIES是一種與聯(lián)結(jié)和數(shù)據(jù)庫視圖相似的多表操作方式,但是其性能不如聯(lián)結(jié)和數(shù)據(jù)庫視圖好。

4、 INSERT, UPDATE, and DELETE時,使用內(nèi)表的方式來減少與數(shù)據(jù)庫交互次數(shù)

5、 使用游標讀取數(shù)據(jù),這樣省掉了將從數(shù)據(jù)庫中的取記錄放入內(nèi)表的INTO語句這一過程開銷。

6、 避免全表掃描,在WHERE orHAVING從句中使用索引字段進行查詢。

R/3 System會自動為primary index(主鍵索引,也叫第一索引)創(chuàng)建UNIQUE主鍵索引。如果在WHERE orHAVING從句中未使用到primary index fields,則不會使用到主鍵索引。此時可以通過ABAP Dictionary來創(chuàng)建第二索引(可以是unique的,也可以是非唯一索引)

在創(chuàng)建索引時,索引字段不能在其他索引中使用過(即索引字段不要重疊),否則性能會很差。另外,只能那些經(jīng)常讀取的表進行創(chuàng)建索引,而那些經(jīng)常需要更新的表,則不適合創(chuàng)建索引,因為在數(shù)據(jù)更新時同時會更新索引。最后,索引創(chuàng)建時不多于4個字段,一個表上的創(chuàng)建的索引不要超過5個。

在需要經(jīng)常訪問的字段上創(chuàng)建索引,并且將重復(fù)數(shù)據(jù)最少的字段放在索引最開頭的規(guī)則來確定索引中字段順序。要在重復(fù)率少的字段上創(chuàng)建索引,而不應(yīng)該在重復(fù)率高的字段上創(chuàng)建索引

 

7、 除了主鍵字段,如果一個表的某些字段被SELECT語句頻繁訪問,則考慮基于這些字段建立第二索引。注:一個表的不是越多越好,使用創(chuàng)建不當(dāng)?shù)牡诙饕M行查詢可能導(dǎo)致比不使用該索引進行查詢更差的性能

 

 

8、 組成索引的所有字段都要用到,并且使用的是“=”表達式,而且各個表達式使用“AND”連接時,查找效率會最高。

9、 在條件從句中不要使用否定的邏輯表達式,如NE(<>)、NOT LIKE,因為這樣數(shù)據(jù)庫不會使用索引,所以要使用肯定操作比較操作符,如EQ、LIKE。另外,如果可能,避免在WHERE從句中使用NOT操作符,因為數(shù)據(jù)庫不會用到索引。

10、      不要使用OR來連接多個索引字段表達式,OR后面的表達式中的字段將不會用到索引,看是否能使用IN操作符轉(zhuǎn)換

11、      使用部分索引要注意的問題:如果一個索引是由多個字段組成的,你可以只使用一部分字段來進行查詢時,也可以使用到索引,但使用時要注意要按照索引定義的順序來使用,如定義時為 a,b,c,d,e 五個字段組成的索引,當(dāng)使用c,d來查詢時,查詢條件前面也一定要帶上a,b查詢條件字段,所以當(dāng)只按c,d兩個字段查詢,是用不到索引的(好像只要按物理順序?qū)懀强梢杂玫剿饕模浚浚浚?/p>

12、      在WHERE條件語句中,要將索引字段條件寫在最前面(左邊),非索引字段寫在最后面,這樣查詢時效率會高些

13、      最好不要將允許為NULL值的字段作為索引字段,因為某些數(shù)據(jù)庫不會將NULL值存儲到索引表中。

14、      一般不要使用ORDER BY,除非ORDER BY所使用的索引與WHERE語句所使用的索引一樣。此時可以將數(shù)據(jù)讀到內(nèi)表后,對內(nèi)表進行排序

 

image194

 

image195

 

image196

image197

image198

image199

image200

image201

image202

image203

image204

 

 

 

使用Buffer Tables

你可以通過訪問服務(wù)器上的Buffer Tables來最大限度的減少訪問數(shù)據(jù)的時間。

是否是緩存表,可以在ABAP Dictionary中來配置:

 

表的三種緩沖類型:

l  Partial buffering (單記錄緩存single entry) :從數(shù)據(jù)庫中僅讀取一條數(shù)據(jù)并存儲到table buffer 中。此緩存只對SELECT SINGLE…語句起作用,如果不是則繞過單記錄緩存區(qū),直接訪問數(shù)據(jù)庫表。

image205

l  Generic buffering(普通緩存,區(qū)域緩存):在此種情況下,你需要在指定一個generic key (由部分或全部關(guān)鍵字段組。如果主鍵是由一個字段構(gòu)成,則不能選擇此類型緩存。下面的generic key為前面三個主鍵:MANDT、CARRID、COUNTNUM) 。表的內(nèi)容會被劃分到相應(yīng)的generic areas中(根據(jù)WHERE條件中使用的主鍵字段),當(dāng)你使用generic keys進行數(shù)據(jù)訪問時,則屬于此generic area的整片數(shù)據(jù)都會被加載到table buffer中。客戶特定的表一般根據(jù)client來緩存。此類型的緩存需注意:

1、  查詢時如果使用BYPASSING BUFFER 選項,除了繞過緩存直接到數(shù)據(jù)庫查詢外,查詢出來的數(shù)據(jù)也不會放入緩存。

2、  只要查詢條件中出現(xiàn)了用作緩存區(qū)域的所有字段(generic key),則查詢出所有滿足generic key的所有數(shù)據(jù),然后進行緩存。

3、  如果查詢條件中g(shù)eneric key只出現(xiàn)某個或者某部分,則不會進行緩存操作。

4、  如果主鍵是只由一個字段組成,則不能設(shè)定為此種緩存。

5、  如果有MANDT字段,則為generic key的第一個字段(注:在創(chuàng)建表時,MANDT只能是第一個字段,否則不起作用)

image206

將相關(guān)的數(shù)據(jù)放入Buffer,至于將哪些數(shù)據(jù)放入,則根據(jù)設(shè)定的generic key為條件。

 

image207

image208

 

l  Resident(常駐) buffering (全部緩存100%) The first time the table is accessed, its entire(整個) contents are loaded in the table buffer.(在第一次讀取表數(shù)據(jù)時,會將整個表的數(shù)據(jù)都會緩存下來,不管WHERE條件,都會將整個表緩存起來)

image209

 

當(dāng)從一個具有緩沖功能的表讀取數(shù)據(jù)時,以下過程會發(fā)生:

1.      ABAP program從buffered table中讀取數(shù)據(jù)

2.      ABAP processor 解析Open SQL 語句。如果查詢的表配置了綏中,ABAP processor 則會在服務(wù)器上檢查local buffer ,看查詢的數(shù)據(jù)是否已緩存

3.      如果查詢的數(shù)據(jù)沒有被緩存,將會去查詢數(shù)據(jù)庫。如果存在,則將滿足條件的數(shù)據(jù)返回到程序中。

4.      數(shù)據(jù)服務(wù)器會將數(shù)據(jù)傳送到SAP應(yīng)用服務(wù)器,并將它緩存下來

5.      將查找到的數(shù)據(jù)返回到應(yīng)用程序

 

當(dāng)修改一個具有緩沖功能的表時,以下動作會發(fā)生:

1.      數(shù)據(jù)庫表與SAP應(yīng)用服務(wù)器上的緩沖會被更新。數(shù)據(jù)庫接口(database interface)記錄修改日志到table DDLOG表中(Buffer Synchronization表)。如果系統(tǒng)不只有一個application server,其他的服務(wù)器上的緩存并不會立即更新。

2.      所有的應(yīng)用服務(wù)器會定期的讀取table DDLOG,根據(jù)該表中的日志來更新緩存。掃描的間隔與buffering type有關(guān),在分布式系統(tǒng)中,同步時間為60 seconds

3.      在未同步的應(yīng)用服務(wù)上,用戶讀取的數(shù)據(jù)是舊的。該數(shù)據(jù)直到下次緩存同步時才認為過期。

 

適合使用緩存的表:

1.      頻繁讀取的表

2.      很少修改的表

3.      相對小的表(few lines, few columns, or short columns)

4.      延遲更新可接受的表

 

SELECT 語句在下列方式不會使用到緩存:

1.      在FROM從句中使用了BYPASSING BUFFER 選項

2.      在SELECT從句中使用了DISTINCT選項

3.      在SELECT從句使用Aggregateexpressions

4.      FROM從句中使用了join

5.      WHERE從句中使用了IS NULL條件

6.      WHERE從句中使用了Subqueries(子查詢)

7.      使用了ORDER BY從句(如果排序的字段是主鍵,則還是會使用緩存)

8.      使用了GROUP BY從句

9.      使用了FOR UPDATE選項(經(jīng)測試,好像還是會用到緩存,但FOR UPDATE是要依靠數(shù)據(jù)庫系統(tǒng)本身來加鎖的,但明確的指定繞過緩存選項又不支持:SELECT SINGLE FOR UPDATE… BYPASSING BUFFER… 這樣的語句又不支持)

10.    另外,所有的Native SQL 語句不會使用到緩存

原文出自 SAP師太技術(shù)博客,博客鏈接:www.cnblogs.com/jiangzhengjun
上一篇:Linux手動安裝sbt步驟

下一篇:Native SQL

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 安顺市| 林周县| 鄯善县| 恩平市| 永康市| 凤山县| 云梦县| 英超| 正阳县| 辰溪县| 白山市| 景德镇市| 杂多县| 大兴区| 垦利县| 阿拉尔市| 九龙县| 左权县| 自贡市| 图片| 松江区| 湘潭县| 闽侯县| 古交市| 安岳县| 滨海县| 禹州市| 蓬溪县| 沾益县| 衡阳县| 公主岭市| 乐山市| 昆明市| 开化县| 井研县| 杭锦后旗| 洛川县| 常熟市| 南岸区| 油尖旺区| 友谊县|