$DATA
Synopsis
$DATA(variable,target) $D(variable,target)
Parameters
Argument | Description |
---|---|
variable | The variable whose status is to be checked. A local or global variable, subscripted or unsubscripted. The variable may be undefined. You cannot specify a simple object property reference as variable; you can specify a multidimensional property reference as variable with the syntax obj.property. |
target | Optional — A variable into which $DATA returns the current value of variable. |
Description
You can use $DATA to test whether a variable contains data before attempting an operation on it. $DATA returns status information about the specified variable. The variable parameter can be the name of any variable (local variable, process-private global, or global), and can include a subscripted array element. It can be a multidimensional object property; it cannot be a non-multidimensional object property.
The possible status values that may be returned are as follows:
Status Value | Meaning |
---|---|
0 | The variable is undefined. Any reference would cause an <UNDEFINED> error. |
1 | The variable exists and contains data, but has no descendants. Note that the null string ("") qualifies as data. |
10 | The variable identifies an array element that has descendants (contains a downward pointer to another array element) but does not contain data. Any direct reference to such a variable will result in an <UNDEFINED> error. For example, if y(1) is defined, but y is not, $DATA(y) returns 10, set x=y will produce an <UNDEFINED> error. |
11 | The variable identifies an array element that has descendants (contains a downward pointer to another array element) and contains data. Variables of this type can be referenced in expressions. |
You can use modulo 2 (#2) arithmetic to return a boolean value from $DATA: $DATA(var)#2 returns 0 for the undefined status codes (0 and 10), and returns 1 for the defined status codes (1 and 11).
Status values 1 and 11 indicate only the presence of data, not the type of data.
You can use the Undefined()Opens in a new tab method of the %SYSTEM.ProcessOpens in a new tab class to set behavior when encountering an undefined variable. For more information on <UNDEFINED> errors, refer to the $ZERROR special variable.
$DATA Tests Locks, Routines, Jobs, and Globals
-
$DATA(^$LOCK(lockname)) tests for the existence of a lock. Note that the return values are different: 0 = lock does not exist; 10 = lock exists. Lock descendants cannot be determined. Values 1 and 11 are never returned. Refer to ^$LOCK for further details.
-
$DATA(^$ROUTINE(routinename)) tests for the existence of the OBJ code version of a routine. Note that the return values are different: 0 = routine OBJ code does not exist; 1 = routine OBJ code exists. Values 10 and 11 are never returned. Refer to ^$ROUTINE for further details.
-
$DATA(^$JOB(jobnum)) tests for the existence of a job. Note that the return values are different: 0 = job does not exist; 1 = job exists. Values 10 and 11 are never returned. Refer to ^$JOB for further details.
-
$DATA(^$GLOBAL(globalname)) tests for the existence of a global. The return codes are the same as for variables: 0, 1, 10, and 11. Refer to ^$GLOBAL for further details.
Parameters
variable
The variable that is being tested for the presence of data:
-
variable can be a local variable, a global variable, or a process-private global (PPG) variable. It can be subscripted or unsubscripted.
If a global variable, it can contain an extended global reference. If a subscripted global variable, it can be specified using a naked global reference. Even when referencing an undefined subscripted global variable, variable resets the naked indicator, affecting future naked global references, as described below.
-
variable can be a multidimensional object property. It cannot be a non-multidimensional object property. Attempting to use $DATA on a non-multidimensional object property results in an <OBJECT DISPATCH> error.
For example, the %SQL.StatementMetadataOpens in a new tab class has a multidimensional property columnIndex, and a non-multidimensional property columnCount. In the following example, the first $DATA returns a value; the second $DATA results in an <OBJECT DISPATCH> error:
SET x=##class(%SQL.StatementMetadata).%New() WRITE "columnIndex defined: ",$DATA(x.columnIndex),! WRITE "columnCount defined: ",$DATA(x.columnCount)
$DATA cannot return a data status value for a Proxy Object property. Caché instead issues a message that the specified property does not exist. This property access limitation is unique to the class %ZEN.proxyObjectOpens in a new tab, which is defined in the InterSystems Class Reference.
-
If variable is the ^$ROUTINE structured system variable, the possible returned status values are 1 or 0.
target
An optional parameter. Specify the name of a local variable, a process-private global, or a global. This target variable does not need to be defined. If target is specified, $DATA writes the current data value of variable into target. If variable is undefined, the target value remains unchanged.
The ZBREAK command cannot specify the target parameter as a watchpoint.
Examples
This example writes a selected range of records from the ^client array, a sparse array consisting of three levels. The first level contains the client’s name, the second the client’s address, and the third the client’s accounts, account numbers, and balances. A client can have up to four separate accounts. Because ^client is a sparse array there may be undefined elements at any of the three levels. The contents for a typical record might appear as follows:
^client(5) John Jones ^client(5,1) 23 Bay Rd./Boston/MA 02049 ^client(5,1,1) Checking/45673/1248.00 ^client(5,1,2) Savings/27564/3270.00 ^client(5,1,3) Reserve Credit/32456/125.00 ^client(5,1,4) Loan/81263/460.00
The code below provides a separate subroutine to handle the output for each of the three array levels. It uses the $DATA function at the start of each subroutine to test the current array element.
The $DATA=0 test in Level1, Level2, and Level3 tests whether the current array element is undefined. If TRUE, it causes the code to QUIT and revert to the previous level.
The $DATA=10 test in Level1 and Level2 tests whether the current array element contains a pointer to a subordinate element, but no data. If TRUE, it causes the code to write out a “No Data” message. The code then skips to the FOR loop processing for the next lower level. There is no $DATA=10 test in Level3 because there are no elements subordinate to this level.
The WRITE commands in Level2 and Level3 use the $PIECE function to extract the appropriate information from the current array element.
Start Read !,"Output how many records: ",n
Read !,"Start with record number: ",s
For i=s:1:s+(n1) {
If $Data(^client(i)) {
If $Data(^client(i))=10 {
Write !," Name: No Data"
}
Else {
Write !," Name: " ,^client(i)
}
If $Data(^client(i,1)) {
If $Data(^client(i,1))=10 {
Write !,"Address: No Data"
}
Else {
Write !,"Address: ",$Piece(^client(i,1),"/",1)
Write " , ",$Piece(^client(i,1),"/",2)
Write " , ",$Piece(^client(i,1),"/",3)
}
}
For j=1:1:4 {
If $Data(^client(i,1,j)) {
Write !,"Account: ",$Piece(^client(i,1,j),"/",1)
Write " #: ",$Piece(^client(i,1,j),"/",2)
Write " Balance: ",$Piece(^client(i,1,j),"/",3)
}
}
}
}
Write !,"Finished."
Quit
When executed, this code might produce output similar to the following:
Output how many records: 3 Start with record number: 10 Name: Jane Smith Address: 74 Hilltop Dr., Beverly, MA 01965 Account: Checking #: 34218 Balance: 876.72 Account: Reserve Credit #: 47821 Balance: 1200.00 Name: Thomas Brown Address: 46 Huron Ave., Medford, MA 02019 Account: Checking #: 59363 Balance: 205.45 Account: Savings #: 41792 Balance: 1560.80 Account: Reserve Credit #: 64218 Balance: 125.52 Name: Sarah Copley Address: No Data Account: Checking #: 30021 Balance: 762.28
In the following example, a multidimensional property is used as the variable value. This example returns the names of all defined namespaces to the target parameter:
SET obj = ##class(%ResultSet).%New("%SYS.Namespace:List")
DO obj.Execute()
WRITE $DATA(obj.Data,targ),! // returns 0
SET targ="blank"
WHILE targ'="" {
DO obj.Next()
WRITE $DATA(obj.Data,targ) // returns 10
WRITE " ",$DATA(obj.Data("Nsp"),targ),! // returns 1
IF targ'="" {
WRITE "Namespace: ",targ,! }
}
WRITE !,"Done!"
A similar program returns the same information using the $GET function.
Notes
Naked Global References
$DATA sets the naked indicator when used with a global variable. The naked indicator is set even if the specified global variable is not defined (Status Value = 0).
Subsequent references to the same global variable can use a naked global reference, as shown in the following example:
IF $DATA(^A(1,2,3))#2 {
SET x=^(3) }
For further details on using $DATA with global variables and naked global references, see Using Multidimensional Storage (Globals) in Using Caché Globals.
Global References in a Networked Environment
Using $DATA to repeatedly reference a global variable that is not defined (for example, $DATA(^x(1)) where ^x is not defined) always requires a network operation to test if the global is defined on the ECP server.
Using $DATA to repeatedly reference undefined nodes within a defined global variable (for example, $DATA(^x(1)) where any other node in ^x is defined) does not require a network operation once the relevant portion of the global (^x) is in the client cache.
For further details, refer to Developing Distributed Applications in the Caché Distributed Data Management Guide.
Functions Related to $DATA
For related information, see $GET and $ORDER. Since $ORDER selects the next element in an array that contains data, it avoids the need to perform $DATA tests when looping through array subscripts.
See Also
-
KILL command
-
SET command
-
$GET function
-
$ORDER function
-
Using Multidimensional Storage (Globals) in Using Caché Globals