第十一章 Caché 函数大全 $DATA 函数

2020-09-01  本文已影响0人  Cache技术分享

第十一章 Caché 函数大全 $DATA 函数

检查变量是否包含数据。

大纲

$DATA(variable,target)
$D(variable,target)

参数

描述

可以在尝试对变量进行操作之前,使用$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

参数

variable

如果是全局变量,则可以包含扩展的全局变量引用。如果是下标的全局变量,则可以使用naked的全局变量引用来指定它。即使引用未定义的下标全局变量,变量也会重置naked指标,从而影响将来naked的全局变量局引用,如下所述。

例如,%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函数来测试当前数组元素。

Level1Level2Level3中的$DATA = 0测试用于测试当前数组元素是否未定义。如果为TRUE,它将导致代码退出并返回上一级。

Level1Level2中的$DATA = 10测试用于测试当前数组元素是否包含指向从属元素的指针,但没有数据。如果为TRUE,它将导致代码写出“无数据”消息。然后,代码跳到下一个较低级别的FOR循环处理。在Level3中没有$DATA = 10测试,因为没有从属于该级别的元素。

Level2Level3中的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)在客户端缓存中。

上一篇下一篇

猜你喜欢

热点阅读