Re: INITIALIZE vs LET
Posted in 2000
Topics: Performance & Tuning, Storage & Space Management, Connectivity: ESQL/C, 4GL & Embedded SQL, Server Administration, Platform-Specific Issues, Internationalization & Character Sets
Jonathan Leffler wrote:
>
> "Lucky Leavell [RIS]" wrote:
> >
> > Version: 7.31
> > OS: AIX 4.3.3
> >
> > I know the FAQ and the 4GL Reference indicate that initializing each field
> > within a record with LET is preferable to using an INITIALIZE record.* but
> > I have run across a situation that would seem to indicate the use of the
> > INITIALIZE approach even if less efficient: In a production system, one of
> > the main tables had two date columns added (with nulls allowed). There was
> > no problem until on of the programs referenced this table containing a
> > "working storage" image of the table (work LIKE record.*). This program
> > initialized each field (column) using LET statements BUT no one had added
> > the initialization for the two new columns. I found it when I began
> > receiving runtime errors (-1210) and also noted the presence of several
> > dates of 12/31/1899 (?).
Unfortunately the INITIALIZE command would not have solved this for you.
> > At first I added two more LET statements but then thought the better
> > solution would be to precede the initialization with an INITIALIZE
> > record.* to NULL.
No difference, except, as Jonathan says below, in performance. Even that
is marginal on a single INITIALIZE statement.
> > I confess I am new to Informix and Informix 4GL (though not to RDBMS and
> > 4GLs). Would anyone care to comment on my situation and conclusions?
>
> Five years ago, this would have started a huge debate. In fact, if you
> found suitably ancient archives, you could probably find several
> versions of those debates.
It could be that these messages have only just appeared on the list for
some strange reason, or it could just be that no one uses 4GL anymore.
;-)
> The use of INITIALIZE versus LET is a pure performance issue; it is not
> actually all that critical unless you do an awful lot of INITIALIZE
> work. INITIALIZE LIKE is much harder on the system; it goes to the
> syscolval or syscolatt table (if you've used UPSCOL) and digs out
> defaults from there. Ugh.
Yes, the most useful use for repetitive initialisation is for arrays of
records.
> The more complex and controversial issue is the use of RECORD LIKE
> Table.*. It has merits; it has demerits. Merits are that most of the
> code adapts to the appearance of new fields in the tables, and the code
> is more succinct. The demerits are that there are enough places where
> the code does not adapt to the new fields to make adding fields
> problematic - witness your problem (and also screen records in forms,
> and therefore the INPUT statements that use them). So, there's a strong
> argument for using explicitly defined record structures citing exactly
> the columns you intend to work with. New columns don't cause trouble
> unless they won't accept nulls, or you cut corners (eg by forgetting to
> list the columns in an INSERT statement).
The point about using the .* notation that people often overlook is that
it is only used at compile time. So the argument that using .* avoids
problems when adding new columns is mute. The code will still have the
old structure and need to be re-compiled before it will pick up the new
structure. Admittedly you may simply need to re-compile instead of
altering code first, but then this would still not make use of
additional columns.
The other aspect of using the .* notation is that the structure of the
variables in the code is then linked directly to the order of the
columns in the table, which seems to fly in the face of relational
design.
> Speaking personally, I've always used the RECORD LIKE Table.* notation
> and found it too valuable to do without. I have even gone to the extent
> of creating empty tables in the database to define convenient record
> types so I can use RECORD LIKE Table.* notation in multiple files,
> rather than having to worry about synchronizing complex record
> definitions across files. That is more an indictment of I4GL than
> anything else; there is no mechanism that allows you to define types
> other than this one.
Whenever I write 4GL coding standards, I always insist on full column
name definitions, i.e. no .* notation. The LIKE clause can still be
used, but on a field by field basis. The reason for this is simple, it
makes the code maintainable. This is because the code contains a full
list of the columns defined in each record.
I know you can argue that it doesn't take long to shell out to dbaccess
and look up the columns, but I can argue that it doesn't take long to
shell out to dbschema and suck in the columns without having to type
every one by hand, and you only need do it once. Also, the record
definitions are retained as they were at the last compile, which makes
debugging table changes a lot easier on large projects.
The Informix 4GL training course actually suggests the definition of a
duplicate record structure, which is initialised to NULL once and then
used to assign null values to the main record using the LET command. The
main requirement of the LET command is that it has the same number of
arguments on each side of the equals sign. This is then seen as a memory
versus performance design issue, similar to Jonathan's disk versus
performance design issue.
> However, there are several people who still lurk on this news group who
> would probably regard that as anathema, so maybe they'll give you their
> version of the truth (I've tried to represent it, but I undoubtedly
> failed to express all the demerits fully).
I don't know about different versions of the truth, but the main thing
is to be consistent. Define your own coding standards and then stick to
them.
Cheers,
--
Mark.
+----------------------------------------------------------+-----------+
| Mark D. Stock mailto:mdstock@mydas.freeserve.co.uk |//////// /|
| http://www.informix.com http://www.informixhandbook.com |///// / //|
| http://www.iiug.org +-----------------------------------+//// / ///|
| |This email will self-destruct in |/// / ////|
| |10 sec. If you received this email |// / /////|
| |in error, sorry about the mess. |/ ////////|
+----------------------+-----------------------------------+-----------+
Mark D. Stock wrote in message <91bm22$d5p$1@news.xmission.com>... > >> > the initialization for the two new columns. I found it when I began >> > receiving runtime errors (-1210) and also noted the presence of several >> > dates of 12/31/1899 (?). > >Unfortunately the INITIALIZE command would not have solved this for you. Yes it would. a date of 12/31/1899 is a representation of all zero bytes in the 4 byte integer used to store dates. Day 1 in the Informix calendar is 01/01/1900 and this is represented by a long integer value of 1. Hence the bizarre date when the bytes contain zero. I believe that NULL in all numeric types (and dates) is represented by NEGATIVE_MAX_INT - not the proper C define for that value, but I hope you know what I mean. A defect of 4GL start-up is that all data memory is cleared to zero bytes, but that means integers and smallints start as 0, chars start as null (I like that) and decimals also start as null. I think floats start as null or is it zero in this circumstance? Dates start as mentioned above - 31/12/1899 which is really ugly. The ugly part here is, the logical initial value of the variables is different depending on the type - inconsistently zero or null. Hence, using INITIALIZE, which does the hard work of getting all fields to their proper NULL value, is definitely a good idea. Jonathan was talking about using one INITIALIZE X.* as opposed to the use of 50 LET statements which can get "left behind" in the face of schema and software changes. Thus, INITIALIZE X.* is safer to use in the sense that it adapts to new schemas - as long as you at least blindly recompile the 4GL. Regarding performance: I'm not surprised when Jonathan claims it used to be a hot topic, because people get really fussy about performance to the Nth degree. But why? Once you get your variables initialised, you are about to trigger potentially thousands of disk reads and writes. Where is your efficiency now? Dammit, I hope I haven't provoked a fresh, endless dialog on the subject. QRT <someone said> >It could be that these messages have only just appeared on the list for >some strange reason, or it could just be that no one uses 4GL anymore. >;-) I wish...
Related threads
- Backing up Logs
- Informix -1210 error - again !
- java.sql.SQLException: Could not position within a table
- Table locking problem.