Null Indicators
Trapping null values.
here are two ways that a column of a SQL result set can contain the null value. One, it can be derived from an expression that contains a null value. Two, null is returned in outer joins and exception joins when a row in a primary table has no match in a secondary table. In either event, RPG has no way to represent a null value, so what's a guy (a professional i-on-Power guy, that is) to do when an embedded SQL command might return null values?
FETCH may return null
exec sql fetch TheCursor into :Name :NameNullInd;
Notice that both the data variable and the null indicator are prefixed with colons, as they both host variables.
If the data variable is a data structure, use an array for the indicator variable. You can test individual array elements in order to determine if a column returned null or not. In the following example, the programmer tests element four of array NullsInds in order to determine whether the item description came back null or not.
D InvoiceData ds D InvNbr 5p 0 D InvLineNbr 3p 0 D ItemNbr 6a D ItemDescr 30a D ItemPrice 5p 2 D QtySold 3p 0 D NullInds s 5i 0 dim(6) D NullValue s like(NullInds) inz(-1) /free exec sql declare Invoice cursor for SELECT Ln.InvNbr, Ln.LineNbr, Ln.ItemNbr, Itm.Descrip, Ln.Price, Ln.Qty FROM InvLine as Ln LEFT JOIN Items as Itm ON Ln.ItemNbr = Itm.Item; *inlr = *on; exec sql open Invoice; dow '1'; exec sql fetch Invoice into :InvoiceData :NullInds; if sqlstt = '02000'; leave; endif; if NullInds(4) = NullValue; // do whatever endif; enddo; exec sql close invoice; return;
For a short example, cryptic code is no big deal. In a larger program, you might find it advantageous to give the null indicator a name. You can do so by overlaying the array with a data structure. Here's one way to accomplish that.
D InvoiceData ds D InvNbr 5p 0 D InvLineNbr 3p 0 D ItemNbr 6a D ItemDescr 30a D ItemPrice 5p 2 D QtySold 3p 0 D NullInds s 5i 0 dim(6) D NullAddr s * inz(%addr(NullInds)) D InvoiceNulls ds based(NullAddr) D NullInvNbr like(NullInds) D NullLineNbr like(NullInds) D NullItemNbr like(NullInds) D NullItemDescr like(NullInds) D NullItemPrice like(NullInds) D NullQtySold like(NullInds) D NullValue s like(NullInds) inz(-1) /free exec sql declare Invoice cursor for SELECT Ln.InvNbr, Ln.LineNbr, Ln.ItemNbr, Itm.Descrip, Ln.Price, Ln.Qty FROM InvLine as Ln LEFT JOIN Items as Itm ON Ln.ItemNbr = Itm.Item; *inlr = *on; exec sql open Invoice; dow '1'; exec sql fetch Invoice into :InvoiceData :NullInds; if sqlstt = '02000'; leave; endif; if NullItemDescr = NullValue; // do whatever endif; enddo; exec sql close invoice; return;
In this example, NullItemDesc is another name for the fourth element of NullInds.