What Shape is Your Data?
In a SQL world, a specific column in a specific table has exactly one data type and it cannot change. In a pinch, you can represent everything with a varchar, but that's not very useful. Arithmetic gets tricky for numbers, and dates become impossible to sort!Pick, on the other hand, much like XML, is essentially free-form. You can define dictionaries for your data, but there is nothing that forces you to follow the dictionary layout, or even warn you if you depart, and in many Pick dictionaries, you don't have to look far to find two dictionary records that point at the same attribute, but have completely different definitions.
Just about every Pick system I ever worked on had a control file. About 75 to 80% of the time, it was called "CF". The item-id of this file would normally have a structure like this:
Control-record-type "*" Identifier
The asterix was probably the most common delimiter in early Pick systems and carries through to many applications. So some examples might be:
SIZE*SMALL
COLOUR*RED
INDUSTRY.CODE*312000
The thing with this file is that each record type would have a unique structure. For SIZE the first attribute might be an integer, which is the number of inches. COLOUR might have 3 integers for red, green and blue, and INDUSTRY.CODE might have a text name of the industry, followed by some tax rates.
In order to process this and a whole bunch of other problems, we came up with a strategy called a "Select Method" or "Filter". This was a subroutine that you would associate with a table that you defined. This filter was a Pick BASIC subroutine with this signature:
SUBROUTINE SUB-NAME(ID, ITEM, PROCEED)
As soon as our SQL engine read a record for processing, it called this subroutine, passing the item-id in ID, and the full dynamic array text of the item body in ITEM. You got to set PROCEED to 1 or 0 (true or false). If you set it to false, we'd skip the record.
So, for our example above, we'd define 3 table views on the CF file. The first might be called CF_SIZE and the filter method would look like this:
SUBROUTINE LF.CF.SIZE(ID, ITEM, PROCEED)
IF FIELD(ID,"*",1) EQ "SIZE" THEN PROCEED=1 ELSE PROCEED=0
RETURN
END
It would only process records that started with "SIZE*".
You'd then create another view called CF_COLOUR with this filter:
SUBROUTINE LF.CF.SIZE(ID, ITEM, PROCEED)
IF FIELD(ID,"*",1) EQ "COLOUR" THEN PROCEED=1 ELSE PROCEED=0
RETURN
END
This would only process records that started with "COLOUR*".
SUBROUTINE LF.CF.SIZE(ID, ITEM, PROCEED)
IF FIELD(ID,"*",1) EQ "INDUSTRY.CODE" THEN PROCEED=1 ELSE PROCEED=0
RETURN
END
This would only process records that started with "INDUSTRY.CODE".
We would then define a different mapping for each record type.
Note that we avoided periods in table names as periods were significant separators in the SQL world. If you used them you'd have to quote your table names. In the early days, many ODBC clients wouldn't do this, so you were asking for trouble if you used them!
No comments:
Post a Comment