I have said before that there are many ways to skin a cat and with development regardless of tools and languages used, it is no different.
To date I have concentrated on the generic principles of development and also on the CA 2E tool from Computer Associates. I have put quite a few posts in place around 2E with many many more to go. To be honest I am less than 20% through what I intend to post from the technical perspective and I have barely touched the Plex product. Still good things come to those who wait.
http://www.dictionary.com/ has the definition of 'composite' as "made up of disparate or separate parts or elements". In 2E terms it means the linking of two or more functions to serve a business purpose. For example to clear a file using 2e function types you may either call a EXCUSRPGM and use the operating system or you may chose to use a RTVOBJ with no restrictor/positioner keys and then call a DLTOBJ for each record in the file. You could also call a SQL routine, embed the OS400 command in a message etc etc etc. You get my point. The composite in this example is the RTVOBJ/DLTOBJ combination.
There are other composite types that are more often encountered. Especially around creating or changing records in a database file (table for the SQLites amongst you).
I have created functions named CRT/CHG or CHG/CRT to solve a common problem of what do do if the record does or does not already exist in the database.
This lead me to consider is there is a preferred default method and are there any variations. Once again a big thanks to Ray for his contributions here.
CHG/CRT v CRT/CHG
There are times when if a CRTOBJ fails due to the record already being in existence or a CHGOBJ fails because the record does not exist. To solve these issues we generally create combination functions named either CRT/CHG or CHG/CRT. Or if you follow my recommended standards and if these are default functions then they would be named *CRT/CHG or *CHG/CRT.
In general you should select the one that is most likely to succeed, so depending on your knowledge of the environment and the data being processed, if the record is likely to not be there then you need to use the CRT/CHG combo.
There are some performance considerations over and above the availability or otherwise of the underlying record.
A CHGOBJ that contains a CRTOBJ if a record does not exist is inefficient as it generates the following code. This is particularly true for SQL generation.
Pseudo SQL Code
DECLARE CURSOR FOR UPDATE
FETCH
UPDATE if record found
INSERT if no record found
CLOSE CURSOR
Pseudo RPG Code
CHAIN
UPDATE if record found
SETLL & INSERT if no record found
An alternative coding style with a CRTOBJ calling a CHGOBJ if record already exists will generate the following code. The CHGOBJ must be an 'update style' that does not use a cursor.
Pseudo SQL Code
SELECT by key
INSERT if record not found
UPDATE if record exists
Pseudo RPG Code
SETLL
WRITE if record not found
CHAIN & UPDATE if record exists
A CHGOBJ with a little bit of grunt.
To create an 'Update style' CHGOBJ:-
For performance reasons we need to omit the prior SELECT generated for SQL CHGOBJs. This is mainly for CHGOBJs called repeatedly in batch type processing. But it can only be done if there is no requirement to read existing DB1 context fields. To do an immediate update we need to create a special version of a CHGOBJ called an UPDATE function. This will have following characteristics:-
1 - Ensure that there is no coding inside the CHGOBJ. Commonly we must transfer the timestamp coding from inside the CHGOBJ to input parameters and setting the timestamp fields directly on the CHGOBJ call.
2 - Ensure that the CHGOBJ parameters are defined in the default way using the UPD ACP structure. Fields that do not need to be changed should be made NEITHER parameters.
3 - The CHGOBJ function option for Null Update Suppression should be = No. This ensures that there is no attempt to perform an image check.
4 - UPD style CHGOBJs should ideally only have the attributes that are being changed. This is particularly important when calling a CHGOBJ from inside a RTVOBJ over the same file. Passing in DB1 context for those filed not being changed is not conducive to performance since the optimiser cannot differentiate between changed & non changed attributes.
Thoughts, opinions, concerns or fanmail gratefully accepted. Cash donations to charity please.
Thanks for reading.
Lee.
No comments:
Post a Comment
Thanks for considering leaving some comments about my random rants for everything software development and more.