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

第十一章 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函数来测试当前数组元素。

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352