I have the following 3 tables with data:
ZMYTABLE
with columns: ZUSER
& ZTCODE
and 2 records
elias VA01
elias VF01
AGR_1251
with the records
SD_role VA01
SD2_role VA01
SD3_role VA01
SD_role VA02
FI_role VF01
FI_role VF02
AGR_USERS
with records
elias SD_role
elias SD2_role
maria SD_role
maria FI_role
I want to display the fields ZUSER
, ZTCODE
and AGR_NAME
.
I want all records from ZMYTABLE
with the role in which exists each tcode for the specific user, namely:
ZUSER---ZTCODE---AGRNAME
elias---VA01-----SD_role
elias---VA01-----SD2_role
elias---VF01-----
Can someone tell me how to do this by joining the 3 tables with exactly one ABAP SQL statement, in ABAP V7.01 sp07?
I found it easier to use UNION
, the first SELECT will return the lines which correspond to the transactions which match one of the user roles (elias, VA01, SD_role and SD2_role), and the second one will return the lines which correspond to the transactions which don't match any of the user roles (elias, VF01).
I tested it by replacing ZMYTABLE with USR07.
SELECT usr07~bname, usr07~tcode, agr_1251~agr_name
FROM agr_users
INNER JOIN usr07
ON usr07~bname EQ agr_users~uname
INNER JOIN agr_1251
ON agr_1251~agr_name EQ agr_users~agr_name
AND agr_1251~low EQ usr07~tcode
UNION
SELECT DISTINCT usr07~bname, usr07~tcode, ' ' AS agr_name
FROM usr07
WHERE NOT EXISTS (
SELECT * FROM agr_users
INNER JOIN agr_1251
ON agr_1251~agr_name EQ agr_users~agr_name
WHERE usr07~bname EQ agr_users~uname
AND agr_1251~low EQ usr07~tcode )
INTO TABLE @DATA(result).
It gives these results (formatted for ABAP Unit) :
SORT result BY bname tcode agr_name.
TYPES ty_result LIKE result.
assert_equals( act = result exp = VALUE ty_result(
( bname = 'elias' tcode = 'VA01' agr_name = 'SD2_role' )
( bname = 'elias' tcode = 'VA01' agr_name = 'SD_role' )
( bname = 'elias' tcode = 'VF01' agr_name = '' ) ) ).
Below is the ABAP Unit test code to demonstrate that it works, and you may play with it if needed. You need ABAP 7.52 (Open SQL Test Double Framework).
CLASS ltc_main DEFINITION FOR TESTING DURATION SHORT RISK LEVEL HARMLESS
INHERITING FROM cl_aunit_assert.
PRIVATE SECTION.
METHODS test FOR TESTING.
CLASS-METHODS: class_setup, class_teardown.
CLASS-DATA environment TYPE REF TO if_osql_test_environment.
ENDCLASS.
CLASS ltc_main IMPLEMENTATION.
METHOD class_setup.
environment = cl_osql_test_environment=>create( i_dependency_list = VALUE #(
( 'USR07' ) ( 'AGR_1251' ) ( 'AGR_USERS' ) ) ).
ENDMETHOD.
METHOD test.
TYPES ty_usr07 TYPE STANDARD TABLE OF usr07 WITH EMPTY KEY.
TYPES ty_agr_1251 TYPE STANDARD TABLE OF agr_1251 WITH EMPTY KEY.
TYPES ty_agr_users TYPE STANDARD TABLE OF agr_users WITH EMPTY KEY.
environment->insert_test_data( EXPORTING i_data = VALUE ty_usr07(
( bname = 'elias' tcode = 'VA01' timestamp = 1 )
( bname = 'elias' tcode = 'VF01' timestamp = 2 ) ) ).
environment->insert_test_data( EXPORTING i_data = VALUE ty_agr_1251(
( agr_name = 'SD_role' low = 'VA01' counter = 1 )
( agr_name = 'SD2_role' low = 'VA01' counter = 1 )
( agr_name = 'SD3_role' low = 'VA01' counter = 1 )
( agr_name = 'SD_role ' low = 'VA02' counter = 2 )
( agr_name = 'FI_role ' low = 'VF01' counter = 1 )
( agr_name = 'FI_role ' low = 'VF02' counter = 2 ) ) ).
environment->insert_test_data( EXPORTING i_data = VALUE ty_agr_users(
( uname = 'elias' agr_name = 'SD_role ' )
( uname = 'elias' agr_name = 'SD2_role' )
( uname = 'maria' agr_name = 'SD_role ' )
( uname = 'maria' agr_name = 'FI_role ' ) ) ).
"<==== here insert the ABAP SQL provided above & expectations to verify
ROLLBACK WORK.
ENDMETHOD.
METHOD class_teardown.
environment->destroy( ).
ENDMETHOD.
ENDCLASS.
If you have an ABAP release < 7.50, UNION
is impossible, instead define 2 separate SELECT
, the first one with INTO TABLE @DATA(result)
and the second one with APPENDING TABLE result
.
PS: I also did the following tests, inspired from the other answers, they don't work (most of them return the role "FI_role" for "VF01", instead of an empty role).
Failed attempt 1-A:
SELECT usr07~bname, usr07~tcode, agr_1251~agr_name
FROM agr_users
INNER JOIN usr07
ON usr07~bname EQ agr_users~uname
INNER JOIN agr_1251
ON agr_1251~agr_name EQ agr_users~agr_name AND
agr_1251~low EQ usr07~tcode
INTO TABLE @DATA(result).
SORT result BY bname tcode agr_name.
TYPES ty_result LIKE result.
assert_equals( act = result exp = VALUE ty_result(
( bname = 'elias' tcode = 'VA01' agr_name = 'SD2_role' )
( bname = 'elias' tcode = 'VA01' agr_name = 'SD_role' ) ) ).
Failed attempt 1-B:
SELECT DISTINCT usr07~bname,
usr07~tcode,
agr_1251~agr_name
FROM usr07
INNER JOIN agr_1251
ON agr_1251~low EQ usr07~tcode
INNER JOIN agr_users
ON agr_users~uname EQ usr07~bname
WHERE
agr_users~agr_name EQ agr_1251~agr_name OR EXISTS (
SELECT *
FROM agr_users AS inner_agr_users
INNER JOIN agr_1251 AS inner_agr_1251
ON inner_agr_1251~agr_name EQ inner_agr_users~agr_name
WHERE
inner_agr_users~agr_name EQ agr_1251~agr_name
)
INTO TABLE @DATA(result).
SORT result BY bname tcode agr_name.
TYPES ty_result LIKE result.
assert_equals( act = result exp = VALUE ty_result(
( bname = 'elias' tcode = 'VA01' agr_name = 'SD2_role' )
( bname = 'elias' tcode = 'VA01' agr_name = 'SD_role' )
( bname = 'elias' tcode = 'VF01' agr_name = 'FI_role' ) ) ).
Failed attempt 2:
SELECT b~bname, b~tcode, a~agr_name
FROM agr_1251 as a
INNER JOIN usr07 as b
ON a~low EQ b~tcode
INNER JOIN agr_users as c
ON a~agr_name EQ c~agr_name
INTO TABLE @DATA(result).
SORT result BY bname tcode agr_name.
TYPES ty_result LIKE result.
assert_equals( act = result exp = VALUE ty_result(
( bname = 'elias' tcode = 'VA01' agr_name = 'SD2_role' )
( bname = 'elias' tcode = 'VA01' agr_name = 'SD_role' )
( bname = 'elias' tcode = 'VA01' agr_name = 'SD_role' )
( bname = 'elias' tcode = 'VF01' agr_name = 'FI_role' ) ) ).
DB access should look like this:
SELECT DISTINCT zmytable~zuser,
zmytable~ztcode,
agr_1251~agr_name
FROM zmytable
INNER JOIN agr_1251
ON agr_1251.ztcode EQ zmytable.ztcode
INNER JOIN agr_users
ON agr_users.zuser EQ zmytable.zuser
WHERE
agr_users.agr_name EQ agr_1251.agr_name OR EXISTS(
SELECT *
FROM agr_users AS inner_agr_users
INNER JOIN agr_1251 AS inner_agr_1251
ON inner_agr_1251.agr_name EQ inner_agr_users.agr_name
WHERE
inner_agr_users.agr_name EQ agr_1251.agr_name
).
Add INTO
clause and deal with the output.
To access all records, you should use DB Access as below.
SELECT b~zuser, b~ztcode, a~agr_name
FROM agr_1251 as a
INNER JOIN zmytable as b
ON a~tcode EQ b~tcode
INNER JOIN agr_user as c
ON a~agr_name EQ c~agr_name.
Rest you can use ABAP to display output.
Triple Join works for version > 7.4.
SELECT c~zuser, a~zrole, c~ztcode INTO CORRESPONDING FIELDS OF TABLE @lt_result
FROM agr_users AS a INNER JOIN agr_1251 AS b
ON a~zrole = b~zrole
RIGHT OUTER JOIN zmytable AS c
ON c~ztcode = b~ztcode AND c~zuser = a~zuser.
I have been looking in which table the SU53 report contents is stored. It seems it's stored in USR07 and USR07_EXT for higher releases.
This is how I got to this post.
However, this table is always empty ALTHOUGH there is clearly SU53 content for a different userID than mine.
Really scratching my head here, because if you hit F1 in the SU53 report and then the wrench icon, it points to table USR07, which is then empty.
What am I missing ? Thanks
Oh by the way, I am looking for a table that retains the last auth check fail per user. We want to use this info so a chatbot can grab this info and cross-reference with UST12 and ultimately the originating single role. We have a setup where each auth-object-field-value combination is included in exactly 1 single role. Otherwise, the chatbot would have to present a list of multiple single role matches to the end-user, of whom we know he/she will pick any role. So, having only 1 match, the chatbot can do it's single role requesting work on behalf of that user.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.