Thanks for reading.
Lee.
This is a summary of the files available for SQL. We've only just scratched the surface with these. We are only limited by our imagination with what tasks we can automate, improve etc.
Firstly I would identify the journal that is being used. This may change from time to time so it is best to check each and every time you perform these steps. Do a WRKOBJ for the library and main file you are trying to track entries for.
WRKOBJ OBJ(DATALIB/TARGETFILE)
Take option 8=Display Description and page down three
times or do a DSPFD for the given file and search of the Journal name from the output.
Now you know the journal. Perform the action(s) you wish to monitor for
and note the times. (start and Finish)
You can then extract this data from the journal using the DSPJRN command. Below is an example of isolating the entries in a particular environment. I have gone for all files in library MSLTSTDTA in this example but there are plenty of filtering options. I then chose to output the resultant data into a file so that I could query it more easily.
DSPJRN JRN(TB_JRN/JRN0103000) FILE((DATALIB/*ALL)) FROMTIME(280222 074200) TOTIME(280222 074300) OUTPUT(*OUTFILE) OUTFILE(LDARE/LD_JOURNAL). The OUTFILE keyword is optional but will help if you want to perform some queries are a saved dataset.
Please note that the date and time parameters are particularly important as this can take a while to extract otherwise. Just this small sample took a few seconds interactively. If querying for more, you might want to consider submitting the task.
The resultant data file is formatted as follows:-
The main item to look for is the 'Entry Type'. These codes identify when data is inserted,
updated or deleted from the database table as well as if it is rolled back.
https://www.ibm.com/docs/en/i/7.2?topic=information-journal-code-descriptions
Entry Code |
Description |
BR |
Before-image of record updated for rollback
operation |
DR |
Record deleted for rollback operation |
PT |
Record added to a physical file member. If the
file is set up to reuse deleted records, then you may receive either a PT or
PX journal entry for the change |
PX |
Record added directly by RRN (relative record
number) to a physical file member. If the file is set up to reuse deleted
records, then you may receive either a PT or PX journal entry for the change |
UB |
Before-image of a record that is updated in
the physical file member (this entry is present only if IMAGES(*BOTH) is
specified on the STRJRNPF command) |
UP |
After-image of a record that is updated in the
physical file member |
UR |
After-image of a record that is updated for
rollback information |
For a full list of journaling codes you can use this link within the IBM i documentation.
https://www.ibm.com/docs/en/i/7.2?topic=information-all-journal-entries-by-code-type
Today I had a minor task to implement. The task was to initialise some new data in a file.
Typically, I would write a program as an EXCEXTFUN and do my processing via standard 2E code. The problem with little data update programs is that unless you manage them well (i.e. remove them, label them so you can ignore them etc), they start to clutter the model. On the other hand they are handy to have around in case someone needs to do something similar in the future.
However, unless you are a software house, you probably don't care too much that this 'product field' was initialised 8 years ago by xyz user.
That all said and done, my task was to insert a data record and there were some fields that needed to be initialised that contained the business data, and, there was also an AUDIT STAMP for the INSERT. If you don't mind me saying, it was quite a convoluted one at that too with numerous fields. This AUDIT STAMP required a User, Date, Time, Job Number and Job Name among other fields. With 2E all of these are simple to MAP and are available to us via the JOB context.
My task was to implement the data without adding to the setup/fix program maintenance burden and on this occasion we have a few choices.
Or, as I did in this instance.
4. Simply give them a line of SQL I wanted them to execute.
Sweet, job done, but how do I initialise the 2E formatted date, or get the current system date and time from the machine and, where do I get the JOB details from that are so easily available within 2E code via the JOB context.
The answer is as follows: SQL has what it calls global variables (Blue) and functions (Red). It just turns out that some of these are useful for me to update my fields in the AUDIT STAMP.
In order to initialise my fields I just substitute my insert data with the following:-
User Profile = USER
Date = DEC(CURDATE())-19000000
Time = DEC(CURTIME())
Job Number = LEFT(JOB_NAME,6)
Job Name = SUBSTRING(JOB_NAME, LOCATE('/',JOB_NAME,8)+1,10)
You will note that to get the 2E DTE format we simply minus the 19000000. For the standard TIME and USER fields we just use the variables without any manipulation.
For Job Number we need to extract the data the JOB_NAME variable. Usually this is formatted as 123456/LDARE/QPADEV0001 for example. However, for people with longer names it could be 654321/PLONGNAME/EOD, also the job running the task may not be an interactive screen if it was submitted for example.
This means that to get the job name data from the JOB_NAME SQL global variable we need to call a little function that locates and substrings all the data after the 2nd '/'. Given that the JOB_NUMBER is always 6 long I've just arbitrarily started from the 8th character. I could have embedded more LOCATE calls to replace this hardcoded value, but as always, time was against me.
Hopefully, in the future if you need to update a table via SQL, but were put off by now knowing how to get at some of these global variables, the above will stick in your mind.
Thanks for reading.
Lee.
Tip: First of all if you are reading this please benchmark the program(s) and do one adjustment each time to determine what is making the difference for your situation. Don't be tempted into making too many changes at once as you'll never learn the value of each approach. Overtime you will learn which ones make the most difference for your system workload. Above all, you must remember to re-baseline after each set of changes, as not all changes are equal, some may actually slow down your programs.There are numerous strategies for improving overall batch performance. Typically these would included.