In SQ02 transaction, I want to use the check command.
Can I replace the OR operator with another operator, which shorts the command?
Is there an operator like IN, which exists in SQL?
The check command is something like:
CHECK SKB1-BUKRS EQ '1000' or CHECK SKB1-BUKRS EQ '2001' or CHECK SKB1-BUKRS EQ '5221' .
Is there an operator like IN, which exists in SQL?
CHECK SKB1-BUKRS in ('1000', '2001', '5221')
When I write in the Record Processing section:
START-OF-SELECTION.
CHECK skb1-bukrs IN gt_ranges.
then I receive ABAP error:
I am not an expert when it comes to SQ02 I can see however that there are sections for DATA and INITIALIZATION so the example below should work. IN operator in ABAP (excluding OpenSQL of course) can only be used with ranges.
Example:
REPORT zzz.
DATA: gt_ranges TYPE RANGE OF bukrs.
TABLES: skb1.
INITIALIZATION.
gt_ranges = VALUE #(
( sign = 'I' option = 'EQ' low = '1000' )
( sign = 'I' option = 'EQ' low = '2001' )
( sign = 'I' option = 'EQ' low = '5221' )
).
START-OF-SELECTION.
CHECK skb1-bukrs IN gt_ranges.
Related
I created these three radio buttons to define values to the variable TEST.
The first two work just fine: if I click in p_r1 it assigns B and if I click p_r2 it assigns A.
I wanted the third to assign * to get all status i.e A, B, C.
Why doesn't it work? Isn't * a special character that means all like % in SQL?
DATA: TEST TYPE C.
PARAMETERS:
P_R1 RADIOBUTTON GROUP GRP1 DEFAULT 'X',
P_R2 RADIOBUTTON GROUP GRP1,
P_R3 RADIOBUTTON GROUP GRP1.
IF P_R1 = 'X'.
TEST = 'B'.
ELSEIF P_R2 = 'X'.
TEST = 'A'.
ELSEIF P_R3 = 'X'.
TEST = '*'.
ENDIF.
SELECT VBELN,GBSTK
FROM LIKP
WHERE GBSTK = #TEST
INTO TABLE #DATA(IT_FINAL).
CL_DEMO_OUTPUT=>DISPLAY( IT_FINAL ).
A few things to keep in mind to make your requirement work:
An = or EQ in the where condition does not allow for wildcards. I.e. when test equals '*' in your example it will only find entries in the database table where GBSTK equals '*', most probably zero entries
To use wildcards you need to use LIKE instead of = or EQ
The general wild card to mach any string is '%' and not '*'
For more details check the SAP help for SELECT - WHERE for your specific version. Here is the one for 752: https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-US/abapwhere.htm?file=abapwhere.htm
I have the following select statement in ABAP:
SELECT munic~mandt VREFER BIS AB ZZELECDATE ZZCERTDATE CONSYEAR ZDIMO ZZONE_M ZZONE_T USAGE_M USAGE_T M2MC M2MT M2RET EXEMPTMCMT EXEMPRET CHARGEMCMT
INTO corresponding fields of table GT_INSTMUNIC_F
FROM ZCI00_INSTMUNIC AS MUNIC
INNER JOIN EVER AS EV on
MUNIC~POD = EV~VREFER(9).
"where EV~BSTATUS = '14' or EV~BSTATUS = '32'.
My problem with the above statement is that does not recognize the substring/offset operation on the 'ON' clause. If i remove the '(9) then
it recognizes the field, otherwise it gives error:
Field ev~refer is unknown. It is neither in one of the specified tables
nor defined by a "DATA" statement. I have also tried doing something similar in the 'Where' clause, receiving a similar error:
LOOP AT gt_instmunic.
clear wa_gt_instmunic_f.
wa_gt_instmunic_f-mandt = gt_instmunic-mandt.
wa_gt_instmunic_f-bis = gt_instmunic-bis.
wa_gt_instmunic_f-ab = gt_instmunic-ab.
wa_gt_instmunic_f-zzelecdate = gt_instmunic-zzelecdate.
wa_gt_instmunic_f-ZZCERTDATE = gt_instmunic-ZZCERTDATE.
wa_gt_instmunic_f-CONSYEAR = gt_instmunic-CONSYEAR.
wa_gt_instmunic_f-ZDIMO = gt_instmunic-ZDIMO.
wa_gt_instmunic_f-ZZONE_M = gt_instmunic-ZZONE_M.
wa_gt_instmunic_f-ZZONE_T = gt_instmunic-ZZONE_T.
wa_gt_instmunic_f-USAGE_M = gt_instmunic-USAGE_M.
wa_gt_instmunic_f-USAGE_T = gt_instmunic-USAGE_T.
temp_pod = gt_instmunic-pod.
SELECT vrefer
FROM ever
INTO wa_gt_instmunic_f-vrefer
WHERE ( vrefer(9) LIKE temp_pod ). " PROBLEM WITH SUBSTRING
"AND ( BSTATUS = '14' OR BSTATUS = '32' ).
ENDSELECT.
WRITE: / sy-dbcnt.
WRITE: / 'wa is: ', wa_gt_instmunic_f.
WRITE: / 'wa-ever is: ', wa_gt_instmunic_f-vrefer.
APPEND wa_gt_instmunic_f TO gt_instmunic_f.
WRITE: / wa_gt_instmunic_f-vrefer.
ENDLOOP.
itab_size = lines( gt_instmunic_f ).
WRITE: / 'Internal table populated with', itab_size, ' lines'.
The basic task i want to implement is to modify a specific field on one table,
pulling values from another. They have a common field ( pod = vrefer(9) ). Thanks in advance for your time.
If you are on a late enough NetWeaver version, it works on 7.51, you can use the OpenSQL function LEFT or SUBSTRING. Your query would look something like:
SELECT munic~mandt VREFER BIS AB ZZELECDATE ZZCERTDATE CONSYEAR ZDIMO ZZONE_M ZZONE_T USAGE_M USAGE_T M2MC M2MT M2RET EXEMPTMCMT EXEMPRET CHARGEMCMT
FROM ZCI00_INSTMUNIC AS MUNIC
INNER JOIN ever AS ev
ON MUNIC~POD EQ LEFT( EV~VREFER, 9 )
INTO corresponding fields of table GT_INSTMUNIC_F.
Note that the INTO clause needs to move to the end of the command as well.
field(9) is a subset operation that is processed by the ABAP environment and can not be translated into a database-level SQL statement (at least not at the moment, but I'd be surprised if it ever will be). Your best bet is either to select the datasets separately and merge them manually (if both are approximately equally large) or pre-select one and use a FAE/IN clause.
They have a common field ( pod = vrefer(9) )
This is a wrong assumption, because they both are not fields, but a field an other thing.
If you really need to do that task through SQL, I'll suggest you to check native SQL sentences like SUBSTRING and check if you can manage to use them within an EXEC_SQL or (better) the CL_SQL* classes.
I have a procedure with the parameter IT_ATINN:
IMPORTING
REFERENCE(IT_ATINN) TYPE STRING_TABLE
IT_ATINN contains a list of characteristics.
I have the following code:
LOOP AT values_tab INTO DATA(value).
SELECT ( #value-INSTANCE ) AS CUOBJ
FROM IBSYMBOL
WHERE SYMBOL_ID = #value-SYMBOL_ID
AND ATINN ??? "<======== HERE ???
APPENDING TABLE #DATA(ibsymbol_tab).
ENDLOOP.
How can I check if ATINN (in the WHERE clause) is equal to any entry in IT_ATINN?
To achieve what you want (and I assume you want dynamic SELECT fields) you cannot use inline declarations here, both in LOOP and in SELECT:
The structure of the results set must be statically identifiable. The SELECT list and the FROM clause must be specified statically and host variables in the SELECT list must not be generic.
So either you use inline or use dynamics, not both.
Here is the snippet that illustrates Sandra good suggestion:
TYPES: BEGIN OF ty_value_tab,
instance TYPE char18,
symbol_id TYPE id,
END OF ty_value_tab.
DATA: it_atinn TYPE string_table.
DATA: rt_atinn TYPE RANGE OF atinn,
value TYPE ty_value_tab,
values_tab TYPE RANGE OF ty_value_tab,
ibsymbol_tab TYPE TABLE OF ibsymbol.
rt_atinn = VALUE #( FOR value_atinn IN it_atinn ( sign = 'I' option = 'EQ' low = value_atinn ) ).
APPEND VALUE ty_value_tab( instance = 'ATWRT' ) TO values_tab.
LOOP AT values_tab INTO value.
SELECT (value-instance)
FROM ibsymbol
WHERE symbol_id = #value-symbol_id
AND atinn IN #rt_atinn
APPENDING CORRESPONDING FIELDS OF TABLE #ibsymbol_tab.
ENDLOOP.
Overall, it makes no sense select ibsymbol in loop, 'cause it has only 8 fields, so you can easily collect all necessary fields from values_tab and pass them as dynamic fieldstring.
If you wanna use alias CUOBJ for your dynamic field you should add it like this:
LOOP AT values_tab INTO value.
DATA(aliased_value) = value-instance && ` AS cuobj `.
SELECT (aliased_value)
...
Remember, that your alias should exists among ibsymbol fields, otherwise in case of static ibsymbol_tab declaration this statement will throw a short dump.
I have function module which imports my_values
my_values is an custom internal table type of string.
This "my_values" variable contains for example: ["foo", "bar"]
I want to select all values from table Z_MYTAB where the column my_col is in my_values.
I tried this:
SELECT * FROM Z_MYTAB WHERE
my_col in #my_values INTO TABLE #DATA(my_rows).
But this fails with an error message:
table my_values has wrong row structure
(The message was translated to English. The original could be slightly different)
I could loop over my_values but I would like to avoid this.
How to do SQL IN with host variables which are internal tables?
Selection with IN is possible only with a range table.
Conversion of an internal table into a range table can be done like this:
DATA ltr_value TYPE RANGE OF string.
ltr_value = VALUE #( FOR <my_value> IN my_values
( sign = 'I'
option = 'EQ'
low = <my_value> )
).
IN openands could be of 2 types:
SELECT ... WHERE my_col IN ( value1, value2 , value3)
in this case no host expression can be used as right operand
SELECT ... WHERE my_col IN sel_tab[]
in this case sel_tab is a range like
So you could use the following:
DATA sel_tab type range of string.
sel_tab = value #( for ls in my_values ( sign = 'I' option = 'EQ' low = ls ) ).
SELECT * FROM Z_MYTAB WHERE
my_col in #sel_tab[] INTO TABLE #DATA(my_rows).
Best regards
User JozsefSzikszai pointed me to "SELECT FOR ALL ENTRIES".
I found this in the docs:
For an elementary row type, the pseudo component table_line must be specified for comp.
See: https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-US/abenwhere_logexp_itab.htm
IF my_values is initial.
exit.
endif.
SELECT * FROM Z_MYTAB
FOR ALL ENTRIES IN #my_values WHERE
column_name = #my_values-table_line
INTO TABLE #DATA(result_rows).
Is there a way to get a list of all BUKRS which the current user is allowed to see?
I want to use this list as a filter in open sql. Imagine the result of the method I search stored the result in bk_list. Then I could use bk_list like this:
SELECT * FROM some_table WHERE bukrs IN bk_list
Another way to do it, based on the class CL_AUTH_OBJECTS_TO_SQL (officially supported, as of ABAP 7.50, as explained in the documentation of AUTHORITY-CHECK), here the program reads the flights from the read-authorized airline carriers :
DATA(authsql) = cl_auth_objects_to_sql=>create_for_open_sql( ).
authsql->add_authorization_object( EXPORTING
iv_authorization_object = 'S_CARRID'
it_activities = VALUE #( ( auth_field = 'ACTVT' value = '03' ) )
it_field_mapping = VALUE #(
( auth_field = 'CARRID'
view_field = VALUE #( table_ddic_name = 'SFLIGHT' field_name = 'CARRID' ) ) ) ).
DATA(where) = authsql->get_sql_condition( ).
SELECT * FROM sflight INTO TABLE #data(sflights) WHERE (where).
I am afraid you can do it one by one only. Roughly:
SELECT bukrs
INTO TABLE #DATA(lt_t001)
FROM t001
WHERE ... . "Selection critera, if necessary
LOOP AT lt_t001
ASSIGNING FIELD-SYMBOL(<ls_t001>).
DATA(lv_tabix) = sy-tabix.
AUTHORITY-CHECK OBJECT 'F_BKPF_BUK'
ID 'BUKRS' FIELD <ls_t001>-bukrs
ID 'ACTVT' FIELD '03'. "Here you need the proper activity (display '03' /change '02' / etc.)
IF sy-subrc <> 0. "Auth check failed
DELETE lt_t001 INDEX lv_tabix.
ENDIF.
ENDLOOP.
At the end lt_t001 contains only the company codes, for which the user has authorization.