Re: Using LIKE to define records in 4GL
Posted in 1995
This subject was discussed extensively at the end of January 1995 (starting on the 24th or 25th according to my records). Maybe you should go and read the archive records of that discussion. Cathy Kipp has summarised the conclusions of that adequately in a recent posting. I'm going to pick up on a common misconception which is tangential to the rest of the discussion. Again, this has been dealt with previously, but it bears reiteration. >From: Mark Denham <Mark.Denham@bbc.co.uk> >Date: Fri, 28 Jul 95 10:31:00 PDT >X-Informix-List-Id: <list.7064> > >I feel like an argument. Has anyone got any views on the use of LIKE to >define RECORDS in 4GL, or any limitations on how you use it based on >personal experience? > >To start the ball rolling I hate it and where I can insist that it is not >used. I particularly dislike its use in GLOBALS files! > >Here are my reasons: > >1) When used in the globals file, it results in the runtime app opening > the db and attempting to locate the tables of interest. In an > environment where you have multiple copies of the db, not necessarily > with the same name, this method forces you to have to recompile the > programs for each db, or to have a dummy db that is used to compile and > is left in existance in each db enviroment. If your programs need to run in a multi-database environment, you have to write them more carefully than you do in a single-database environment. Mark's observation about the database being present at run-time is only correct if the MAIN program is compiled with a non-procedural DATABASE statement in the source file. The program does not check at run-time whether the tables which were referenced at compile-time are present or have the same type. It simply executes the statements on the assumption that they are present, relying on the Engine to complain if they aren't, or if the structure has changed too much. If you are designing your code to work with different databases selected at run-time, your archetypal MAIN program should look like: -- No GLOBALS here, and no DATABASE statement here either! MAIN DEFER INTERRUPT DEFER QUIT -- Or maybe not CALL standard_options() CALL main_program() END MAIN DEFER statements are only allowed in MAIN, which is why they are present. Because this code has no DATABASE statement in it, no database is selected automatically. The function standard_options() is responsible for a number of startup operations, one of which is selecting the run-time database. It can also be used to set standard options, such as the various function keys (hence it's name), and it can start the error log, and it can do security checking and anything else that is necessary. The operational code for the application is in the function main_program() which is written in a separate file. You might or might not want to add a CLEAR SCREEN and an EXIT PROGRAM 0 after the call to main_program(). This technique means that you can have test and production versions of the database, possibly with the same name in different OnLine systems, or with different names in the same OnLine system. You can have a separate database for each company in a group run by a holding company, etc. If I was doing production coding and in charge of standards, this structure would be be used in all my projects. Indeed, the code for MAIN might even be in a library, and no programmer would ever write a MAIN program; they would use the library version. In practice, it isn't quite that simple since there are interactive programs which have a screen attached, and batch programs (typically run by cron) which don't necessarily have a screen attached, and you may need different startup sequences for the two, but the general idea is definitely valid. I have used standard options functions extensively, but I've never gone as far as enforcing the startup sequence by insisting that MAIN is dragged out of a library. Going back to the original question; for the source code in the files which do not contain MAIN, you will need to have a database around when the code is compiled in order to pick up the correct types of the fields you have defined LIKE particular columns (this is good because it means that if the column changes type, your code changes type too -- see Cathy's comments). The compile time database need not be one of the databases present at run-time as long as the structures of the tables in the run-time database(s) are sufficiently similar to the compile-time database for there to be no type compatability problems. Yours, Jonathan Leffler (johnl@informix.com) #include <disclaimer.h>