One of the new arrivals with the latest rounds of Technology Refreshes was a table function to retrieve the authority for a particular object. "Wait!" I hear you regular readers say, "Wasn't there already a SQL View added to show that information?" And you are correct in IBM i 7.3 TR2 the OBJECT_PRIVILEGES View was released.
With a Table function I pass it a set of parameters and only the results for those values are returned. If I use a View then the entire View has to be searched for the rows matching the selection criteria. By using a Table function, rather than a View, I can get the information I want quicker. I will demonstrate this in the examples below.
The OBJECT_PRIVILEGES Table function and View have the same columns. The only annoying difference is the name of the authorized user profile in the View is AUTHORIZATION_NAME, while in the Table function it is AUTHORIZATION_USER.
In these example I am only interested in determining if user profile is authorized to use a file, TESTFILE. The profiles authority is held in the column OBJECT_AUTHORITY. Therefore, if I want to see who is authorized to use the file TESTFILE in the library MYLIB I would need to pass the Table function the following:
- Library name
- Object name
- Object type
My SQL Select for the Table function to return the user and authority is:
01 SELECT AUTHORIZATION_USER,OBJECT_AUTHORITY 02 FROM TABLE(QSYS2.OBJECT_PRIVILEGES('MYLIB','TESTFILE','*FILE')) |
Which returns the following results in 430ms:
AUTHORIZATION_USER OBJECT_AUTHORITY ------------------ ---------------- *PUBLIC *EXCLUDE SIMON *ALL |
As you can see my profile, SIMON, has all authority to the object, while everyone else, *PUBLIC, is excluded from it.
Let me do the same with the OBJECT_PRIVILEGES View:
01 SELECT AUTHORIZATION_NAME,OBJECT_AUTHORITY 02 FROM QSYS2.OBJECT_PRIVILEGES 03 WHERE SYSTEM_OBJECT_SCHEMA = 'MYLIB' 04 AND SYSTEM_OBJECT_NAME = 'TESTFILE' 05 AND OBJECT_TYPE = '*FILE' |
The results returned are identical, and they took 520ms. 90ms in this case may not seem like much, but I am using an IBM i which has very little activity on it. I would expect the difference to be greater on a well utilized partition running a fully functional ERP application and people using it.
With this very simple example with no group profiles or authorization lists I could create a program to check if the current user profile is authorized to use TESTFILE:
01 **free 02 dcl-s Authority char(10) ; 02 dcl-s Who char(10) ; 03 exec sql WITH T1 AS 04 (SELECT AUTHORIZATION_USER, 05 OBJECT_AUTHORITY 06 FROM TABLE(QSYS2.OBJECT_PRIVILEGES('MYLIB', 07 'TESTFILE', 08 '*FILE')) 09 WHERE AUTHORIZATION_USER IN (CURRENT_USER,'*PUBLIC')) 10 SELECT OBJECT_AUTHORITY,AUTHORIZATION_USER 11 INTO :Authority,:Who 12 FROM T1 13 ORDER BY AUTHORIZATION_USER DESC 14 FETCH FIRST ROW ONLY ; 15 dsply ('Stmt 1 = ' + %trimr(Authority) + ' (' + %trimr(Who) + ')') ; 16 clear Authority ; 17 exec sql WITH T1 AS 18 (SELECT AUTHORIZATION_USER, 19 OBJECT_AUTHORITY 20 FROM TABLE(QSYS2.OBJECT_PRIVILEGES('MYLIB', 21 'TESTFILE', 22 '*FILE')) 23 WHERE AUTHORIZATION_USER IN ('NOBODY','*PUBLIC')) 24 SELECT OBJECT_AUTHORITY,AUTHORIZATION_USER 25 INTO :Authority,:Who 26 FROM T1 27 ORDER BY AUTHORIZATION_USER DESC 28 FETCH FIRST ROW ONLY ; 29 dsply ('Stmt 2 = ' + %trimr(Authority) + ' (' + %trimr(Who) + ')') ; 30 *inlr = *on ; |
Line 1: My code just has to be free format RPG.
Lines 2 and 3: Definitions for the variables I will be using. The first for the authority and the second for the user profile.
Lines 3 – 14: A common table expression that will build a table in memory, and then use it to return the information I want.
Lines 3 – 9: First part of the table expression. All table expressions start with the word WITH. Following the WITH is the name of the temporary table I am building, T1. Within the parentheses is the Select that uses the OBJECT_PRIVILEGES table function to return the results for TESTFILE. I am only selecting the current user profile, CURRENT_USER and *PUBLIC. The results are placed in the temporary table T1.
Lines 10 – 14: This part of the common table expression uses the data in the temporary table T1 to determine if I am authorized to TESTFILE. By sorting the user profile in descending order will mean that the current user's profile comes first, and then *PUBLIC. The FETCH FIRST ROW ONLY ensures that only one row is fetched. If the user is authorized to the file their profile is retrieved, if they are not then *PUBLIC is retrieved.
Line 15: The results returned are shown using RPG's display operation code, DSPLY.
Line 16: I am clearing the variable Authority just to make sure that you can see that there is no "carry over" from the previous SQL statement.
Lines 17 – 28: Same common table expression before, except I only want the results from the Table function for the profiles NOBODY and *PUBLIC. The temporary table will only contain one row as there will not be a row for NOBODY. Therefore, when the second part of the statement is executed only the results for *PUBLIC are retrieved.
Line 29: Display the results from the second common table expression.
After compiling, when I run this program these are the results shown to me:
DSPLY Stmt 1 = *ALL (SIMON) DSPLY Stmt 2 = *EXCLUDE (*PUBLIC) |
Will I use this Table function? Yes, as I can get the information I need quicker than the View I will be replacing some of the logic I have in some programs where I use the View.
For better example of checking authority, including group profiles see here.
You can learn more about the OBJECT_PRIVILEGES SQL Table function from the IBM website here.
This article was written for IBM i 7.4 TR2 and 7.3 TR8.
No comments:
Post a Comment
To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.
Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.