第五十五章 Caché 函数大全 $QUERY 函数
对本地或全局数组执行物理扫描。
大纲
$QUERY(reference,direction,target)
$Q(reference,direction,target)
参数
- reference 引用,其值为公共局部变量或全局变量的名称(或可选的下标)。不能将简单的对象属性指定为引用。可以使用语法obj.property将多维属性指定为引用。
- direction 可选-遍历数组的方向。前进= 1,后退= -1。默认值为forward。
- target 可选-返回参考的当前数据值。
描述
$QUERY
对公共本地或全局数组执行物理扫描;它将返回已定义节点的完整引用,名称和下标,然后依次返回到指定数组节点。如果不存在这样的节点,则$QUERY
返回空字符串。
参数
reference
此参数必须计算为公共变量或全局变量。 $QUERY
无法扫描私有变量。
此参数可以是多维对象属性。它不能是非多维对象属性。尝试在非多维对象属性上使用$QUERY
会导致<OBJECT DISPATCH>
错误。
返回的全局引用可以与引用参数中指定的级别处于同一级别,更低级别或更高级别。如果指定引用而不指定下标,则$QUERY
返回数组中第一个定义的节点。
direction
如果未指定方向,则默认方向为正向。如果要指定方向,则参数值1将向前遍历数组,值-1将向后遍历数组。
target
如果要指定目标,则必须指定方向。如果参考参数中标识的变量未定义,则目标值保持不变。
ZBREAK
命令无法将目标参数指定为观察点。
示例
本示例介绍了一个通用例程,用于输出用户指定数组中所有节点的数据值。它可以容纳任意数量级别的数组。该代码执行与示例中$ORDER
函数下的代码相同的操作。但是,它不需要6条线,而只需要6条线,并且可以处理的级别数不受限制。
/// d ##class(PHA.TEST.Function).QUERY()
ClassMethod QUERY()
{
READ !,"Array name: ",ary QUIT:ary=""
SET queryary=$QUERY(@ary@(""))
WRITE !,@queryary
FOR {
SET queryary=$QUERY(@queryary)
QUIT:queryary=""
WRITE !,@queryary
}
WRITE !,"Finished."
QUIT
}
DHC-APP>d ##class(PHA.TEST.Function).QUERY()
Array name: ^yx
ADMDATE()2015-03-01()2015-03-03()34!SessionGRP!1^23!gbFlag!0^6!DocSpc!^6!CarPrvTp!^-1()4!0!0^5!1!0^6!0!0()()1^3^4()
ORDDATE$SelectPara!2015-08-23#2015-08-23$ColPara!Null#Null#Null$RowPara!ResDep#AdmType#ALL!AdmType#AdmType#ALL$StatPara!13#数量!14#总费用!15#记帐费用!16#折扣费 用!17#自付费用!26#医嘱数量!31#进货价!67#条码数!68#手术数量!69#药品售价!81#日期进 货价~~!1~~~~~~~~
Date@1^2015/12/6^2015/12/6^Pat@1^Fee@1^Bill@1^1@^^Stat@1^^0^^^^0^^^^Cfg!!7!23^0^fNod@^^^^1@1
6923450657638#685
132||1#311#4638#1
第一个SET
命令使用$QUERY
和下标间接寻址来初始化对包含数据的第一个现有节点的全局引用。。 (就像$ORDER
一样,$QUERY
接受一个空字符串来指定数组中的第一个下标。)第一个WRITE
命令输出找到的第一个节点的值。如果省略,则第一个节点将被跳过。
在FOR
循环中,$QUERY
用于检索下一个节点并更新全局引用,然后其内容由WRITE
命令输出。后置条件QUIT
在找到空字符串(“”
)时终止循环,表示$QUERY
已到达数组的末尾。
除非希望区分指针节点($DATA = 11
)和终端节点($DATA = 1
),否则不需要$DATA
测试。
注意
使用$QUERY
遍历数组
重复使用,$QUERY
可以以从左到右,从上到下的方式遍历整个数组,返回定义的节点的整个序列。 $QUERY
可以从指定用于参考的下标确定的点开始。它沿水平轴和垂直轴进行。例如:
SET exam=$QUERY(^client(4,1,2))
DHC-APP 2d1>SET exam=$QUERY(^client(4,1,2))
DHC-APP 2d1>w exam
^client(4,3)
DHC-APP 2d1>zw ^client
^client(4,1)="Jones"
^client(4,3)="Jones"
^client(4,5)="Smith"
DHC-APP 2d1>SET exam=$QUERY(^client(4,3))
DHC-APP 2d1>w exam
^client(4,5)
根据此示例,假设使用三级数组,$QUERY
可能返回以下任何值:
Value | 由$QUERY 函数返回,如果... |
---|---|
^client(4,1,3) |
如果^client(4,1,3) 存在并且包含数据。 |
^client(4,2) |
如果^client(4,1,3) 不存在或不包含数据,并且如果^client(4,2) 不存在并且包含数据。 |
^client(5) |
如果^client(4,1,3) 和^client(4,2) 不存在或不包含数据,并且^client(5) 确实存在且包含数据。 |
null string ("") |
如果先前的全局引用都不存在或不包含数据; $QUERY 已到达数组末尾。 |
方向值为-1时,$QUERY
可以从右到左,从下到上的方式以相反的顺序遍历整个数组。
ORDER相比
$QUERY
与$ORDER
函数的不同之处在于$QUERY
返回完整的全局引用,而$ORDER
仅返回下一个节点的下标。 $ORDER
仅沿水平轴前进,跨一级节点。
$QUERY
与$ORDER
的不同之处还在于,它仅选择那些包含数据的现有节点。 $ORDER
选择现有节点,而不管它们是否包含数据。 $ORDER
对存在进行隐式测试($DATA'= 0
),$QUERY
对存在和数据执行隐式测试($DATA'= 0
和$DATA'= 10
)。但是请注意,$QUERY
不会区分包含数据的指针节点($DATA = 11
)和终端节点($DATA = 1
)。为了区别起见,必须在代码中包含适当的$DATA
测试。
与$ORDER
一样,$QUERY
通常与循环处理一起使用,以遍历不使用连续整数下标的数组中的节点。 $QUERY
只是返回带有值的下一个节点的全局引用。 $QUERY
提供了非常紧凑的代码来访问全局数组
像$NAME
和$ORDER
函数一样,$QUERY
可以与裸全局引用一起使用,该裸引用没有指定数组名称,并且指定了最近执行的全局引用。例如:
/// d ##class(PHA.TEST.Function).QUERY1()
ClassMethod QUERY1()
{
s ^client(1)=1
SET a= ^client(1)
SET x=2
SET z=$QUERY(^(x))
w z
}
DHC-APP>d ##class(PHA.TEST.Function).QUERY1()
^client(4,1)
DHC-APP>zw ^client
^client(1)=1
^client(4,1)="Jones"
^client(4,3)="Jones"
^client(4,5)="Smith"
第一个SET
命令建立当前的全局参考,包括参考的级别。第二个SET
命令设置用于下标的变量。 $QUERY
函数使用裸全局引用返回^client(2)
之后的下一个节点的完整全局引用。例如,返回的值可能是^client(2,1)
或^client(3)
。
$QUERY
和扩展的全局变量引用
可以使用%SYSTEM.Process
类的RefInKind()
方法来控制$QUERY
是否以每个进程为基础以扩展全局引用形式返回全局引用。可以通过设置Config.Miscellaneous
类的RefInKind
属性来建立系统范围的默认行为。
先左后右,在上下。
/// d ##class(PHA.TEST.Function).QUERY2()
ClassMethod QUERY2()
{
s pha="^^DHCPHARW"
//s pha="^DHCPHARi(""PAPMI"")"
//s pha="^DHCPHAC"
for{
s pha=$QUERY(@pha)
w pha,!
q:pha=""
}
}
DHC-APP>d ##class(PHA.TEST.Function).QUERY2()
^DHCPHARW(2)
^DHCPHARW(14)
^DHCPHARW(18)
^DHCPHARW(19)
^DHCPHARW(20)
^DHCPHARW(21)
^DHCPHARW(22)
...