TCode per department and user - abap

I have a strange request from the business. They want a report where they give a tcode or tcodes and the program will check which department has this/these and which users.
OK, I have found a couple of tables like AGR_TCODES (Assignment of roles to Tcodes), AGR_USERS (Assignment of roles to users) and USER_ADDR (Users by address data) to find what I want.
My question is: if a user has access to a tcode that it does not belong to one of his role, how can we catch this?
For example: I have access to VA03 but none of my roles is connected to this tcode.
Is there any way to catch this?

Try transaction S_BCE_68001397 (user selection based on permission values), select for permission object S_TCODE and the transaction as the permission value should give you the list you need. Transaction S_BCE_68001398 does the same, but doesn't allow you to query users for other permission objects.
The problem with these reports is that it might be either difficult or tedious to check for a large number of transaction codes. You could have a look at the source code of those transactions, report RSUSR002 and see if you can use the locally defined classes the reports use to query for multiple transaction codes and create a report based on your specific requirements.

Yoy can use tables AGR_1251 and AGR_USERS.
AGR_1251 will give you the Roles with the S_TCODE object and the Value = tcode given by the user.
Then you go to table AGR_USERS and get the users for the role with the S_TCODE= tcode.
SELECT adr_users~UNAME
FROM AGR_USERS JOIN AGR_1251 ON AGR_USERS~MANDT = AGR_1251~MANDT
and AGR_USERS~AGR_NAME = AGR_1251~AGR_NAME
WHERE AGR_1251~OBJECT = 'S_TCODE'
AND AGR_1251~LOW = param_tcode.
Hope this helps

Finally with the help of Dirk Trilsbeek I found the solution to what I was looking for. Here is the selection:
SELECT DISTINCT a~von e~ttext d~department d~bname d~name_first
d~name_last d~name_textc c~profile
INTO CORRESPONDING FIELDS OF TABLE gt_tcode_per_dprtm_usr
FROM ust12 AS a
INNER JOIN ust10s AS b
ON a~auth = b~auth AND
a~objct = b~objct AND
a~aktps = b~aktps
INNER JOIN ust04 AS c
ON b~profn = c~profile
INNER JOIN user_addr AS d
ON c~bname = d~bname
INNER JOIN tstct AS e
ON e~tcode = a~von
WHERE a~objct = 'S_TCODE' AND
a~von IN so_tcode AND
e~sprsl = 'G'.
I want to thank all of you for your answers.

Related

How to improve the performance of SQL query in Oracle DB

one of the tab is broken in the Application (when hit that tab it keeps on rotating and calling the particular service and getting 404 error after sometime). we created indexes for few columns in Application DB to see if that improves performance. Creating indexes didn't make much difference.
so We planned to rewrite the sql query to improve the performance and fix it.
select distinct
editedUser.*
from
users editedUser,
relationship_ref editedUserRelationship,
users approvingUser,
user_role approvingUserRoles,
role_permission approvingUserRolePermissions,
account approvingUserAccount
where
approvingUser.user_id = 175263
and approvingUser.user_id = approvingUserRoles.user_id
and approvingUserRoles.role_id = approvingUserRolePermissions.role_id
and approvingUserRoles.user_role_status_id = 2
and editedUserRelationship.relationship_id =
editedUser.submitted_relationship_id
and (approvingUser.account_id = approvingUserAccount.account_id
or approvingUser.account_id is null)
and editedUser.review_status = 'R'
and approvingUserRolePermissions.permission_id =
editedUserRelationship.view_pending_permission_id;
It is taking nearly 6 mins.So can one please suggest how to use the proper joins in this query. It has 36 columns and 30,000 records.
Rearranged in a style that is easier to read (to me at least), I get this:
select distinct ed.*
from users ap
join user_role ro
on ro.user_id = ap.user_id
join account ac
on ac.account_id = ap.account_id or ap.account_id is null
join role_permission rp
on rp.role_id = ro.role_id
join relationship_ref re
on re.view_pending_permission_id = rp.permission_id
join users ed
on ed.submitted_relationship_id = re.relationship_id
where au.user_id = 175263
and ro.user_role_status_id = 2
and ed.review_status = 'R'
How many approving users have null account_id? For any of those, you retrieve all accounts in the system. Is that actually the business requirement? I'm not sure that it makes any sense. The query does not make any further use of that table, so perhaps you can remove the account join entirely.

How to join two queries in access

I am incapable of make a query that return me a results as follows:
TABLES: series, usuarios, siguiendo, valoraciones_personales
Each table has got this records:
example: field1(value), field2(value),...
series (I refer a tv show, I am spanish and here we say "serie=tv_show")
1. id_serie(1),id_titulo('Sons of anarchy')
2. id_serie(2),id_titulo('Lost')
usuarios (user)
1. id_usuario(1), nick('david')
siguiendo (a usser follow a series)
1. id_serie(1),id_usuario(1)
2. id_serie(2),id_usuario(1)
valoraciones_personales (personal assessments)
1. id_serie(1),id_usuario(1),nota(8)
Ok, what I want is a result with all records of the table siguiendo, and if that user valued one of that series, it must shows the score (nota in spanish), and if that user didnĀ“t scored that series, I want to show "without score".
The view I want:
*titulo, nota*
- Sons of anarchy, 8
- Lost, without score
Can anyone help me?
Specifically in MSACCESS
Create a query called something like AllUserSeries
SELECT
U.UserID
,U.FullName
,S.SeriesID
,S.SeriesName
FROM
usuarios as U
,series as S
This is the equivalent of a cross join
Then another:
SELECT
A.FullName
,A.SeriesName
,Nz(Cstr(R.Score),"Not Rated") as Rating
FROM
AllUserSeries AS A
LEFT OUTER JOIN valoraciones_personales AS R
ON A.UserID = R.UserID
AND A.SeriesID = R.SeriesID
WHERE
A.UserID = #UserID
The tricky bit is getting a list of all the series a user may have liked. to do this normally i would do a cross join to get all permutations that could exist, then left join from there to the ratings table using Nz to handle null values as you see fit.
*sorry for kinda making up the other column names it was easier for me to use English hope that okay :D

SQL - SELECT with JOINED Table

I'm trying to do a selection from the user tabel. For each user i would like to sum the Timediff for all posts in tblregtime for current user for given date parameters.
Problem is that i need to get information even if there is no registration done at the given date for current user. If no registration i need output that current user has TotalDiff=0. My current SQL doesn't work in this way. It will just give the fname,lname and TotalDiff if there is a post in tblregtime
sql:
select u.fname,u.lname, sum(cast(TIME_TO_SEC(TIMEDIFF(r.edate,r.sdate)) AS UNSIGNED)-r.break_time) as TotalDiff
from tbluser u
RIGHT OUTER JOIN tblregtime r on r.userid=u.id where r.projectid=21
and year(r.sdate)=2013 and month(r.sdate)=10 and day(r.sdate)=7
If you are trying to keep everything in tbluser, then you want a left join instead of a right join. However, you also need to move the where conditions into the on clause. Otherwise, when there is no match, the comparisons will fail (because the r. values will be NULL):
select u.fname,u.lname,
sum(cast(TIME_TO_SEC(TIMEDIFF(r.edate,r.sdate)) AS UNSIGNED)-r.break_time) as TotalDiff
from tbluser u LEFT JOIN
tblregtime r
on r.userid = u.id and
r.projectid = 21 and
year(r.sdate) = 2013 and month(r.sdate) = 10 and day(r.sdate) = 7;
I would also recommend that you change the final date comparison to something like:
r.sdate = '2013-10-07'
This form would allow the use of an index on r.sdate. As you have written it, the SQL engine (at least the SQL engines I am familiar with) would not be smart enough to use the index.

Match All Records

I am having difficulty with writing an SQL query for my application. Below shows a screenshot of some of the tables in my database.
Please let me explain how a section of my application works, and then I can show you the problem I am having with my SQL query.
A User can create an application form on my system (dbo.Form). An application form consists of several sections, one of those sections is Employment History (dbo.FormEmployment). An employment record includes details like employer name, start date etc, but also a gradeID. A User can add one or more employment records to the table dbo.FormEmployment.
A system administrator can add a Shift (dbo.Shift) to the system, and also then assign Grades to a Shift. These Grades are recorded in the dbo.ShiftGrade table. A Shift can be assigned 1 or more Grades, i.e. it could be assigned 1,2,3,4 or 5 Grades.
When the system administrator has added the Shift and Shift Grades, I then want to perform an SQL query to return a list of Users whose Grades match that of the Grades assigned to a Shift (remember the User adds their Grade when they add an employment record).
I have written the following SQL query which works, however, the issue with this query is that it returns a list of Users, that have any Grade that matches that of the Grades assigned to a Shift.
SELECT u.userID, u.userTypeID, u.firstName, u.lastName, u.email, u.password,
u.contactNumber, u.organisationID, u.emailVerificationCode, u.mobileVerificationCode,
u.userStatusID, u.AddedBy, u.AddedDate, u.ModifiedBy, u.ModifiedDate
FROM [User] u
--Check Grades Match
WHERE u.userID IN
(
SELECT f.locumID
FROM dbo.Form f, dbo.FormEmployment emp
WHERE f.formID = emp.formID
AND emp.statusID = 101
AND emp.workYN = 1
AND emp.gradeID IN (
select gradeID from dbo.ShiftGrade where shiftID = #p0
)
)
You can see I am using the IN statement to do this. However, I only want to return a list of Users who can match exactly the same Grades that have been assigned to a Shift. Therefore, if a Shift has been assigned 3 Grades, then I want a List of Users who also have the exact same three Grades to be returned.
I apologise for the lengthy post, I just thought it would be better explained this way.
Any feedback or help with this would be greatly appreciated.
select u.*
from dbo.Users u
join dbo.Form f on u.? = f.formId
join dbo.FormEmployment fe on fe.formId = f.formId
join dbo.Grade g on g.gradeId = fe.gradeId
join dbo.ShiftGrade shg on shg.gradeId =g.gradeId
join dbo.Shift sh on sh.shiftId = shg.shiftId
where
sh.shiftId = -- recently added shift id
and g.gradeId == -- recently added grade id

running queries on more than one table

I'm trying to make a query in two tables:
SIMPLE_PERSON with 3 fields (name, grid and Social Security Card)
INDIVIDUAL_AGGREGATE with 4 fields: grid(PK), type( D(Driver) or C(client)), code, simple_person(foreign key of simple_person))
When I register some person, I have to save they on the SIMPLE_PERSON and set the type of aggregate that they are ( Driver or Client). And cannot have two equal social security card numbers.
With AJAX, I throw a checker that returns an alert box if the SSC is registered, but my SQL query doesn't work. I need to making a query that returns to me if a Social Security Card is already registered. I'm trying to use EXISTS, but I haven't had much success:
SELECT simple_person.name
FROM simple_person
WHERE SSC = 'SSC_NUMBER'
AND EXISTS (SELECT individual_aggregate.code FROM individual_aggregate
WHERE code = 'xx'
AND individual_aggregate.type = 'D');
Somebody can help me to make this query work?
did you wanted to check if there is a person that registered on a some Social security number?
if yes what i did is join between the two tables
and return the rows that equal to a specific social security number.
you can add to the WHERE statement (AND IA.code = 'XX' AND IA.Type = 'D')
SELECT SP.Name
FROM simple_person AS SP
INNER JOIN individual_aggregate AS IA ON SP.grid = IA.grid
WHERE SP.SSC = {someNumber}
helped you?
Your subquery in the EXISTS clause isn't actually hitting a table, view or other.
Your sub-select is missing the FROM clause.
SELECT
individual_aggregate.code
FROM
individual_aggregate
WHERE
code = 'xx'
AND individual_aggregate.type = 'D'
Regards
Sigersted