Programming / RPG
SQL does field reference files, too!
In a previous article, I discussed how naming conventions really help in database design and programming, and in so doing I touched upon the concept of the field reference file. Field reference files are an easy way to make sure your data elements are consistent, but I'll bet you didn't know you could use them in DDL as well. In this article, I'll show you how it's done.
Using a Field Reference File
If you're a DDS shop, I hope you're already using a field reference file. But let's review quickly how that works. First, I create a file with definition of all the basic data elements of my system. As always, naming is important, and when I create a field reference file, I use short names so that I can later put a prefix on them when defining my files. Using a prefix is a matter of preference; some people actually use the same field name in multiple files. I've never been a huge fan of that approach, but I don't argue when someone uses it. Like most programming architecture decisions, there are benefits and drawbacks to the technique. But let's move ahead with my normal approach. For this example, I define a reference file called REFFILPF, with the record format RREFFIL. Below is an excerpt:
CUST 6S 0 TEXT('CUSTOMER NUMBER')
NAME 30 TEXT('NAME')
ADDR 30 TEXT('ADDRESS')
This reference file identifies a number of fields. Now I define my customer master file from that. Again, I present just a portion of the file:
CMCUST R REFFLD('CUST')
CMNAME R REFFLD('NAME')
CMADDR1 R REFFLD('ADDR')
CMADDR2 R REFFLD('ADDR')
The attributes of the fields in the customer master depend on the attributes defined in the field reference file. What this allows me to do is to keep consistency among fields with common data. As an example, CMADDR1 and CMADDR2 share the same attributes: they're both 30-character fields. But I'd like to differentiate them both in field name and in their descriptive text. I can easily override the text from the field definition file by specifying a text keyword for each address field. If I didn't, both fields would get the same text of "ADDRESS".
References in DDL
To use reference fields in DDL, you start the same way, by creating the field reference file. Create it as shown below:
CREATE TABLE MYLIB.REFFILPF (
CUST NUMERIC(6, 0) NOT NULL DEFAULT 0 ,
NAME CHAR(30) CCSID 37 NOT NULL DEFAULT '' ,
ADDR CHAR(30) CCSID 37 NOT NULL DEFAULT '' ,
) RCDFMT REFFILR;
LABEL ON COLUMN MYLIB.REFFILPF (
CUST TEXT IS 'Customer',
NAME TEXT IS 'Name',
ADDR TEXT IS 'Address'
As you can see, I have to use separate statements in DDL to create the table and then to assign the text to the fields. I suppose the CREATE TABLE command is already pretty complicated and the DB2 powers that be just didn't want to add more DB2-specific extensions to it, so they just created the LABEL ON statement. I'm just glad that you're able to set the text for as many fields as you want in one LABEL ON statement; I'd hate to have to execute one LABEL ON for every field. Anyway, with these two statements, you've effectively duplicated the effort of the original REFFILPF DDS above. This creates the field reference file that other database files can use as a model. You may have noticed that I used uppercase and lowercase on the DDL; that just allows me to make sure that I ran the command successfully. If my file fields have uppercase text, then I know I didn't execute the DDL correctly. Also, please note that I used the dot notation (MYLIB.REFFILPF) rather than the more traditional slash syntax (MYLIB/REFFILPF). Either will work on the green-screen, but the dot syntax also works in GUI tools such as IBM i Navigator or any of the myriad SQL clients out there. Because of that, I've moved almost exclusively to the dot notation for qualifying files.
So now that I have a field reference file, it's time to use it to create a file that refers to it. Creating the file is simple:
CREATE TABLE MYLIB.CUSMASPF AS (
SELECT CUST AS CMCUST,
NAME AS CMNAME,
ADDR AS CMADDR1,
ADDR AS CMADDR2
) DEFINITION ONLY RCDFMT CUSMASR;
This is a really powerful technique. Basically, I just build a SELECT statement that pulls in all the fields that I need from the reference file. In that SELECT, I use the AS clause to rename them in such a way that they fit the new table's naming convention. Then the only additional piece is to add the DEFINITION ONLY clause at the end just before I define the record format name; this lets the system know I'm creating an empty file. However, you may have noticed something missing; I haven't changed the descriptions of the two address fields. Without any additional intervention, the two fields would both have the same text of "Address". I can remedy that situation with a LABEL ON statement:
LABEL ON COLUMN JPLUTA.CUSMASPF (
CMADDR1 TEXT IS 'Address 1',
CMADDR2 TEXT IS 'Address 2'
You'll note that, like DDS, I only have to specify overrides for the fields whose text I want to change. The other fields get their defaults from the field reference file. And in fact, if I bring the file up in ProData's popular DBU utility, I'd see something like this:
Figure 1: My new file looks like this when adding records in DBU.
Text and Column Headings
You might have noticed that I only talked about field text in this discussion. As IBM i programmers, we know there are actually two descriptive attributes associated with every field: the text and the column heading. The default is for both to be the same, but they don't have to be. If you're someone who relies on the column heading to be different from the text for some or all of your fields, rest assured that IBM i DDL has you covered. You specify the column heading using the same LABEL command, except that you leave off the keyword TEXT. Here is an example:
LABEL ON COLUMN MYLIB.REFFILPF (
CUST IS 'CustNo'
By not specifying the keyword TEXT, the label value is applied to the column heading. This particular statement overrides the column heading on the CUST field only. To get a little more detail on text and column headings, you can refer an article I wrote a while back.
There are some other minor differences. DDL is not quite a complete replacement for DDS. As an example, I haven't found a way to specify an edit code for a numeric field in DDL. This is more of a convenience feature; it's nice to be able to look at numeric fields in a query without the commas. But if you can live without that capability, you can make the move entirely from DDS to DDL yet still retain your field reference file capabilities. And that's worth the effort for me.