關於SAP ABAP字元變數和字串變數字元個數的一個知識點,和一個血案
今天是2020年5月2日,五一國際勞動節小長假的第二天。讓我們繼續勞動起來。
使用ABAP strlen函式計算下列這4個字元和字串變數中包含的字元個數。
大家先別急著滑動螢幕,先試著自己計算一下,看和標準答案是否有出入。也許大家覺得這些小的知識點沒什麼用,但Jerry馬上會分享一個我實際處理過的客戶incident,正是由於類似這種看似不起眼的小知識點沒有留意,最後影響了專案進展。
正確答案,依次是:
- 2
- 1
- 19
- 17
逐一解釋。
strlen( lv_s ) = 2
整型變數的值,整數1,賦給字串變數lv_s, 這裡發生一個隱式型別轉換。
SAP幫助文件裡宣告,整型變數賦給字串變數時,如果整數為負數,則字串變數末尾為"-";如果整數為正數,則字串變數末尾為空白字元。換言之,當整型變數到字串變數的隱式型別轉換髮生時,字串變數末尾會多出一位,代表賦值源頭的整型數的符號位。
lv_s多出來的這個空白字元在偵錯程式裡看得很清楚,2000正是空白字元的16進位制編碼。同時偵錯程式裡也能看到lv_s的字串個數為2.
strlen( lv_s2 ) = 1
和前一例相比,lv_s2的複製操作沒有出現隱式型別轉換,而是直接被賦以了一個字元常量,故字元個數為1.
strlen( lv_ss) = 19
lv_ss的型別為SSTRING,實際就是一個CHAR20:
在偵錯程式裡,lv_ss有18個前導空白(leading blank)字元,字元"1"和1個尾部空白(trailing blank)字元組成,總共20個字元,偵錯程式裡的Technical Type顯示為C(20).
那為什麼strlen(lv_ss)不等於20,而等於19?SAP幫助文件裡給出了答案——SSTRING即CHAR20這種變數,屬於固定長度(fixed length)型別變數。當使用strlen函式計算這種變數的字串個數時,尾部空白字元不應參加計數,所以要減一。
strlen( lv_s3) = 17
有了例三的基礎,這個就很容易了。變數lv_s3型別是CHAR18,屬於固定長度型別變數,因此strlen計算出的字串個數為18 - 1 = 17.
第一個例子中,我們把一個整數直接賦給了一個字串變數,發生了隱式型別轉換。在實際專案中,這種隱式型別轉換很容易出現在函式或者ABAP類方法的引數傳遞中。對於函式或ABAP類方法的形式引數,如果我們傳遞的實際引數型別和其型別不匹配,就會發生隱式型別轉換,這種自動轉換有時並非我們期望發生的,甚至容易被忽略。
看一個真實的例子。我曾經擔任過一個俄羅斯的SAP CRM客戶專案的Dev Angel,收到過一個效能相關的incident,客戶開啟某個UI的速度極其緩慢,甚至經常超時。
我透過除錯,最終發現罪魁禍首位於下段程式碼。該程式碼從SAP CRM發起RFC呼叫,去SAP ERP讀取資料,Max Hit設定為15,意思是期望ERP端至多返回15條記錄。
然而從ERP端返回了總共408093條記錄。顯然,雖然透過硬編碼指定Max Hit為15,卻完全沒有起到限制作用。
起初我想當然地認為這是ERP函式的bug,沒有正確處理CRM呼叫端傳遞過來的Max Hit. 然而當我在偵錯程式裡單步執行到CRM函式內部檢視iv_max_entries時,一下傻了眼:
它的值從15一下變成了3473457. 這個數字是什麼鬼?!
再看函式的形式引數定義,iv_max_entries型別為整型,而二次開發顧問傳入的硬編碼值'15', 是一個字元值,我頓時恍然大悟。
'15'是怎麼變成魔幻數字3473457的?
Jerry先不解釋,而是請大家看下面這段程式碼:
執行,正好輸出3473457這個魔幻數字。那麼程式碼第四行31003500是哪裡來的?其實就是字串'15'的十六進位制編碼。
也就是說,二次開發顧問在RFC呼叫時,將硬編碼的'15'傳給了接受整型變數的函式引數IV_MAX_ENTRIES. 應該該引數型別為整型,所以'15'的十六進位制編碼'31003500'被自動轉換成了對應的整型數3473457. 顯然這不是開發顧問期望的行為,但因為程式能夠繼續執行,所以這個問題暫時被掩蓋了。
而RFC呼叫完成之後,緊接著是一個巢狀的LOOP. 在Max Hit能按照期望工作的前提下,對於最多包含15條記錄的內表,就算進行巢狀的LOOP操作也能很快完成。但如今因為Max Hit不工作,內表記錄從最多15條一下子變成了超過40萬條,在這麼龐大規模的內表上進行巢狀LOOP操作,效能可想而知。
經歷過這次incident的處理之後,我個人覺得,使用隱式型別轉換的最佳實踐就是根本不去用它。程式設計師在工作的時候,必須時刻清醒地知道自己在做什麼,要扼住編譯器的咽喉,而不要被編譯器扼住了咽喉。
感謝閱讀,祝大家五一節快樂。
要獲取更多Jerry的原創文章,請關注公眾號"汪子熙":
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24475491/viewspace-2689685/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SAP ABAP 字串變數容易疏忽和混淆的一些知識點試讀版字串變數
- 統計字串字元個數字串字元
- js 字串中取得第一個字元和最後一個字元JS字串字元
- 獲取一個字串中出現最多的字元和他的個數字串字元
- 關於ThreadLocal變數的一個坑thread變數
- javascript中關於value的一個小知識點(value既是屬性也是變數)JavaScript變數
- 關於例項變數和靜態變數的一點疑問變數
- 記錄一個關於變數命名的事情變數
- C語言sizeof()變數、字元、字串C語言變數字元字串
- (字串動態規劃)一個字串變成另一個字串的步驟數字串動態規劃
- Octave 數字轉字元,連線兩個字串,以及如何將字串轉換為變數名稱字元字串變數
- javascript檢測一個變數是否為數字或者數字字串JavaScript變數字串
- ABAP 程式碼中,哪些特殊字元不能用於變數命名?字元變數
- js如何計算一個字元在字串中出現的次數JS字元字串
- . 【JAVA】給定任意 字串"yekmaakkccekymbvb",求出字串中有多少種字元,以及每個字元的個數?Java字串字元
- 040統計數字字元的個數字元
- js如何判斷一個變數是否是一個數字JS變數
- js如何判斷一個變數是數字還是數字字串JS變數字串
- 華納雲:linux怎麼將一個變數賦給另一個變數Linux變數
- JavaScript統計字串中重複字元的個數JavaScript字串字元
- 第一個CSS變數:currentColorCSS變數
- 繫結變數的一個例子變數
- 關於 JavaScript 字串的一個小知識JavaScript字串
- 將一個字串中含有全形的數字字元、字母、空格或'%+-()'字元轉換為相應半形字元字串字元
- 關於range的一個知識點
- js判斷一個變數是否為字串型別JS變數字串型別
- 寫一個函式,輸入一個4位數字,要求輸出這4個數字字元函式字元
- 1374 生成每種字元都是奇數個的字串字元字串
- 如何計算字串某個字元出現的次數字串字元
- 統計字串中某個字元出現的次數字串字元
- linux shell組合多個變數為一個新變數並執行Linux變數
- javascript判斷一個變數是否是數字JavaScript變數
- 利用HashMap統計字元個數HashMap字元
- 用python3統計一行字元中的英文字母,空格,數字和其他字元的個數Python字元
- Js基礎知識(一) – 變數JS變數
- isAlnum判斷字元是否為字母數字字元(字母和數字都屬於字母數字字元)字元
- 輸出字串中出現次數最多的字元和次數字串字元
- 得到字串 位元組 長度 中文 兩個字元 英文一個字元字串字元