For all entries使用中注意的問題

對於不能join的表,使用for all entries in語句將該表與內表串聯。

SELECT bseg~kunnr

       bseg~lifnr     

       bseg~belnr

INTO TABLE itab_bseg

FROM bseg

   FOR ALL ENTRIES IN itab_main

WHERE bukrs in _bukrs

and ( belnr = itab_main-belnr

    AND hkont = itab_main-hkont ).

由於BSEG不能和BSISinner join所以先將BSIS內容放到itab_main 中,然後用 FOR ALL ENTRIES IN來串聯。

1-WHERE子句中的bukrs in _bukrs是指bseg-bukrs存在於_bukrs這個select-options中,_bukrs不是itab_mainfield所以這部分不包括在括號中.

當然會增加內存使用了。
原本一個條件,數次(驅動表的紀錄條數)向對DB操作,
使用了FOR ALL ENTRIES後,
相當於把驅動表裏的條件字段的所有值用OR 連起來,
一次對DB操作,
條件語句增大,勢必使內存佔用增多。

 

1SELECT CARRID

         CONNID

         PRICE

    FROM SFLIGHT

    INTO TABLE IT_PRICE

     FOR ALL ENTRIES IN IT_SFLIGHT

   WHERE CARRID = IT_SFLIGHT-CARRID

     AND CONNID = IT_SFLIGHT-CONNID'.

WHERE 條件中,IT_SFLIGHT-CARRIDIT_SFLIGHT-CONNID這些列將用作佔位符。該 SELECT 語句的結果集是 SELECT 語句的所有結果集的聯合,這些結果集是用內部表 IT_SFLIGHT 中的相應值在每一行上替換佔位符的結果。實際上該WHERE子句的特殊變式就是下面WHERE基本語句的簡略寫法。

SELECT DISTINCT CARRID

                  CONNID

                  PRICE

    FROM SFLIGHT

    INTO TABLE IT_PRICE

   WHERE ( CARRID = 'LH'   AND

           CONNID = '2415' ) OR

         ( CARRID = 'SQ'   AND

           CONNID = '0026' ) OR

         ( CARRID = 'LH'   AND

           CONNID = '0400' ) .

2使用該語句,對於最後得出的結果集系統會自動刪除重複行。因此如果你要保留重複行記錄時,記得在SELECT語句中添加足夠鍵值項目(有必要時,增加全部鍵值項目),以保證結果集中所需重複項目不會被刪除。(例如選取支付金額時,支付事件可能不同,但金額可能相同,此時一定要注意,以避免錯誤刪除結果記錄。)

3FOR ALL ENTRIES IN後面使用的內部表itab如果爲空,系統將視爲無條件選取,將當前CLIENT下所有記錄選出。因此爲避免無意義的全件檢索,在使用該語句前一定要判斷內部表itab是否爲空,爲空時不執行包含該語句的數據庫檢索處理。

4.由於itab-f實際上是作爲佔位符被替換,所以內部表itab中不要包含HEADER行(項目標識名稱行),以免造成混淆,檢索出錯。

5.內部表itab中作爲條件替換用項目的類型和長度,一定要和檢索數據庫中對應的項目相同,否則編譯不能通過。

6.對於內部表itab中作爲條件替換用項目,不能使用LIKE,BETWEEN,IN比較操作符。因爲這些比較操作符都是不確定比較操作符(將選擇條件設定在一個範圍內),而FOR ALL ENTRIES IN語句的作用相當於將選擇條件塊全部並列開來,用OR連接,如果每個OR分支中又是不確定的範圍,那麼系統性能將大大降低,因此R/3系統在使用該語句時禁止使用不確定比較操作符。

7.使用該語句時,ORDER BY語句和HAVING語句將不能使用。

8.使用該語句時,除COUNT( * )以外的所有合計函數(MAX,MIN,AVG,SUM)都不能使用。

//判斷內表是否爲空

使用語句: DESCRIBE TABLE ITAB LINES VARIABLE.判斷系統變量sy-subrc是否爲0,如果爲0就表示不空,反之爲空!
DESCRIBE TABLE ITAB LINES VARIABLE

IF NOT P_VARIANT IS INITIAL.
   
WX_VARIANT-VARIANT = P_VARIANT.

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

 

一、Select語句中使用FOR ALL ENTRIES IN需要注意的問題
ABAP編程中使用for all entries in 是必不可少的語句相信大家都使用過例如

data: begin of ig_bseg occurs 0,
          werks like bseg-werks,
          belnr  like bseg-belnr,
          gjahr  like bseg-gjahr,
          dmbtr like bseg-dmbtr,
        end of ig_mseg.
if not ig_bkpf[] is initial.
  select werks belnr gjahr dmbtr into corresponding fields of table ig_bseg
  from bseg for all entries in ig_bkpf
  where werks = ig_bkpf-werks and belnr = ig_bkpf-belnr and  gjahr = ig_bkpf-gjahr.
endif.


需要注意以下問題
1
、首先,必須要判斷For all entries in後面的內表是否爲空,如果它爲空的話,那麼在where條件中的與內表中字段進行比較的結果全部爲真,也就是全部滿足條件,這會導致取出非常多的數據,極大地影響系統的性能。
2
、對於上例,按照邏輯分析可以取出某個憑證的所有行項目,但是實際情況會與你預期的不一致,如果某個憑證的多個行項目的dmbtr值是完全一樣的,那麼在內表ig_bseg中你只會得到一行記錄,而不是多行,它自動使用了distinct,或者說刪除了重複的行,這是個非常致命的問題,會導致你的程序邏輯錯誤,而且很難以查找,解決的辦法就是要保證內表ig_bseg中取出的數據必須要有主鍵字段,在本例中,需要再添加buzei字段。

二、自建表和從系統外導入數據需要注意的問題
1
、自建表中建立文本類型的字段(自己創建domain)時,需要注意是否允許字段可以保留文本的大小寫狀態,否則默認會全部轉換爲大寫字母。
2
對於各種憑證編碼字段,如:物料憑證mblnrkunnrlifnrbelnr,在導入數據到自建表中時,一定要注意前導0的補充問題,否則導入的數據可能沒有前導0,補充前導0的函數爲CONVERSION_EXIT_ALPHA_INPUT,另外,在建立自建表時,將該字段對應的domainConvers. routine:設置爲ALPHA

 

補充,就是覺得這個用於數據少的內表合適,雖然是說一下子從數據庫裏拿數據,連接數據庫次數少了,可是對數據庫造成的負擔較大。

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

 

Duplicates are discarded from the result set. If the internal table itab does not contain any entries, the system treats the statement as though there were no WHERE cond condition, and selects all records.

使用FOR ALL ENTRIES的時候,取出的字段一定要包括表的主鍵,這樣就沒有問題了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章