Former Member
February 25, 2014 3 minute read
Alternative to READ_TEXT Function Module (No more FM needed)
554289,736
Hello everyone!
This one is for all of those and me too. Most of the posts I have seen on SDN where people asking for alternative READ_TEXT alternative fuvtion module for read_text | SCN or mass usage of READ_TEXT. Some good or better developers – I must say – are worried about performance issues. Few newbies are still looking for the usage of READ_TEXT. Lol. FM – READ_TEXT issue with data declaration | SCN
I was also looking for some alternate solution but all in vain. I found one good wiki about the usage of the FM: Function Example READ_TEXT ABAP wrapper function – Enterprise Information Management – SCN Wiki. This one is great but obviously I have two main concerns. 1. Performance, 2. Mass usage of reading long text of any object. There is another way to achieve mass read of long text by looping the READ_TEXT (lol, that’s funny), I don’t need this either because I need performance. I don’t want Basis guys cursing me!
So, what I came with was to avoid READ_TEXT, now the question is HOW? You might think of a big NO! Not possible! But remember
Lots of time people say no when they don’t know.
Let me assure you one thing I have done this and it is ready working like a charm.
All you need to do is just fetch the data, first from STXH then from the line item table STXL. Only question left is how to decompress the long text? Well, that’s pretty easy and not a big deal all you need is the use of IMPORT statement.
Now let’s see what we have to and how to do it? Below is the code that’s is working 4 to 5 times faster than READ_TEXT performance and is as simple as anything!
*&---------------------------------------------------------------------*
*& Report ZMA_READ_TEXT
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT ZMA_READ_TEXT.TYPES: BEGIN OF TY_STXL,TDNAME TYPE STXL-TDNAME,
CLUSTR TYPE STXL-CLUSTR,
CLUSTD TYPE STXL-CLUSTD,
END OF TY_STXL.DATA: T_STXL TYPE STANDARD TABLE OF TY_STXL.FIELD-SYMBOLS: <STXL> TYPE TY_STXL.
• compressed text data without text name
TYPES: BEGIN OF TY_STXL_RAW,CLUSTR TYPE STXL-CLUSTR,
CLUSTD TYPE STXL-CLUSTD,
END OF TY_STXL_RAW.DATA: T_STXL_RAW TYPE STANDARD TABLE OF TY_STXL_RAW.DATA: W_STXL_RAW TYPE TY_STXL_RAW.• decompressed text
DATA: T_TLINE TYPE STANDARD TABLE OF TLINE.FIELD-SYMBOLS: <TLINE> TYPE TLINE.
DATA: T_STXH TYPE STANDARD TABLE OF STXH,W_STXH TYPE STXH.
SELECT TDNAME TDOBJECT TDIDFROM STXH
INTO CORRESPONDING FIELDS OF TABLE T_STXH.
*AND THEN
• select compressed text lines in blocks of 3000 (adjustable)
SELECT TDNAME CLUSTR CLUSTDINTO TABLE T_STXL
FROM STXL
PACKAGE SIZE 3000
FOR ALL ENTRIES IN T_STXH "WITH APPLICATION DATA AND TDNAME
WHERE RELID = 'TX' "standard text
AND TDOBJECT = T_STXH-TDOBJECT
AND TDNAME = T_STXH-TDNAME
AND TDID = T_STXH-TDID
AND TDSPRAS = SY-LANGU.
LOOP AT T_STXL ASSIGNING <STXL>.• decompress text
CLEAR: T_STXL_RAW[], T_TLINE[].
W_STXL_RAW-CLUSTR = <STXL>-CLUSTR.
W_STXL_RAW-CLUSTD = <STXL>-CLUSTD.
APPEND W_STXL_RAW TO T_STXL_RAW.IMPORT TLINE = T_TLINE FROM INTERNAL TABLE T_STXL_RAW.
• access text lines for further processing
LOOP AT T_TLINE ASSIGNING <TLINE>.WRITE: / <TLINE>-TDLINE.ENDLOOP.ENDLOOP.FREE T_STXL.
ENDSELECT.Here is the output: I have not restricted it to any object (obviously you can do it for your need) and boy it pulls more then 1300 records within a nano second!
Boom!!
There is another Function Module to fetch multiple texts: RETRIEVAL_MULTIPLE_TEXTS but I haven’t used it.
Now the last thing, I want to thank Mr. Julian Phillips and Mr. Thomas Zloch. Thankful to Julian because he posted and Thomas gave the solution. Same solution I implemented with some additions. Here is the post I referred to: Mass reading standard texts (STXH, STXL)
I hope you will reuse this code to fetch multiple long text and your comments, suggestions and complaints are welcome!
Note: Sourcecode attached!
以下内容整理自 SAP 官方 ABAP 速查表(主题:Built-In Functions),作为本文的扩展补充资料。
This ABAP cheat sheet includes a variety of built-in functions in ABAP, along with code snippets to demonstrate their functionality. Many of the functions covered here are also included in other ABAP cheat sheets that focus on specific topics.
ABAP offers a range of predefined built-in functions for different purposes. These include numeric functions for calculating numeric values, string functions for processing strings, table functions for working with internal tables, and more.
The functions can have one argument, which is a data object or an expression whose content is passed, or they can have multiple arguments, some of which may be optional in certain cases. Each function has a specific return value and can be specified in different positions.
Built-in functions are also available in ABAP SQL and ABAP CDS.
[!NOTE] - For more detailed information, refer to the topics linked in the More Information section. - Avoid naming your methods the same as built-in functions within classes. Otherwise, the methods will "hide" the built-in functions. - The examples in the ABAP cheat sheet are not comprehensive in terms of functions covered, syntax options and parameters used. Always refer to the ABAP Keyword Documentation for more details. - Disclaimer
[!NOTE] - Logical functions in ABAP return a truth value, either true or false. They are primarily used in logical expressions, for example, in control statements likeIF ... ELSE ... ENDIF, and other statements that involve conditions. - Note that ABAP does not have a Boolean data type for truth values, nor does it support Boolean data objects. Instead, thexsdboolfunction can be used to represent truth values in various situations where theabap_booltype from theabaptype pool, i.e. the valuesabap_true('X') andabap_false(''), is expected. - Many of the examples in this section utilize thexsdboolfunction to visualize the truth value, rather than usingIFcontrol structures, for example. - For more information, see here.
| Function | Details/Code Snippet |
boolc | Boolean function that returns a truth value. In this case, it is a single-character value of type string. When true, it returns the string X. When false, it returns a blank. The result is not to be compared with abap_true and abap_false (because of c to string conversion). To get the technical type c (with the values 'X' and ''), you can use the xsdbool function. |
xsdbool | Boolean function that returns a truth value. Similar to boolc, it returns the value X for true, and a blank for false. Unlike boolc, the return value is of type c of length 1, and can be compared with abap_true and abap_false. |
containscontains_any_ofcontains_any_not_of |
|
matches | Comparing a search range of a value with a regular expression. More optional parameters are available (e.g. case, off, len). |
line_exists | Checking whether a line exists in an internal table. A table expression must be specified. |
| Function | Details/Code Snippet |
abssignceilfloortruncfracipow |
|
nminnmax | Numeric extremum functions that return the value of the largest or smallest of the passed arguments. |
acosasinatancossintancoshsinhtanhexploglog10sqrt | Regarding the details of the result and type conversion of floating point functions, refer to the ABAP Keyword Documentation. The following snippet shows a small selection. |
roundrescale | Rounding functions expect a decimal floating point number as argument. The return value is of type decfloat34. The functions can be used to round to decimal places and precisions. In addition, rounding rules can be specified. For more details, refer to the ABAP Keyword Documentation. |
factorialbinomial |
|
| Function | Details/Code Snippet |
numofcharstrlenxstrlen | For determining the length of a string, i.e. the number of characters contained in a string. |
cmincmax | Character-like extremum value functions return a string that contains the content of the smallest or biggest of a set of character-like arguments. |
findfind_endfind_any_offind_any_not_of | Search functions |
countcount_any_ofcount_any_not_of | Returning the number of all occurrences in a string |
distance | Returning the Levenshtein distance between two strings, which reflects their similarity |
repeat | Repeating strings as many times as specified |
condense | Condensing strings |
concat_lines_of | Concatenating internal tables into strings |
reverse | Reversing strings |
escape | Escaping special characters according to the specification in the format parameter. Suitable values for the format parameter (which expects a data object of type i) are available in the CL_ABAP_FORMAT class (the constants starting with E_). |
insert | Inserting strings |
match | Returning substrings that match regular expressions |
replace | Replacements in strings |
segment | Returning the occurrence of a segment that is defined by limits, which are not part of the segments. |
shift_leftshift_right | Shifting content |
substringsubstring_aftersubstring_beforesubstring_tosubstring_from | Processing substrings |
to_upperto_lowerfrom_mixedto_mixed | Transforming strings |
translate | Replacing characters |
| Function | Details/Code Snippet |
utclong_current | Retrieving UTC time stamps |
utclong_add | Adding values to time stamps |
utclong_diff | Calculating the time difference between the values of two time stamp fields |
[!NOTE] See the line_exists function in the Logical Functions section.
| Function | Details/Code Snippet |
lines | Returning the number of lines in internal tables |
line_index | Returning the number of the line found using table expressions with respect to the table index used |
[!NOTE] - The examples only demonstrate ABAP SQL statements. Refer to the ABAP Keyword Documentation for the complete picture. - As with the previous examples, the following examples showcase a variety of available functions. - The examples use typed literals to ensure appropriate types are used and to provide self-contained examples.
SELECT SINGLE
"Division, result rounded to an integer
"2
div( 4, 2 ) AS div,
"Division, 3rd argument: result is rounded to the specified
"number of decimals
"0.33
division( 1, 3, 2 ) AS division,
"Result is rounded to first greater integer
"2
ceil( decfloat34`1.333` ) AS ceil,
"Result is the remainder of division
"1
mod( 3, 2 ) AS mod,
"Largest integer value not greater than the specified value
"1
floor( decfloat34`1.333` ) AS floor,
"Returns the absolute number
"2
abs( int4`-2` ) AS abs,
"Result is rounded to the specified position after the decimal separator
"1.34
round( decfloat34`1.337`, 2 ) AS round
FROM zdemo_abap_carr
WHERE carrid = 'LH'
INTO @DATA(numeric_functions).SELECT SINGLE
carrid, "LH
carrname, "Lufthansa
url, "http://www.lufthansa.com
"Concatenates strings, ignores trailing blanks
"LHLufthansa
concat( carrid, carrname ) AS concat,
"Concatenates strings, number denotes the blanks that are inserted
"LH Lufthansa
concat_with_space( carrid, carrname, 1 ) AS concat_with_space,
"First letter of a word -> uppercase, all other letters -> lowercase;
"note that a space and other special characters means a new word.
"Http://Www.Lufthansa.Com
initcap( url ) AS initcap,
"Position of the first occurrence of the substring specified
"6
instr( carrname,'a' ) AS instr,
"String of length n starting from the left of an expression;
"trailing blanks are ignored
"Luft
left( carrname, 4 ) AS left,
"Number of characters in an expression, trailing blanks are ignored
"24
length( url ) AS length,
"Checks if expression contains a PCRE expression;
"case-sensitive by default (case_sensitive parameter can be specified)
"Notes on the 1 = found, 0 = not found
"1
like_regexpr( pcre = '\..', "Period that is followed by any character
value = url ) AS like_regex,
"Returns position of a substring in an expression,
"3rd parameter = specifies offset (optional)
"4th parameter = determines the number of occurrences (optional)
"9
locate( carrname, 'a', 0, 2 ) AS locate,
"Searches a PCRE pattern, returns offset of match;
"many optional parameters: occurrence, case_sensitive, start, group
"21
locate_regexpr( pcre = '\..', "Period followed by any character
value = url,
occurrence = 2 ) "2nd occurrence in the string
AS locate_regexpr,
"Searches a PCRE pattern, returns offset of match + 1;
"many optional parameters: occurrence, case_sensitive, start, group
"2
locate_regexpr_after( pcre = '.', "Any character
value = url,
occurrence = 1 ) AS locate_regexpr_after,
"Removes leading characters as specified in the 2nd argument,
"trailing blanks are removed
"ufthansa
ltrim( carrname, 'L' ) AS ltrim,
"Counts all occurrences of found PCRE patterns
"2
occurrences_regexpr( pcre = '\..', "Period that is followed by any character
value = url ) AS occ_regex,
"Replaces the 2nd argument with the 3rd in an expression
"Lufth#ns#
replace( carrname, 'a', '#' ) AS replace,
"Replaces a found PCRE expression;
"more parameters possible: occurrence, case_sensitive, start
"http://www#ufthansa#om
replace_regexpr( pcre = '\..', "Period that is followed by any character
value = url,
with = '#' ) AS replace_regex,
"Extracts a string with the length specified starting from the right
"hansa
right( carrname, 5 ) AS right,
"Expands string to length n (2nd argument); trailing blanks produced
"are replaced by the characters from the (3rd) argument
"Note that if n is less than the string, the expression is truncated
"on the right.
"Lufthansa###
rpad( carrname, 12, '#' ) AS rpad,
"All trailing characters that match the character of the 2nd argument
"are removed; trailing blanks are removed, too
"Lufthans
rtrim( carrname, 'a' ) AS rtrim,
"Returns a substring; 2nd argument = position from where to start;
"3rd argument: length of the extracted substring
"fth
substring( carrname, 3, 3 ) AS substring,
"Searches for a PCRE expression and returns the matched substring
"More parameters possible: occurrence, case_sensitive, start, group
".lu
substring_regexpr( pcre = '\...', "Period that is followed by any two characters
value = url ) AS substring_regexpr,
"All lower case letters are transformed to upper case letters
"LUFTHANSA
upper( carrname ) AS upper
FROM zdemo_abap_carr
WHERE carrid = 'LH'
INTO @DATA(string_functions).DATA da TYPE d VALUE '20240122'.
DATA ti TYPE t VALUE '123456'.
DATA utc TYPE utclong VALUE '2024-02-15 05:30:00'.
DATA tmst TYPE timestamp VALUE '20240808112458'.
DATA tmstlong TYPE timestampl VALUE '20240101081317.81011'.
SELECT SINGLE FROM i_timezone
FIELDS
"---------------------- Date ----------------------
"Generic date functions (types d, utclong)
"type t also possible; 1
is_valid( @ti ) AS isvalid,
"In the following examples in this 'section', d and utclong are possible.
"2024
extract_year( @utc ) AS extr_year,
"1
extract_month( @da ) AS extr_month,
"15
extract_day( @utc ) AS extr_day,
"Monday
dayname( @da ) AS day_name,
"February
monthname( @utc ) AS month_name,
"3
weekday( @utc ) AS week_day,
"10
days_between( @utc,utclong`2024-02-25 08:14:26` ) AS days_bw,
"20240124
add_days( @da,2 ) AS add_days,
"2024-05-15 05:30:00.0000000
add_months( @utc,3 ) AS add_months,
"Functions for the type datn
"32
datn_days_between( datn`20240111`,datn`20240212` ) AS days_datn_bw,
"20240115
datn_add_days( datn`20240111`,4 ) AS days_datn_add,
"20240611
datn_add_months( datn`20240111`,5 ) AS months_datn_add,
"Functions for the type dats
"1
dats_is_valid( dats`20240812` ) AS dats_valid,
"5
dats_days_between( dats`20240812`,dats`20240817` ) AS days_dats_bw,
"20240816
dats_add_days( dats`20240812`,4 ) AS days_dats_add,
"20241112
dats_add_months( dats`20240812`,3 ) AS months_dats_add,
"---------------------- Time ----------------------
"Generic time functions (types t and utclong)
"As above, types d and utclong also possible; 1
is_valid( @ti ) AS time_is_valid,
"5
extract_hour( @utc ) AS extr_hour,
"34
extract_minute( @ti ) AS extr_min,
"0
extract_second( @utc ) AS extr_sec,
"Function for the type tims
"1
tims_is_valid( tims`231256` ) AS tims_is_valid,
"---------------------- Time Stamp ----------------------
"Note: The type utclong can be used in the generic functions above.
"Functions specific to the type utclong
"Generates a UTC time stamp; e.g. 2024-01-01 12:58:58.5070000
utcl_current( ) AS utcl_current,
"2024-02-15 05:30:05.0000000
utcl_add_seconds( @utc,5 ) AS sec_add_utc,
"51.0000000
utcl_seconds_between( utclong`2024-02-25 08:14:26`,utclong`2024-02-25 08:15:17` ) AS sec_bw_utc,
"Functions specific to the type timetamp
"1
tstmp_is_valid( @tmst ) AS ts_is_valid,
"20240312125858
tstmp_current_utctimestamp( ) AS ts_current,
"The following two functions have an optional parameter on_error.
"Check the ABAP Keyword Documentation
"19
tstmp_seconds_between( tstmp1 = @tmst,
tstmp2 = CAST( dec`20240808112517` AS DEC( 15,0 ) ) ) AS sec_bw_ts,
"20240808112508
tstmp_add_seconds( tstmp = @tmst,
seconds = CAST( dec`10` AS DEC( 15,0 ) ) ) AS sec_add_ts,
"---------------------- Functions for conversions ----------------------
"Note: For the following functions, optional parameters are possible.
"For more details, check the ABAP Keyword Documentation.
"20240808
tstmp_to_dats( tstmp = @tmst,
tzone = CAST( char`EST` AS CHAR( 6 ) ) ) AS tstmp_to_dats,
"072458
tstmp_to_tims( tstmp = @tmst,
tzone = CAST( char`EST` AS CHAR( 6 ) ) ) AS tstmp_to_tims,
"X
tstmp_to_dst( tstmp = @tmst,
tzone = CAST( char`EST` AS CHAR( 6 ) ) ) AS tstmp_to_dst,
"20240122173456
dats_tims_to_tstmp( date = @da,
time = @ti,
tzone = CAST( char`EST` AS CHAR( 6 ) ) ) AS dats_tims_to_tstmp,
"2024-01-01 08:13:17.8101100
tstmpl_to_utcl( tstmpl = @tmstlong ) AS tstmpl_to_utcl,
"20240215053000.0000000
tstmpl_from_utcl( utcl = @utc ) AS tstmpl_from_utcl,
"20240812
dats_to_datn( dats = dats`20240812` ) AS dats_to_datn,
"20240111
dats_from_datn( datn = datn`20240111` ) AS dats_from_datn,
"231256
tims_to_timn( tims = tims`231256` ) AS tims_to_timn,
"155432
tims_from_timn( timn = timn`155432` ) AS tims_from_timn
WHERE TimeZoneID = char`EST`
INTO @DATA(time_and_date_functions).SELECT SINGLE
carrid,
"Type conversion: string of fixed length (e.g. of type c) to variable
"length string of type string
to_clob( carrid ) AS clob,
"Byte string -> character string
bintohex( raw`1234` ) AS bintohex,
"Character string -> byte string
hextobin( char`1234` ) AS hextobin,
"Byte field of type RAW to a byte string (BLOB) of type RAWSTRING
to_blob( raw`1234` ) AS blob,
"Unit and currency conversion functions
"More parameters are available.
"Converts miles to kilometers
unit_conversion( quantity = d34n`1`,
source_unit = unit`MI`,
target_unit = unit`KM` ) AS miles_to_km,
"Creating a unique UUID for each row
uuid( ) AS uuid
FROM zdemo_abap_carr
WHERE carrid = char`LH`
INTO @DATA(special_functions)."The null value is a special value that is returned by a database. It indicates an
"undefined value or result. Note that, in ABAP, there are no special null values. Do
"not confuse the null value with a type-dependent initial value. When using SELECT
"statements to read data, null values can be produced by, for example, outer joins.
"When the null values are passed to a data object, they are transformed to the
"type-dependent initial values. For more information, refer to the ABAP Keyword Documentation.
"The following example uses a left outer join to intentionally create null values. For
"this purpose, two demo database tables of the ABAP cheat sheet repository are cleared and
"populated with specific values to visualize null values.
DELETE FROM zdemo_abap_tab1.
DELETE FROM zdemo_abap_tab2.
MODIFY zdemo_abap_tab1 FROM TABLE @( VALUE #( ( key_field = 1 char1 = 'a' char2 = 'y' )
( key_field = 2 char1 = 'b' char2 = 'z' ) ) ).
MODIFY zdemo_abap_tab2 FROM TABLE @( VALUE #( ( key_field = 1 char1 = 'a' )
( key_field = 2 char1 = 'a' )
( key_field = 3 char1 = 'b' )
( key_field = 4 ) ) ).
"Note that for the entry 'key_field = 4' no char1 value was passed.
"char1 is a shared column of the two database tables, and which is used in
"the ON condition of the join. Since there is no entry in char1 for 'key_field = 4',
"the joined values are null in that case.
"The coalesce function is used to replace null values produced by an outer join with
"a different value.
SELECT tab2~key_field,
coalesce( tab1~char1, '-' ) AS coalesced1,
coalesce( tab1~char2, '#' ) AS coalesced2
FROM zdemo_abap_tab2 AS tab2
LEFT OUTER JOIN zdemo_abap_tab1 AS tab1 ON tab1~char1 = tab2~char1
INTO TABLE @DATA(join_w_null).
*Example table content
*KEY_FIELD COALESCED1 COALESCED2
*1 a y
*2 a y
*3 b z
*4 - # [!NOTE] - The steps to import and run the code are outlined here. - Disclaimer
24_Builtin_Functions.md。版权归原作者所有。