第十一章 Caché 函数大全 $DATA 函数
检查变量是否包含数据。
大纲
$DATA(variable,target)
$D(variable,target)
参数
- variable 要检查其状态的变量。下标或未下标的局部或全局变量。该变量可能是未定义的。不能将简单的对象属性引用指定为变量。可以使用语法obj.property将多维属性引用指定为变量。
- target 可选—一个变量,
$DATA
返回该变量的当前值。
描述
可以在尝试对变量进行操作之前,使用$DATA
来测试变量是否包含数据。$DATA
返回有关指定变量的状态信息。变量参数可以是任何变量(局部变量,进程专用全局变量或全局变量)的名称,并且可以包含带下标的数组元素。它可以是多维对象属性。它不能是非多维对象属性。
可能返回的状态值如下:
状态值 | 含义 |
---|---|
0 | 变量未定义。任何引用都将导致错误。 |
1 | 该变量存在并包含数据,但没有后代。请注意,空字符串(“” )符合数据条件。 |
10 | 该变量标识具有后代(包含指向另一个数组元素的向下指针)但不包含数据的数组元素。对此类变量的任何直接引用都将导致错误。例如,如果定义了y(1 ),但未定义y ,则$DATA(y) 返回10,则设置x = y将产生错误。 |
11 | 该变量标识具有后代(包含指向另一个数组元素的向下指针)并包含数据的数组元素。这种类型的变量可以在表达式中引用。 |
可以使用模2(#2
)算术从$DATA
返回布尔值:$DATA(var)#2
对于未定义的状态码(0和10)返回0,对于定义的状态码(1和1)返回1。 11)..
状态值1和11仅指示数据的存在,而不指示数据的类型。
可以使用%SYSTEM.Process
类的Undefined()
方法来设置遇到未定义变量时的行为。
$DATA 测试 Locks, Routines, Jobs, Globals
-
$DATA(^$LOCK(lockname))
测试锁是否存在。请注意,返回值不同:0=锁不存在;10=锁存在。无法确定锁定后代。值1和11永远不会返回。 -
$DATA(^$ROUTINE(routinename))
测试例程的OBJ代码版本是否存在。请注意,返回值不同:0=例程OBJ代码不存在;1=例程OBJ代码存在。值10和11永远不会返回。 -
$DATA(^$JOB(jobnum))
测试JOB是否存在。请注意,返回值不同:0=作业不存在;1=作业存在。值10和11永远不会返回。 -
$DATA(^$GLOBAL(globalname))
测试是否存在全局变量。返回代码与变量相同:0、1、10和11。
参数
variable
- 正在测试是否存在数据的变量:变量可以是局部变量,全局变量或进程专用全局(PPG)变量。它可以下标或不下标。
如果是全局变量,则可以包含扩展的全局变量引用。如果是下标的全局变量,则可以使用naked的全局变量引用来指定它。即使引用未定义的下标全局变量,变量也会重置naked指标,从而影响将来naked的全局变量局引用,如下所述。
- 变量可以是多维对象属性。它不能是非多维对象属性。尝试在非多维对象属性上使用
$DATA
会导致<Object Dispatch>
错误。
例如,%SQL.StatementMetadata
类具有多维属性column nIndex
和非多维属性column nCount
。在下面的示例中,第一个$DATA
返回值;第二个$DATA
导致<OBJECT DISPATCH>
错误:
/// d ##class(PHA.TEST.Function).data()
ClassMethod data()
{
SET x=##class(%SQL.StatementMetadata).%New()
WRITE "columnIndex defined: ",$DATA(x.columnIndex),!
WRITE "columnCount defined: ",$DATA(x.columnCount)
}
DHC-APP>d ##class(PHA.TEST.Function).data()
columnIndex defined: 0
columnCount defined:
WRITE "columnCount defined: ",$DATA(x.columnCount) }
^
<OBJECT DISPATCH>zdata+3^PHA.TEST.Function.1 *Property 'columnCount' in class '%SQL.StatementMetadata' must be MultiDimensional
$DATA
无法返回代理对象属性的数据状态值。相反,Caché发出一条消息,指出指定的属性不存在。此属性访问限制对于%ZEN.proxyObject
类是唯一的
如果变量是^$ROUTINE
结构化的系统变量,则可能返回的状态值为1或0。
target
可选参数。指定局部变量的名称,进程专用的全局变量或全局变量。不需要定义此目标变量。如果指定了target,则$DATA
将变量的当前数据值写入target。如果未定义变量,则目标值保持不变。
ZBREAK
命令无法将目标参数指定为观察点。
示例
本示例从^ client
数组(一个由三个级别组成的稀疏数组)中写入选定的记录范围。第一级包含客户的姓名,第二级包含客户的地址,第三级包含客户的帐户,帐号和余额。一个客户最多可以拥有四个单独的帐户。因为^ client是一个稀疏数组,所以在这三个级别中的任何一个级别上都可能存在未定义的元素。典型记录的内容可能如下所示:
/// d ##class(PHA.TEST.Function).data1()
ClassMethod data1()
{
set ^client(5) = "John Jones"
set ^client(5,1) = "23 Bay Rd./Boston/MA 02049"
set ^client(5,1,1) = "Checking/45673/1248.00"
set ^client(5,1,2) = "Savings/27564/3270.00"
set ^client(5,1,3) = "Reserve Credit/32456/125.00"
set ^client(5,1,4) = "Loan/81263/460.00"
}
下面的代码提供了一个单独的子例程来处理三个数组级别中每个级别的输出。它在每个子例程的开头使用$DATA
函数来测试当前数组元素。
Level1
,Level2
和Level3
中的$DATA = 0
测试用于测试当前数组元素是否未定义。如果为TRUE,它将导致代码退出并返回上一级。
Level1
和Level2
中的$DATA = 10
测试用于测试当前数组元素是否包含指向从属元素的指针,但没有数据。如果为TRUE,它将导致代码写出“无数据”消息。然后,代码跳到下一个较低级别的FOR循环处理。在Level3
中没有$DATA = 10
测试,因为没有从属于该级别的元素。
Level2
和Level3
中的WRITE
命令使用$PIECE
函数从当前数组元素中提取适当的信息。
/// d ##class(PHA.TEST.Function).data2()
ClassMethod data2()
{
Read !, "输出多少条记录: ", n
Read !, "从记录编号开始: ", s
For i = s : 1 : s + (n) {
If $Data(^client(i)) {
If $Data(^client(i)) = 10 {
Write !, " 名字: 无数据"
} Else {
Write !, " 名字: " , ^client(i)
}
If $Data(^client(i, 1)) {
If $Data(^client(i,1 )) = 10 {
Write !, "地址: 无数据"
} Else {
Write !, "地址: ",$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 !,"账户: ",$Piece(^client(i, 1, j), "/", 1)
Write " #: ",$Piece(^client(i, 1, j), "/", 2)
Write " 结余: ",$Piece(^client(i, 1, j), "/", 3)
}
}
}
}
Write !,"结束."
Quit
}
在执行时,此代码可能会产生类似于以下内容的输出:
DHC-APP>d ##class(PHA.TEST.Function).data2()
输出多少条记录: 2
从记录编号开始: 1
名字: 无数据
地址: 无数据
账户: Cambridge,MA,02142 #: 结余:
结束.
DHC-APP>d ##class(PHA.TEST.Function).data2()
输出多少条记录: 5
从记录编号开始: 5
名字: John Jones
地址: 23 Bay Rd. , Boston , MA 02049
账户: Checking #: 45673 结余: 1248.00
账户: Savings #: 27564 结余: 3270.00
账户: Reserve Credit #: 32456 结余: 125.00
账户: Loan #: 81263 结余: 460.00
结束.
在以下示例中,将多维属性用作变量值。本示例将所有定义的名称空间的名称返回给目标参数:
/// d ##class(PHA.TEST.Function).data3()
ClassMethod data3()
{
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!"
}
DHC-APP>d ##class(PHA.TEST.Function).data3()
0
10 1
Namespace: %SYS
10 1
Namespace: DHC-APP
10 1
Namespace: DHC-CHSSWEB
10 1
Namespace: DHC-CSM
10 1
Namespace: DHC-DATA
10 1
Namespace: DHC-DWR
10 1
Namespace: DHC-EKG
10 1
Namespace: DHC-HEIS
10 1
Namespace: DHC-HR
10 1
Namespace: DHC-LISDATA
10 1
Namespace: DHC-LISSRC
10 1
Namespace: DHC-MEDSRC
10 1
Namespace: DHC-MRQ
10 1
Namespace: DOCBOOK
10 1
Namespace: FDBMS
10 1
Namespace: PACS
10 1
Namespace: PIS
10 1
Namespace: RIS
10 1
Namespace: SAMPLES
10 1
Namespace: USER
10 1
Done!
类似的程序使用$GET
函数返回相同的信息。
注意
naked全局变量
与全局变量一起使用时,$DATA
设置裸指标。即使未定义指定的全局变量(状态值= 0),也会设置裸指标。
对同一全局变量的后续引用可以使用裸的全局引用,如以下示例所示:
/// d ##class(PHA.TEST.Function).data4()
ClassMethod data4()
{
IF $DATA(^A(1,2,3))#2 {
SET x=^(3)
}
}
网络环境中的全局变量
使用$DATA
重复引用未定义的全局变量(例如,未定义^x的$DATA(^x(1)
) 始终需要进行网络操作,以测试是否在ECP服务器上定义了全局变量。
使用$DATA
重复引用已定义的全局变量(例如$DATA(^x(1)
)中未定义的节点,其中定义了^x
中的任何其他节点)后,只要全局的相关部分( ^x
)在客户端缓存中。
网友评论