Nil versus Null

The 4D language has two words that may be confused: Nil & Null.

Nil tests whether the pointer points to a valid container of a value, a field, variable or array. Nil has nothing to do with the content of what is being pointed to. Nil tells you nothing about what may or may not be inside that field, variable, or array.

  • To test if a pointer is nil:
    If ( Nil( $myPointer) )
    End If

NULL means the container (a database field) has no contents. No value = NULL. Do not confuse no value with an empty value. For an Alpha field or Text variable, we represent an empty value in our code as a pair of double-quotes: $companyName := ""
  • To test for NULL, call the command Is field value Null
  • To set a NULL, removing the value entirely, call the command SET FIELD VALUE NULL

Here's code to test for nil pointer…

C_pointer( $pointerToText )
if Nil( $pointerToText )
  `ERROR condition.
else ` else not nil, we have a valid pointer. So use it.
  C_TEXT( $myText )
  $myText := $pointerToText-> `Copy the value of the text.
end if

You should always test a pointer for nil when passed as a parameter, as seen in this code…

if Not(Nil($1))
end if

4D versions 11 & 12 introduce the feature/problem of NULL values in a record's field, as do most other SQL databases. You can have a valid pointer to a record's field, but have no value (NULL) stored in that field. On the other hand, the record's field may have a value (be non-NULL) but that value may be empty such as empty text for Alpha Field, !00/00/00! for date, etc.

So generally you should be testing for 2 or 3 issues:

  • Is pointer valid? (not Nil)
  • Is what's being pointed to a record field with a value? (not NULL)
  • Is the value valid in the record field being pointed to? (not empty, within expected range, etc.)

--- 4D code --------
C_pointer( $pointerToField )
C_TEXT( $myText )
$myText := "ERROR - This text never got set"

if Nil($ pointerToField )
  `ERROR condition.
else ` else not nil, we have a valid pointer. So use it.
  IF ( Type($pointerToField->) = Is Alpha Field )
    If ( Is field value Null( $pointerToField )
        `ERROR condition. No value (NULL).
    Else // Else we have an actual value

      If ( $pointerToField-> = "" )
        $myText := "Got text? Nope." `Flag error condition if having an empty string was unexpected.
        $myText := $pointerToField-> `Copy the value of the field.   <-------- GOAL
      End If

    End IF

    `ERROR - Expected an Alpha field, but got a pointer pointing to something else.
  End if
end if
… Do something with $myText

If you're working with Date, Blob, or other types of variabless or fields rather than Alpha/String, same concepts apply. Just change the data types in code above, but logic is the same.

Caveat: These code examples were written freehand, not written or tested in 4D.

Tip: In general you should avoid dealing with NULL by defining your database fields as "NOT NULL" in SQL, meaning a record with a NULL in that field will be rejected by the database engine. Chris Date explains why.

No comments:

Post a Comment