Timothy Leavitt · Feb 9, 2016

Property with SqlComputed and SqlComputeCode, but not Calculated or SqlComputeOnChange

Looking at a property defined as follows:

Property SystemTime As %Library.TimeStamp [ SqlComputeCode = {Set {*}=$ZDATETIME($NOW(),3,1,0)}, SqlComputed ];

The documentation talks about using SqlComputed and SqlComputeCode with SqlComputeOnChange (specifying which events will trigger computation), and about using them with the Calculated keyword (so it's always computed). I don't see any specific explanation of the case above, though, when neither SqlComputeOnChange nor Calculated is specified.

From a bit of testing, it seems that the behavior is:

  • Upon SQL insert or first %Save, if no value has been specified explicitly for such a property, the SqlComputeCode is run to provide an initial value. (In an SQL insert, null is treated as an explicitly-specified value; in Objects, explicitly setting the property to "" is not.)
  • Otherwise, the SqlComputeCode is never invoked automatically.

Is there anything I'm missing?

3 0 4 410


In my opinion better will be so:

Property SystemTime As %TimeStamp [ InitialExpression = {$ZDATETIME($NOW(),3,1,0)}, ReadOnly ];

This variant will work and for SQL and for Objects.
In addition the developer will not be able to explicitly set a different value.

I agree. In some cases, having an initial default value determined when the object is saved - possibly based on values of other properties, which InitialExpression wouldn't allow - could be useful, if that's how SqlComputed + SqlComputeCode is expected to work. This probably isn't one of those cases.

This is working as expected (to the best of my knowledge).  If you have a property that is SqlComputed and not Calculated, then the property value is stored on disk.  We calculate that value to store it on disk and do so on the first INSERT/%Save().  Then, since there is no SqlComputeOnChange value, the value won't be re-computed on any UPDATEs.  However, I believe you will be able to set that property directly via INSERT/%Save().