CDS View parameters in-line syntax form or not? - abap

During a select from CDS with parameters, the into table does it always have to be in-line declaration??
MRP:
#AbapCatalog.sqlViewName: 'ZCDS_PARAM1'
#AbapCatalog.compiler.compareFilter: true
#AccessControl.authorizationCheck: #CHECK
#EndUserText.label: 'Test parameters'
define view ZCDS_PARAM
with parameters
part_number : matnr // Input parameter
as select from mara
{
key matnr as material,
mtart as material_type,
matkl as material_group
}
where
matnr = :part_number
ABAP Program:
SELECT *
FROM zcds_param( part_number = '000000001000001234' )
INTO TABLE #DATA(lt_material). -->should it always be in-line here??
IF sy-subrc IS INITIAL .
WRITE : 'Material Exists!'.
ENDIF.

Inline declarations are not mandatory, but the new syntax is
So you need the # sign, and commas between field names.
(source: I tried it in a 7.53 system)

No, not necessarily.
You can also declare the variable explicitly as TYPE TABLE OF zcds_param (or alternatively a local structure type which has all the fields you want with the correct name and type) and then use INTO CORRESPONDING FIELDS OF TABLE:
DATA lt_material TYPE TABLE OF zcds_param.
SELECT *
FROM zcds_param( part_number = '000000001000001234' )
INTO CORRESPONDING FIELDS OF TABLE #lt_material.

Related

Dynamically read an internal table with more than one key field

Let us say I have the following code:
iob_typedescr ?= cl_abap_typedescr=>describe_by_name( 'HOUSES' ).
iob_structdescr_table ?= iob_typedescr.
it_ddic_all = iob_structdescr_table->get_ddic_field_list( ).
LOOP AT it_ddic_all INTO is_ddic WHERE keyflag EQ 'X'.
APPEND is_ddic TO it_keyfields.
ENDLOOP.
So basically, in the above code I know all of the key fields in the table HOUSES and they are in the table it_keyfields. Now if I had an internal table which had the same structure as HOUSES and wanted to select data from it how would I be able to do this dynamically? If I knew I had only one key then I could do a READ TABLE as follows:
READ TABLE it_internal_table WITH KEY (key_name) = provided_value TRANSPORTING NO FIELDS.
But in this case I may have more than one key in it_keyfields so I am not sure how I could write the READ TABLE statement for this.
You could create a dynamic where condition and use it with LOOP WHERE.
Here is a snippet using table SPFLI as an example.
" variable that contains dynamic where condition later
DATA lv_where TYPE string.
" field-symbol that can contain any data
FIELD-SYMBOLS: <f_field_value> TYPE any.
" define it_internal_table (can be dynamic)
DATA it_internal_table TYPE TABLE OF spfli.
it_internal_table = VALUE #(
( mandt = '001' carrid = '002' connid = '0003' cityfrom = 'PARIS' )
( mandt = '001' carrid = '004' connid = '0005' cityfrom = 'BERLIN' )
).
" define provided values that need to be searched in it_internal_table
DATA(ls_provided_entry) = VALUE spfli( mandt = '001' carrid = '002' connid = '0003' cityfrom = 'PARIS' ).
" create dynamic where condition
LOOP AT it_keyfields ASSIGNING FIELD-SYMBOL(<f_key>).
ASSIGN COMPONENT <f_key>-fieldname OF STRUCTURE ls_provided_entry TO <f_field_value>.
IF sy-subrc = 0.
IF lv_where IS INITIAL.
lv_where = |{ <f_key>-fieldname } = `{ <f_field_value> }`|.
ELSE.
DATA(lv_where_and) = |AND { <f_key>-fieldname } = `{ <f_field_value> }`|.
CONCATENATE lv_where lv_where_and INTO lv_where SEPARATED BY space.
ENDIF.
ENDIF.
ENDLOOP.
" now check with LOOP WHERE if the provided entry exists in it_internal_table
LOOP AT it_internal_table ASSIGNING FIELD-SYMBOL(<f_internal_table_line>) WHERE (lv_where).
" if this point is reached, the entry exists;
" <f_internal_table_line> contains the complete line
WRITE 'The entry exists'.
EXIT.
ENDLOOP.
If you want to handle different numbers of key fields dynamically at runtime then you won't be able to do that with a READ command. However, you can now also read data from an internal table using SELECT and there you can dynamically create a WHERE condition that selects on fields only known during runtime.
From the documentation: Use of SELECT to access an internal table using as an alternative to the statement READ TABLE. Unlike READ TABLE, the statement SELECT offers a (dynamic) WHERE condition and evaluates the field list for the inline declaration. The statement is executed on the AS ABAP and the data in the internal table is not transported to the database.

The field "str_mara" is unknown, but there is a field with the similar name "it_mara"

I want to display the content of Mara table.
types : begin of str_mara,
matnr type mara-matnr,
ernam type mara-ernam,
end of str_mara.
data it_mara type table of str_mara .
select matnr ernam from mara into TABLE it_mara .
loop at it_mara into str_mara.
write:/ str_mara-matnr , str_mara-ernam.
endloop.
Well, there is no variable named str_mara. There is just a type named str_mara.
Just loop using a field symbol as it should be done anyway.
LOOP AT it_mara ASSIGNING FIELD-SYMBOL(<str_mara>).
WRITE: /, <str_mara>-matnr, <str_mara>-ernam.
ENDLOOP.
Type is just a static definition, no memory is allocated, therefore cannot be used on its own.
You can either create a variable with that type or use a inline declaration to create a variable like that.
option 1: data ls_mara type str_mara.
option 2: loop at lt_mara into data(ls_mara).
Or go with Umar's answer :)
BTW, be sure to check your where condition on the access to mara table.
You can also use inline declaration to display content of mara table with fewer line of ABAP code.
SELECT matnr, ernam FROM mara INTO TABLE #DATA(lt_mara) .
LOOP AT lt_mara ASSIGNING FIELD-SYMBOL(<fs_mara>).
WRITE: /, <fs_mara>-matnr, <fs_mara>-ernam.
ENDLOOP.

How to pass single-column table to AMDP method?

I need to pass a table with a single column to an AMDP method which throws the error, the other parameters go fine:
TYPES: BEGIN OF s_so_i,
parent_key TYPE snwd_so_i-parent_key,
product_guid TYPE snwd_pd-node_key,
node_key TYPE snwd_so_i-node_key,
END OF s_so_i.
TYPES: BEGIN OF s_product,
product_guid TYPE snwd_pd-node_key,
category TYPE snwd_pd-category,
END OF s_product.
TYPES: tt_product TYPE STANDARD TABLE OF s_product,
tt_so TYPE STANDARD TABLE OF snwd_node_key, "<-- error
tt_so_i TYPE STANDARD TABLE OF s_so_i.
How should I define it?
instead of using snwd_node_key I can suggest you to use EGUID_S.
EGUID_S is a structure with only including a single column with RAW16 as SYSUUID
instead of
tt_so TYPE STANDARD TABLE OF snwd_node_key,
use
tt_so TYPE STANDARD TABLE OF EGUID_S,
Adding this solved the problem:
TYPES: BEGIN OF s_so,
so_guid TYPE snwd_so-node_key,
END OF s_so.
TYPES: tt_product TYPE STANDARD TABLE OF s_product,
tt_so_i TYPE STANDARD TABLE OF s_so_i,
tt_so TYPE STANDARD TABLE OF s_so. <--
So it seems the table type must point to a structure type.

Set parameter name as an internal table name

I wanted to know if it is possible to make the input parameter name as an internal table.
Please have a look in the snippet of the code. In this report I am trying to take p_dbtab as a table name then make an internal table i_temp of the type p_dbtab.
REPORT ZPRACTICDYNAMIC.
SELECTION-SCREEN BEGIN OF BLOCK 1.
PARAMETERS:
p_dbtab TYPE tabname DEFAULT 'FARR_D_FULFILLMT' OBLIGATORY.
SELECTION-SCREEN END OF BLOCK 1.
DATA: it_tab TYPE STANDARD TABLE OF p_dbtab.
this will work:
data: rt_data type REF TO data.
PARAMETERS: p_dbtab TYPE tabname DEFAULT 'FARR_D_FULFILLMT' OBLIGATORY.
FIELD-SYMBOLS: <t_data> type any TABLE.
CREATE DATA rt_data type STANDARD TABLE OF (p_dbtab).
assign rt_data->* to <t_data>.

What is wrong with the following ABAP code

REPORT zbc400_figure157.
TYPES: BEGIN OF t_conn,
cityfrom TYPE spfli-cityfrom,
cityto TYPE spfli-cityto,
carrid TYPE spfli-carrid,
connid TYPE spfli-connid,
END OF t_conn.
DATA:
conn_list LIKE STANDARD TABLE OF t_conn,
startline LIKE sy-tabix,
BEGIN OF wa_travel,
dest TYPE spfli-cityto,
cofl_list LIKE conn_list,
END OF wa_travel,
travel_list LIKE SORTED TABLE OF wa_travel WITH UNIQUE KEY dest.
FIELD-SYMBOLS:
<fs_conn> TYPE t_conn,
<fs_conn_int> TYPE t_conn,
<fs_travel> TYPE wa_travel.
PARAMETERS pa_start TYPE spfli-cityfrom DEFAULT 'FRANKFURT'.
SELECT carrid cityfrom cityto
FROM spfli
INTO CORRESPONDING FIELDS OF TABLE conn_list.
SORT conn_list BY cityfrom cityto ASCENDING AS TEXT.
** build up nested table.
LOOP AT conn_list ASSIGNING <fs_conn> WHERE cityfrom = pa_start.
CLEAR wa_travel.
wa_travel-dest = <fs_conn>-cityto.
READ TABLE conn_list
WITH KEY cityfrom = wa_travel-dest
TRANSPORTING NO FIELDS
BINARY SEARCH.
startline = sy-tabix.
LOOP AT conn_list ASSIGNING <fs_conn_int>
FROM startline.
IF <fs_conn_int>-cityfrom <> wa_travel-dest.
EXIT.
ENDIF.
APPEND <fs_conn_int> TO wa_travel-cofl_list.
ENDLOOP.
SORT wa_travel-cofl_list BY cityto carrid ASCENDING AS TEXT.
INSERT wa_travel INTO TABLE travel_list.
ENDLOOP.
Error: Field "T_CONN" is unknown. It is neither in one of the specified tables nor defined by a "DATA" statement . . . . . . . . . .
We declare an inner table COFL_LIST and an outer table TRAVEL_LIST with corrosponding work areas. An internal table CONN_LIST buffers all of the flight connections and sorts them.
The program uses 3 tables, inner table, outer table and an internal table.
I made the changes in the program as suggested by LPK:
conn_list TYPE STANDARD TABLE OF t_conn,
However, now the problem is in line:
FIELD-SYMBOLS:
<fs_conn> TYPE t_conn,
<fs_conn_int> TYPE t_conn,
<fs_travel> TYPE wa_travel.
Error: The type "WA_TRAVEL" is unknown.
In the program wa_travel variable is already defined in it's BEGIN OF wa_travel and END OF wa_travel block. Why can't the system pick this up?
This line is wrong:
conn_list LIKE STANDARD TABLE OF t_conn,
T_CONN is a type and therefore you have to use TYPE instead of LIKE.
You can find an explanation about the difference here.
The declaration is not correct...
FIELD-SYMBOLS:
TYPE t_conn,
TYPE t_conn,
TYPE wa_travel.
Should be
FIELD-SYMBOLS:
TYPE t_conn,
TYPE t_conn,
LIKE wa_travel.
You need to check with the link provided in the previous answer... or you can use the following from the Help Portal on TYPE & LIKE