Subroutine – Call External Subroutine

The syntax for calling subroutine from other program

Perform <subroutine>(<program>) [TABLES <actual table list>]
                                [USING <actual input list>]
                                [CHANGING <actual output list>]

By referring to previous example Subroutine – Recursive Call. This example will call to the subroutine fibonacci in program ZBC_SR_BASIC.

REPORT  ZBC_SR_REF.

 PARAMETERS p_num TYPE i.

 START-OF-SELECTION.
   DATA: output  TYPE i,
         sNum    TYPE string,
         sOutput TYPE string,
         desc    TYPE string.

   IF p_num < 0 OR p_num >= 22.
     WRITE:/ 'The input number cannot less than 0 or greater than 21.'.
     EXIT.
   ENDIF.

 * Call to ZBC_SR_BASIC -> fibonacci to get the value
   PERFORM fibonacci(ZBC_SR_BASIC) USING p_num CHANGING output.
   " Convert integer to string
   MOVE p_num TO sNum.
   MOVE output TO sOutput.

   desc = 'F(n): n=& F=&'.
   REPLACE '&' WITH sNum INTO desc.
   REPLACE '&' WITH sOutput INTO desc.

   WRITE:/ desc.

Result:


Fibonacci (1 to 21)                                                                            1
------------------------------------------------------------------------------------------------
F(n): n=15  F=610

Subroutine – Recursive Call

This example will show how to use subroutine to get the Fibonacci number by using Recursive Call. Due to performance issue, this program will only show first 21 Fibonacci numbers.

REPORT  ZBC_SR_BASIC.
 
 DATA idx TYPE i VALUE 21.
 
 START-OF-SELECTION.
   DO idx TIMES.
     PERFORM getFib USING sy-index.
   ENDDO.
 
 FORM getFib USING num TYPE i.
   DATA: output  TYPE i,
         sNum    TYPE string,
         sOutput TYPE string,
         desc    TYPE string.
 
   PERFORM fibonacci USING num CHANGING output.
   " Convert integer to string
   MOVE num TO sNum.
   MOVE output TO sOutput.
 
   desc = 'F(n): n=& F=&'.
   REPLACE '&' WITH sNum INTO desc.
   REPLACE '&' WITH sOutput INTO desc.
 
   WRITE:/ desc.
 ENDFORM.
 
 *---------------------------------------------------
 * Recursive Call: This FORM will call back to itself
 *---------------------------------------------------
 FORM fibonacci USING num CHANGING out.
   DATA: lv_num1 TYPE i,
         lv_num2 TYPE i,
         out1 TYPE i,
         out2 TYPE i.
   IF num > 2.
     lv_num1 = num - 1.
     PERFORM fibonacci USING lv_num1 CHANGING out1.
     lv_num2 = num - 2.
     PERFORM fibonacci USING lv_num2 CHANGING out2.
 
     out = out1 + out2.
   ELSEIF num = 2.
     out = 1.
   ELSE.
     out = num.
   ENDIF.
 ENDFORM.

Result:

Fibonacci List                                                                              1
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
F(n): n=1  F=1
F(n): n=2  F=1
F(n): n=3  F=2
F(n): n=4  F=3
F(n): n=5  F=5
F(n): n=6  F=8
F(n): n=7  F=13
F(n): n=8  F=21
F(n): n=9  F=34
F(n): n=10  F=55
F(n): n=11  F=89
F(n): n=12  F=144
F(n): n=13  F=233
F(n): n=14  F=377
F(n): n=15  F=610
F(n): n=16  F=987
F(n): n=17  F=1597
F(n): n=18  F=2584
F(n): n=19  F=4181
F(n): n=20  F=6765
F(n): n=21  F=10946

Internal Table – COLLECT Statement

The COLLECT statement is use to sum up the field by categorize other fields as the different category.

For example, we have the following data.

CODE TYPE VALUE
A0001 K01 10
A0002 K01 20
A0003 K02 30
A0003 K02 5
A0001 K01 7

After we use COLLECT statement, we will get the following result.

CODE TYPE VALUE
A0001 K01 17
A0002 K01 20
A0003 K02 35

Example 1: CODE for 3 fields

REPORT  ZBC_ITCOLLECT_3FLD.
* Define the IT Line
 TYPES: BEGIN OF iLine,
 code(10)  TYPE c,
 type(10)  TYPE c,
 value     TYPE i,
 END OF iLine.

* Internal Table
* Work area with Header Line
 DATA: it_code     TYPE STANDARD TABLE OF iLine INITIAL SIZE 10 WITH HEADER LINE,
 wa_code     TYPE iLine,
 wa_code_tmp TYPE iLine,
 sMsg        TYPE string.

PERFORM WRITE_TXT USING 'Section 1: Insert 5 records into the internal table.'.

* COLLECT 1
 it_code-code = 'A0001'.
 it_code-type = 'K01'.
 it_code-value = 10.
 COLLECT it_code.

* COLLECT 2
 it_code-code = 'A0002'.
 it_code-type = 'K01'.
 it_code-value = 20.
 COLLECT it_code.

* COLLECT 3
 it_code-code = 'A0003'.
 it_code-type = 'K02'.
 it_code-value = 30.
 COLLECT it_code.

* COLLECT 4
 it_code-code = 'A0003'.
 it_code-type = 'K02'.
 it_code-value = 5.
 COLLECT it_code.

* COLLECT 5
 it_code-code = 'A0001'.
 it_code-type = 'K01'.
 it_code-value = 7.
 COLLECT it_code.

PERFORM WRITE_IT.

FORM WRITE_IT.
 LOOP AT it_code INTO wa_code_tmp.
 WRITE:/ wa_code_tmp-code, wa_code_tmp-type, wa_code_tmp-value.
 ENDLOOP.
 SKIP.
 ENDFORM.

FORM WRITE_TXT USING sMsg.
 SKIP 2.
 WRITE: sMsg.
 ULINE /1(70).
 ENDFORM.

Result

Section 1: Insert 5 records into the internal table.
----------------------------------------------------------------------
A0001      K01                17
A0002      K01                20
A0003      K02                35

Example 2: Code for 2 fields and collect with empty statement.

REPORT  ZBC_ITCOLLECT.

* Define the IT Line
TYPES: BEGIN OF iLine,
code(10)  TYPE c,
section   TYPE i,
END OF iLine.

* Internal Table
* Work area with Header Line
DATA: it_code     TYPE STANDARD TABLE OF iLine INITIAL SIZE 10 WITH HEADER LINE,
wa_code     TYPE iLine,
wa_code_tmp TYPE iLine,
sMsg        TYPE string.

PERFORM WRITE_TXT USING 'Section 1: Insert 5 records into the internal table.'.

DO 5 TIMES.
it_code-code = SY-INDEX.
it_code-section = SY-INDEX ** 2.
COLLECT it_code.
ENDDO.

PERFORM WRITE_IT.

PERFORM WRITE_TXT USING 'Section 2: Now add in another 5 records into the internal table and write out.'.

DO 5 TIMES.
it_code-code = SY-INDEX.
it_code-section = SY-INDEX ** 3.
WRITE:/ it_code-code, it_code-section.
COLLECT it_code.
ENDDO.

PERFORM WRITE_TXT USING 'Section 3: This is the output for COLLECT.'.
PERFORM WRITE_IT.

sMsg = 'Section 4: Perform COLLECT in LOOP of 5'.
PERFORM WRITE_TXT USING sMsg.
DO 5 TIMES.
COLLECT it_code.
PERFORM WRITE_TXTH2 USING SY-INDEX.
PERFORM WRITE_IT.
ENDDO.

FORM WRITE_IT.
LOOP AT it_code INTO wa_code_tmp.
WRITE:/ wa_code_tmp-code, wa_code_tmp-section.
ENDLOOP.
SKIP.
ENDFORM.

FORM WRITE_TXT USING sMsg.
SKIP 2.
WRITE: sMsg.
ULINE /1(70).
ENDFORM.

FORM WRITE_TXTH2 USING sMsg.
SKIP 1.
WRITE: 9 'COLLECT', sMsg.
ULINE /1(30).
ENDFORM.

Result

Section 1: Insert 5 records into the internal table.
----------------------------------------------------------------------
1           1
2           4
3           9
4          16
5          25

Section 2: Now add in another 5 records into the internal table and write out.
----------------------------------------------------------------------
1           1
2           8
3          27
4          64
5         125

Section 3: This is the output for COLLECT.
----------------------------------------------------------------------
1           2
2          12
3          36
4          80
5         150

Section 4: Perform COLLECT in LOOP of 5
----------------------------------------------------------------------
COLLECT          1
------------------------------
1           2
2          12
3          36
4          80
5         275

COLLECT          2
------------------------------
1           2
2          12
3          36
4          80
5         400

COLLECT          3
------------------------------
1           2
2          12
3          36
4          80
5         525

COLLECT          4
------------------------------
1           2
2          12
3          36
4          80
5         650

COLLECT          5
------------------------------
1           2
2          12
3          36
4          80
5         775

In the second example, you can see that, the additional FORM is created. It’s just like a sub function, that we can call it from other part of our program, to reduce our code.

To declare:

FORM function_name [USING variable/structure,…].

…

ENDFORM.

To call it:

PERFORM function_name [USING variable/structure,…].

How To: Dynamic where clause

Assignment to Bryan: How to build a dynamics where clause at run time.

Hints:  Use internal table.

The POPUP_TO_CONFIRM (popup message box) also included in this example.

REPORT  ZBC_SQLDW.

* Declare parameter to get the filter from user input.
PARAMETERS pFilter(20) TYPE c LOWER CASE .

* Declare dynamic where variable as Internal Table
DATA: d_where_1(100) OCCURS 0 WITH HEADER LINE.

* Declare vAns as answer variable, and 
* sFilter for filter string
DATA: vAns TYPE c,
      sFilter(100) TYPE c.

TABLES KNA1.

CALL FUNCTION 'POPUP_TO_CONFIRM'
EXPORTING
  TITLEBAR = 'Message Box'
  TEXT_QUESTION = 'Are you want to continue?'
  TEXT_BUTTON_1 = '-- Yes --'
  TEXT_BUTTON_2 = '-- No --'
IMPORTING
  ANSWER = vAns.

IF vAns = '1'. " If user click "Yes"
  WRITE:/ 'You are clicked on YES'.

  IF STRLEN( pFilter ) > 0.
    CONCATENATE 'NAME1 LIKE ''%' pFilter '%''' INTO sFilter.
    APPEND  sFilter to d_where_1.
    APPEND  'AND LAND1 = ''MY''' to d_where_1.
  ELSE.
    APPEND 'NAME1 LIKE ''Bryan''' to d_where_1.
    APPEND  ' AND LAND1 = ''MY''' to d_where_1.
  ENDIF.

WRITE:/ 'User key in parameter: ', pFilter.
WRITE:/ 'Generated SQL:', sFilter.

SKIP.

WRITE:/ 'Search result(s)'.
WRITE:/.
ULINE (15).

  SELECT * FROM KNA1
    WHERE (d_where_1). " It will look like: NAME1 LIKE '%an%'.  "
    WRITE:/ 'Account Number: ', Kna1-KUNNR.
    WRITE: 'Customer Name: ', Kna1-NAME1.
  ENDSELECT.
ELSEIF vAns = '2'. " If user click "No"
  WRITE:/ 'You are clicked on NO'.
  STOP.
ELSEIF vAns = 'A'. " If user click "Cancel"
  WRITE:/ 'You are clicked on Cancel'.
  STOP.
ENDIF.

Parameters for POPUP_TO_CONFIRM

Here’s the parameters for POPUP message (available imports/exports/tables)

TITLEBAR                                 ==> DEFAULT SPACE
DIAGNOSE_OBJECT        LIKE DOKHL-OBJECT ==> DEFAULT SPACE
TEXT_QUESTION                            ==> string
TEXT_BUTTON_1                            ==> DEFAULT 'Yes'(001)
ICON_BUTTON_1          LIKE ICON-NAME    ==> DEFAULT SPACE
TEXT_BUTTON_2                            ==> DEFAULT 'No'(002)
ICON_BUTTON_2          LIKE ICON-NAME    ==> DEFAULT SPACE
DEFAULT_BUTTON                           ==> DEFAULT '1'
DISPLAY_CANCEL_BUTTON                    ==> DEFAULT 'X'
USERDEFINED_F1_HELP    LIKE DOKHL-OBJECT ==> DEFAULT SPACE
START_COLUMN           LIKE SY-CUCOL     ==> DEFAULT 25
START_ROW              LIKE SY-CUROW     ==> DEFAULT 6
POPUP_TYPE             LIKE ICON-NAME    OPTIONAL
Answer - It holds the user action
         Yes    = 1
         No     = 2
         Cancel = A

Other POPUP Functions

POPUP_TO_CONFIRM
POPUP_TO_CONFIRM_LOSS_OF_DATA  – Create a dialog box in which you make a question whether the user wishes to perform a processing step with loss of data.
POPUP_TO_CONFIRM_STEP – Create a dialog box in which you make a question whether the user wishes to perform the step.
POPUP_TO_CONFIRM_WITH_MESSAGE – Create a dialog box in which you inform the user about a specific decision point during an action.
POPUP_TO_CONFIRM_WITH_VALUE – Create a dialog box in which you make a question whether the user wishes to perform a processing step with a particular object.
POPUP_TO_DECIDE – Provide user with several choices as radio buttons
POPUP_TO_DECIDE_WITH_MESSAGE – Create a dialog box in which you inform the user about a specific decision point via a diagnosis text.
POPUP_TO_DISPLAY_TEXT – Create a dialog box in which you display a two line message
POPUP_TO_SELECT_MONTH – Popup to choose a month
POPUP_WITH_TABLE_DISPLAY – Provide a display of a table for user to select one, with the value of the table line returned when selected.
POPUP_WITH_2_BUTTONS_TO_CHOOSE

Tutorial 1 – Q4 Form with CustGroup (Bryan)

Thinking to use table trigger on create to set the datetime and recid. But failed to do it until end of today.

 
REPORT  ZCUSTGROUP.

 PARAMETERS P_CGCODE TYPE ZBCUSTGRP-CUSTGROUPID DEFAULT '001'.
 PARAMETERS P_CGDESC TYPE ZBCUSTGRP-DESCRIPTION DEFAULT 'Default Group'.

 DATA: iRecId TYPE i,
       sDateTime TYPE TZNTIMESTP.

 DATA: tCG TYPE ZBCUSTGRP.

 * To get last value of recid
 SELECT MAX( RECID )
   INTO iRecId
   FROM ZBCUSTGRP.

 * Set date time
 CONCATENATE sy-datum sy-uzeit INTO sDateTime.

 * Construct data
 tCG-CUSTGROUPID = P_CGCODE.
 tCG-DESCRIPTIOn = P_CGDESC.
 tCG-CREATEDDATETIME = sDateTime.
 tCG-RECID = iRecId + 1.

 * Insert data
 INSERT ZBCUSTGRP FROM tCG.

 WRITE:/ 'The record insert'.
 IF SY-SUBRC = 0.
   WRITE: 'successfully.'.
 ELSE.
   WRITE: 'was failed'.
 ENDIF.

 SKIP 3.

 ULINE /(34).
 WRITE:/ '     Here''s the information'.
 ULINE /(34).
 WRITE:/ 'Cust Group Code', 17 ':', 19 tCG-CUSTGROUPID.
 WRITE:/ 'Cust Group Name', 17 ':', 19 tCG-DESCRIPTION.
 WRITE:/ 'Date Time', 17 ':', 19 tCG-CREATEDDATETIME.
 WRITE:/ 'New RecId', 17 ':', 19 tCG-RECID LEFT-JUSTIFIED.
 ULINE /(34).

Result – Part 1:

Show parameters

Showing the message

Table content

Reference:

For table trigger: http://www.indiastudychannel.com/resources/50466-EVENTS-table-maintenance-generator-ABAP.aspx

Tips

To change the label for PARAMETERS, use Go to -> Text elements -> Selection Text

Then edit the label.

Table Trigger

Code for table trigger: (but not success yet)

 *----------------------------------------------------------------------*
 ***INCLUDE LZBTESTF01 .
 *----------------------------------------------------------------------*

 FORM CREATE_ENTRY.
   DATA: sDT(14) TYPE c,
       iRecId TYPE i.

   SELECT MAX( RECID )
   INTO iRecId
   FROM ZBCUSTGRP.

   CONCATENATE sy-datum sy-uzeit INTO sDT.
   ZBCUSTGRP-CREATEDDATETIME = sDT.
   ZBCUSTGRP-RECID = iRecId.
   UPDATE ZBCUSTGRP.
 ENDFORM.

SQL MODIFY

Posted by Bryan

Syntax

MODIFY <target_database_tab> <databae_tab_lines>

This is a very useful function for us to update or insert data.

This MODIFY will either UPDATE or INSERT data to the table. It will base on the primary key to determine the operation of UPDATE or INSERT. When the keys are exists, UPDATE will use to update the existing data. But when the keys is not exists, it will switch to INSERT operation and create a new record.

The syntax is similar with UPDATE and DELETE.

Example 1: MODIFY a single record

TABLES KNA1.
DATA vline TYPE KNA1.
vline-KUNNR = ‘000001’.
vline-NAME1 = ‘Bryan’.
MODIFY KNA1 FROM vline.

If the record with KUNNR=‘000001’ is exists and NAME1 = ‘Bryan Chong’, this operation will update the NAME1 to ‘Bryan’.

If the record is not exists, then a new record with KUNNR= ‘000001’ and NAME1 = ‘Bryan’ will be created.

Example 2: MODIFY multiple records

DATA: myTable TYPE HASHED TABLE OF KNA1
WITH UNIQUE KEY KUNNR,
tabLine LIKE LINE OF myTable.

tabLine-KUNNR = ‘000001’.
tabLine-NAME1 = ‘Bryan’.
INSERT tabLine INTO TABLE myTable.

tabLine-KUNNR = ‘000009’.
tabLine-NAME1 = ‘Jack’.
tabLine-ORT01 = ‘Kuala Lumpur’.
INSERT tabLine INTO TABLE myTable.

MODIFY KNA1 FROM myTable.

SQL DELETE

Posted by Bryan

Syntax

DELETE [FROM] <target_database_tab> <databae_tab_lines>

After we studied on SELECT, INSERT and UPDATE syntax and statement, we will see that the DELETE statement also looks similar with UPDATE.

Example 1: DELETE with WHERE clause

In this example, we can see that, it’s same with general SQL-DELETE.

TABLES: KNA1.
DELETE FROM KNA1
WHERE KUNNR = ‘0000001’

Example 2: DELETE with MOVE

TABLES KNA1.
DATA: BEGIN OF vline,
        KUNNR TYPE KNA1-KUNNR,
      END OF vline.

MOVE ‘000001’ TO vline -KUNNR.
DELETE KNA1 FROM vline.

Example 3: Using table variable

TABLES KNA1.
DATA vline TYPE KNA1.

vline-KUNNR = ‘000001’.
DELETE KNA1 FROM vline.

Example 4: Using Table name

TABLES KNA1.
KNA1-KUNNR = ‘000001’.  “ We also can use MOVE ‘000001’ TO KNA1-KUNNR.
DELETE KNA1.

Example 5: Delete multiple records

In this example, we are using internal table to keep all the information that we need to delete, it’s hashed table.

DATA: myTable TYPE HASHED TABLE OF KNA1
                   WITH UNIQUE KEY KUNNR,
      tabLine LIKE LINE OF myTable.

tabLine-KUNNR = ‘000001’.
INSERT tabLine INTO TABLE myTable.

tabLine-KUNNR = ‘000009’.
INSERT tabLine INTO TABLE myTable.

DELETE KNA1 FROM TABLE myTable.

SQL UPDATE

Posted by Bryan


Syntax

UPDATE <target_database_tab> <database_tab_lines>.

There are 3 approaches to update a record in ABAP.

  1. Traditional UPDATE statement
    UPDATE target SET f1 = ? WHERE conditions
  2. Update a single record from variable
    UPDATE target FROM target_line
    UPDATE target
  3. Update multiple records from variable
    UPDATE target FROM work_area
    UPDATE target FROM TABLE internal_table

Example 1:

This is the traditional SQL method.

UPDATE KNA1 SET NAME1 = ‘new name’WHERE KUNNR = ‘000001’

Example 2:

In this example, we can see that, what we need to do is to assign the values into the fields, where primary fields are mandatory. When we update the table, it will automatically select those records that need to update, based on primary keys, and update the records, based on what we defined here.

TABLES KNA1.
DATA vline TYPE KNA1.
vline-KUNNR = ‘000001’.
vline-NAME1 = ‘new name’.
UPDATE KNA1 FROM vline.

Example 3: Using MOVE

In this example, we can see the different ways to assign value, which is using MOVE.

TABLES KNA1.
DATA vline TYPE KNA1.
MOVE ‘000001’ TO vline-KUNNR.
MOVE ‘new name’ TO vline-NAME1.
UPDATE KNA1 FROM vline.

Example 4: Using Table name

We also can use the table name directly to assign values to fields, and update the table.

TABLES KNA1.
MOVE ‘000001’ TO KNA1-KUNNR.
MOVE ‘new name’ TO KNA1-NAME1.
UPDATE KNA1.

Example 5: Update batch records, using hashed table.

This example is to update multiple records by using hashed table, which is similar to INSERT.

DATA: myKNA1 TYPE HASHED TABLE OF KNA1
                  WITH UNIQUE KEY KUNNR,
      myLine LIKE LINE OF myKNA1.

myLine-KUNNR = ‘000001’.
myLine-NAME1 = ‘my new name’.
INSERT myLine INTO TABLE myKNA1.

myLine-KUNNR = ‘000002’.
myLine-NAME1 = ‘my new name 2’.
INSERT myLine INTO TABLE myKNA1.

UPDATE KNA1 FROM TABLE myKNA1.

SQL INSERT

Posted by Bryan Chong


The INSERT statement is ABAP is very powerful.

Syntax

INSERT INTO <target_database_tab> <database_tab_lines>.

Target, is the database table name, and also can be a variable of table.

Lines, it can be a single record or multiple records.

Insert for Single Line

We could have 3 ways to insert single line to database table.

By declaring a variable, and store the information into it, and then insert to database table.

First method will be

INSERT INTO table VALUES theLineVariable.

Second method is

INSERT table FROM theLineVariable.

The code different for first and second method are first method using “INTO & VALUES”, where second method using “FROM”. It makes the code shorter.

The third method, we can use the declared table to store the information, and then insert to database table. This method is look very simple. But, if we use this method, the table that declared, are not allowed to use again in other part.

INSERT table.

Example1: 3 ways to insert data.

Part A: Using first method

TABLES KNA1.
DATA cu TYPE KNA1.
cu-KUNNR = '007'.
cu-NAME1 = 'Bryan'.
INSERT INTO KNA1 VALUES cu.

Part B: Using second method

TABLES KNA1.
DATA cu TYPE KNA1.
cu-KUNNR = '007'.
cu-NAME1 = 'Bryan'.
INSERT KNA1 FROM cu.

Part C: Using third method

TABLES KNA1.
KNA1-KUNNR = '007'.
KNA1-NAME1 = 'Bryan'.
INSERT KNA1.

Insert for multiple lines

The concept of this is similar to SELECT multiple records to a variable. Here we need to create the Hashed Table, it will act like a temporary table with same structure with the original table.

We also can define the accepting rules for the insert to prevent runtime error during execution. This can be added to the end of the statement “ACCEPTING DUPLICATE KEYS”.

Example 2: To insert multiple line

* Define the hashed table and the line of hashed variable
DATA: hKNA1 TYPE HASHED TABLE OF KNA1
            WITH UNIQUE KEY MANDT KUNNR,
      lKNA LIKE LINE OF hKNA1.

* Now insert data into the hashed table
lKNA-KUNNR = '008'. lKNA-NAME1 = 'John'.
INSERT lKNA INTO TABLE hKNA1. 

lKNA-KUNNR = '009'. lKNA-NAME1 = 'Marry'.
INSERT lKNA INTO TABLE hKNA1.

lKNA-KUNNR = '010'. lKNA-NAME1 = 'Steven'.
INSERT lKNA INTO TABLE hKNA1.

* This line is to insert data from hashed table to physical table
INSERT KNA1 FROM TABLE hKNA1 ACCEPTING DUPLICATE KEYS.

SQL SELECT

Posted by Bryan


SQL in ABAP, is different from other languages, e.g.: Ax.

SELECT Syntax

SELECT        <selected_result>
INTO          <target_area>
FROM          <source_database_tab>
[WHERE        <where_condition>]
[GROUP BY     <fields>]
[HAVING       <having_condition>]
[ORDER BY     <fields>].

Example 1: Select all column

TABLE: KNA1.
SELECT *
  FROM KNA1
  WRITE:/ KNA1-KUNNR, KNA1-NAME1.
ENDSELECT.

This is similar to Ax Code:

while select CustTable {
    info(CustTable.AccountNum) 
}

If want to get single record, we can use this.

SELECT SINGLE *
  FROM KNA1.
WRITE:/ KNA1-KUNNR, KNA1-NAME1.

Example 2: Select particular columns

In the select field list, we have to use ~ to point to the table & fields, e.g.: KNA1~KUNNR.

For the list of the fields, traditionally, we are using comma “,” as the separator, but in ABAP, we just use space.

We need to assign the result to a variable by INTO.

TABLES: KNA1.
DATA: BEGIN OF dsCT,
  AcNum TYPE KNA1-KUNNR,
  Name TYPE KNA1-NAME1,
  City TYPE KNA1- ORT01,
  END OF dsCT.

SELECT ct~KUNNR ct~NAME1 ct~ORT01   INTO dsCT
  FROM KNA1 AS ct.
  WRITE:/ dsCT-AcNum, dsCT-Name, dsCT-City.
ENDSELECT.

WHERE Clause

In the where clause, we use ~ to point to the field of the table.

The WHERE clause conditions, we can use the following

  • Relational Operations
    • Equal: EQ or =
    • Not Equal: NE or <> or ><
    • Less than: LT or <
    • Less than or equal: LE or <=
    • Greater than: GT or >
    • Greater than or equal: GE or >=
  • Range Operators
    • [NOT] BETWEEN a AND b
  • String Pattern
    • [NOT] LIKE pattern1 [ESCAPE pattern2]
    • Wildcard:
      • % for any chars
      • _ for a single char
  • Specifying a list
    • [NOT] IN (a, b, c, …)
  • Work with subqueries:
    • [NOT] IN (subquery)
    • [NOT] EXISTS (subquery)

Example 3:

SELECT SINGLE *
  FROM KNA1.
  WHERE KNA1~ORT01 LIKE '%LUMPUR'
  AND   KNA1~UMSA1 <= 50000.
        " we also can use -- KNA1~UMSA1 LE 50000 
  WRITE:/ KNA1-KUNNR, KNA1-NAME1, KNA1- ORT01, KNA1-UMSA1.

GROUP BY

This is similar with standard SQL query. The syntax will be

SELECT * INTO var FROM table
  GROUP BY field1 field2 …

Field list, are separated by space.

HAVING

The HAVING clause is to restrict the output to selected groups based on specified conditions. This must used only in conjunction with GROUP BY. The syntax is same as standard SQL.

Example 4:

SELECT ZEILE
  INTO fZAILE
  FROM MARI
  GROUP BY ZEILE
  HAVING SUM(MENGE) > 10.

ORDER BY

This ORDER BY is same with standard SQL, but the field list is separated with space

ORDER BY field1 field2 …

JOIN

For this, we have to create the data type for the result set to store the values return from the SQL.

Example 5:

(Here using Ax table as example)

DATA: BEGIN OF rsCT,
        AcNum TYPE CustTable-AccountNum,
        Name TYPE CustTable-FullName,
        Address TYPE Address-Address,
      END OF rsCT.
SELECT ct~AccountNum ct~FullName addr~Address
  INTO rsCT
  FROM CustTable AS ct JOIN Address AS addr
  ON ct~recId = addr~AddrRecId
  WHERE addr~AddrTableId = '77'
        " This is the table ID for CustTable (in Ax) 
  WRITE:/ rsCT-AcNum, rsCT-Name, rsCT-Address.
ENDSELECT.

Aggregate

Syntax

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

Example 6:

DATA count TYPE i.
SELECT COUNT( DISTINCT ORT01 )
  FROM KNA1
  INTO count
  WHERE ORT01 = 'NEW YORK'.

System variables

  1. SY-SUBRC –> it will return the status of the SQL execution, if success, 0 (zero) will return.
  2. SY-DBCNT –> it will return the number of records fetched from database.

Others example of SELECT Statement

Example 7: Select all fields and single record into Corresponding Fields of Table

DATA cust TYPE KNA1.
SELECT SINGLE *
  INTO CORRESPONDING FIELDS OF cust
  FROM  KNA1.

Example 8: Select particular fields and single record into Corresponding Fields of Table

DATA cust TYPE KNA1.
SELECT SINGLE ct~KUNNR ct~NAME1
  INTO CORRESPONDING FIELDS OF cust
  FROM  KNA1 AS ct.

Example 9: Select all fields and multiple records into Corresponding Fields of Table and by looping

DATA cust TYPE KNA1.
SELECT *
  INTO CORRESPONDING FIELDS OF cust
  FROM  KNA1.
...
ENDSELECT.

Example 10: Select particular fields and multiple records into Corresponding Fields of Table and by looping

DATA cust TYPE KNA1.
SELECT ct~KUNNR ct~NAME1
  INTO CORRESPONDING FIELDS OF cust
  FROM  KNA1 AS ct.
  ...
ENDSELECT.

Example 11: Select records into Corresponding Fields of Table and records store in variable

This example is showing about how to create the variables to store the data set and single line data.

DATA: rsCT TYPE STANDARD TABLE OF KNA1,
      lnCT LIKE LINE OF rsCT.
SELECT ct~KUNNR ct~NAME1
  INTO CORRESPONDING FIELDS OF TABLE rsCT
        " Notice that, we have keyword of TABLE here, 
        " which is different from previous example 
  FROM KNA1 AS ct.
IF sy-subrc EQ 0.
  LOOP AT rsCT INTO lnCT.
        " This statement is similar to PHP code: 
        " foreach ($grid_arrray as $single_row) 
        " to split out every row into other variable 
    WRITE:/ lnCT-KNA1, lnCT-NAME1.
  ENDLOOP.
ENDIF.

Subquery

The subquery are same as regular SQL subquery statement, but just to take note on the “( )”. After we type “(“, we must left a space before write SELECT.

Correct Syntax:

( SELECT ... ORDER BY ABC )

Wrong Syntax:

(SELECT ... ORDER BY ABC)

Example 12: Non-scalar subquery

DATA: Emp TYPE TABLE OF zbemployee WITH HEADER LINE.
SELECT zbemployee~Name zbemployee~Place
  INTO TABLE Emp
  FROM zbemployee
  WHERE zbemployee~Dept_ID IN
                         ( SELECT DEPARTMENT_ID
                           FROM ZBDEPARTMENT
                           WHERE DEPARTMENT_NAME = 'COMPUTERS' ). 
LOOP AT Emp.
  WRITE:/ Emp-ID, Emp-Name, Emp-Place.
ENDLOOP.

Example 13: Scalar subquery

DATA: Emp TYPE TABLE OF zbemployee WITH HEADER LINE.
SELECT zbemployee~Name zbemployee~Place
  INTO TABLE Emp
  FROM zbemployee
  WHERE zbemployee~Dept_ID IN
                         ( SELECT DEPARTMENT_ID
                           FROM ZBDEPARTMENT
                           WHERE DEPARTMENT_AREA = zbemployee~AREA ). 
LOOP AT Emp.
  WRITE:/ Emp-ID, Emp-Name, Emp-Place.
ENDLOOP.
Design a site like this with WordPress.com
Get started