第二十三章 Caché 命令大全 SET 命令

第二十三章 Caché 命令大全 SET 命令

为变量赋值。

重点

  1. 单次调用set(a,b,c,...)=value可以执行的最大赋值数量是128。超过此数字会导致错误
  2. 符串值用引号引起来。除了字符串内的双引号被转换为单引号外,字符串的赋值不变。空字符串(“”)是有效值。
  3. SET接受任意长度的变量名,但在为其赋值之前,它会将长变量名截断为31个字符。

大纲

SET:pc setargument,...  
S:pc setargument,...   

setargument可以是:

variable=value
(variable-list)=value

参数

  • pc 可选-后置条件表达式。
  • variable 要设置为相应值的变量。变量可以是局部变量,进程专用全局变量,全局变量,对象属性或特殊变量。(并非所有特殊变量都可以由应用程序设置。)
  • variable-list 逗号分隔的列表,用括号括起来,由一个或多个变量参数组成。变量列表中的所有变量参数都分配有相同的值。
  • value 文字值或计算结果为值的任何有效ObjectScript表达式。可以是JSON对象或JSON数组。

描述

SET命令将值分配给变量。它可以设置单个变量,也可以使用两种语法形式的任意组合设置多个变量。它可以通过指定变量=值对的逗号分隔列表来为变量分配值。例如:

    SET a=1,b=2,c=3
    WRITE a,b,c

通过单次调用set a=value、b=value、c=value、...,可以执行的赋值次数没有限制。

如果指定的变量不存在,则SET会创建该变量并赋值。如果存在指定的变量,则SET将用指定的值替换先前的值。由于SET按从左到右的顺序执行,因此可以为一个变量赋值,然后将该变量赋值给另一个变量:

    SET a=1,b=a
    WRITE a,b
DHC-APP>SET a=1,b=a
 
DHC-APP>WRITE a,b
11
DHC-APP>

值可以是字符串、数字、JSON对象、JSON数组或计算结果为这些值之一的表达式。要定义“空”变量,可以将该变量设置为空字符串(“”)值。

将多个变量设置为相同的值

可以使用SET将相同的值赋给多个变量,方法是指定用圆括号括起来的变量列表(以逗号分隔)。例如:

    SET (a,b,c)=1
    WRITE a,b,c
DHC-APP>SET (a,b,c)=1
 
DHC-APP> WRITE a,b,c
111
DHC-APP>

可以将这两种集合的句法形式以任意组合形式组合在一起。例如:

    SET (a,b)=1,c=2,(d,e,f)=3
    WRITE a,b,c,d,e,f
DHC-APP> SET (a,b)=1,c=2,(d,e,f)=3
 
DHC-APP> WRITE a,b,c,d,e,f
112333
DHC-APP>

单次调用set(a,b,c,...)=value可以执行的最大赋值数量是128。超过此数字会导致错误。

设置多个变量的限制

  • $LIST:不能使用SET(a,b,c,...)=VALUE语法为等号左侧的$LIST函数赋值。尝试这样做会导致错误。必须使用set a=value,$list(mylist,n)=value,c=value,...。使用$LIST设置其中一个项时的语法。
  • $ EXTRACT$ PIECE:如果该函数使用相对偏移,则不能使用SET(a,b,c,...)= value语法为等号左侧的$ EXTRACT$ PIECE函数分配值句法。在相对偏移语法中,星号表示字符串的结尾,*-n* + n表示距字符串结尾的相对偏移。例如,SET(x,$ PIECE(mylist,“ ^”,3))= 123是有效的,但是SET(x,$ PIECE(mylist,“ ^”,*))= 123导致错误。使用相对偏移设置这些功能之一时,必须使用SET a = value,b = value,c = value,...语法。
  • 对象属性:不能使用SET(a,b,c,...)= value语法为等号左侧的对象属性分配值。尝试这样做会导致错误,并显示如下消息:MyPackage.MyClass类的Set属性MyProp不是直接引用,并且不能是多个Set Arg。必须使用set a=value,oref.MyProp=value,c=value,...。设置对象属性时的语法。

    参数

    pc

    可选的后置条件表达式。如果后置条件表达式为TRUE(计算结果为非零数值),则Caché执行该命令。如果后置条件表达式为假(计算结果为零),则Caché不执行该命令。

    variable

    用于接收值求值结果的变量。它可以是局部变量、进程私有全局变量、全局变量或特殊变量。局部变量、进程私有全局变量或全局变量既可以是下标变量,也可以是取消下标变量,可以使用扩展的全局引用指定全局变量。

    局部变量、进程私有全局变量和特殊变量特定于当前进程;它们被映射为可以从所有名称空间访问。全局变量在创建它的进程终止后仍然存在。

    全局变量特定于在其中创建全局变量的命名空间。默认情况下,集在当前名称空间中指定全局。可以使用set在另一个名称空间中定义全局(^myglobal),方法如下:SET ^["Samples"]myglobal="Ansel Adams"。如果指定的名称空间不存在,则Caché会发出错误。如果指定了没有权限的命名空间,则Caché会发出一个错误,后跟全局名称和数据库路径,如下所示:^myglobal,c:\interSystems\cache\mgr\

    变量可以是$PIECE$EXTRACT函数的参数中指定的一段或一段变量。

    可以使用obj.property..将变量表示为对象属性。属性语法,或使用$PROPERTY函数。可以使用以下语法设置i%Property实例属性引用:

      SET i%propname = "abc"
    

    SET接受任意长度的变量名,但在为其赋值之前,它会将长变量名截断为31个字符。如果变量名在前31个字符内不是唯一的,此名称截断可能会导致意外覆盖变量值,如下例所示:

    /// d ##class(PHA.TEST.Command).TestSet()
    ClassMethod TestSet()
    {
        SET abcdefghijklmnopqrstuvwxyz2abc="30 characters"
        SET abcdefghijklmnopqrstuvwxyz2abcd="31 characters"
        SET abcdefghijklmnopqrstuvwxyz2abcde="32 characters"
        SET abcdefghijklmnopqrstuvwxyz2abcdef="33 characters"
        WRITE !,abcdefghijklmnopqrstuvwxyz2abc     // returns "30 characters"
        WRITE !,abcdefghijklmnopqrstuvwxyz2abcd    // returns "33 characters"
        WRITE !,abcdefghijklmnopqrstuvwxyz2abcde   // returns "33 characters"
        WRITE !,abcdefghijklmnopqrstuvwxyz2abcdef  // returns "33 characters"
    }
    
    
    DHC-APP>d ##class(PHA.TEST.Command).TestSet()
     
    30 characters
    33 characters
    33 characters
    33 characters
    

    根据定义,特殊变量由系统事件设置。可以使用SET为某些特殊变量赋值。但是,大多数特殊变量不能使用SET赋值。

    value

    文字值或任何有效的CachéObjectScript表达式。通常,值是数字或字符串表达式。值可以是JSON对象或JSON数组。

    • 在赋值之前将数值转换为规范形式:删除前导和尾随零、加号或尾随小数点。执行从科学记数法的转换和算术运算的评估。
    • 字符串值用引号引起来。除了字符串内的双引号被转换为单引号外,字符串的赋值不变。空字符串(“”)是有效值。
    • 用引号括起来的数值不会转换为规范形式,并且在赋值之前不会执行任何算术运算。
    • 如果使用关系或逻辑表达式,则Caché会指定表达式对齐产生的真值(0或1)。
    • 返回值的对象属性和对象方法是有效的表达式。使用相对点语法(..)。用于将属性或方法值赋给变量。

    JSON值

    可以使用set命令将变量设置为JSON对象或JSON数组。对于JSON对象,该值是由大括号分隔的JSON对象。对于JSON数组,该值是用方括号分隔的JSON数组。

    在这些分隔符中,文字值是JSON文字,而不是ObjectScript文字。无效的JSON文本会生成错误。

    • 字符串文字:必须用双引号将JSON字符串引起来。要将某些字符指定为JSON字符串中的文字,必须指定\转义字符,后跟文字。如果JSON字符串包含双引号文字字符,则此字符写为\“。JSON字符串语法提供双引号(\\“)、反斜杠(\\)和斜杠(\/)的转义。也可以转义行间字符:退格符(\b)、换页符(\f)、换行符(\n)、回车符(\r)和制表符(\t)。任何Unicode字符都可以由六个字符的序列表示:反斜杠、小写字母u和四个十六进制数字。例如,\u0022指定文字双引号字符;\u03BC指定希腊文小写字母Mu。
    • 数字文字:JSON不会将数字转换为ObjectScript规范形式。JSON有自己的转换和验证规则:只允许使用一个前导减号;不允许使用前导加号;不允许使用多个前导符号。允许使用“E”科学记数法字符,但不对其求值。不允许使用前导零;将保留尾随零。小数分隔符的两侧必须有一个数字字符。因此,JSON数字00.00.40.400是有效的。保留零值上的负号。

    对于IEEE浮点数,适用其他规则。

    JSON小数的存储格式与ObjectScript数字不同。ObjectScript浮点小数在达到其最大精度时进行四舍五入,并删除尾随零。JSON压缩的BCD小数允许更高的精度,并保留尾随零。下面的示例显示了这一点:

      SET jarray=[1.23456789123456789876000,(1.23456789123456789876000)]
      WRITE jarray.%ToJSON()
    
    DHC-APP>SET jarray=[1.23456789123456789876000,(1.23456789123456789876000)]
     
    DHC-APP> WRITE jarray.%ToJSON()
    [1.23456789123456789876000,1.234567891234567899]
    
    • 特殊值:JSON支持以下特殊值:truefalsenull。这些是字面值,必须用小写字母指定为不带引号的文字。这些JSON特殊值不能使用变量指定,也不能在ObjectScript表达式中指定。
    • 对象:若要在JSON数组元素或JSON对象值中包含ObjectScript文本或表达式,必须将整个字符串括在括号中。不能在JSON对象键中指定ObjectScript。ObjectScript和JSON使用不同的转义序列约定。要在ObjectScript中转义双引号字符,请将其加倍。在下面的示例中,在JSON数组中指定了JSON字符串文字和ObjectScript字符串文字:
      SET jarray=["This is a \"good\" JSON string",("This is a ""good"" ObjectScript string")]
      WRITE jarray.%ToJSON()
    
    DHC-APP> SET jarray=["This is a \"good\" JSON string",("This is a ""good"" ObjectScript string")]
     
    DHC-APP>WRITE jarray.%ToJSON()
    ["This is a \"good\" JSON string","This is a \"good\" ObjectScript string"]
    

    下面的JSON数组示例指定ObjectScript局部变量并将ObjectScript数值转换为规范形式:

      SET str="This is a string"
      SET jarray=[(str),(--0007.000)]
      WRITE jarray.%ToJSON()
    
    DHC-APP>SET str="This is a string"
     
    DHC-APP>SET jarray=[(str),(--0007.000)]
     
    DHC-APP> WRITE jarray.%ToJSON()
    ["This is a string",7]
    

    下面的示例在JSON对象值中指定ObjectScript函数:

      SET jobj={"firstname":"fred","namelen":($LENGTH("fred"))}
      WRITE jobj.%ToJSON()
    
    DHC-APP>SET jobj={"firstname":"fred","namelen":($LENGTH("fred"))}
     
    DHC-APP>WRITE jobj.%ToJSON()
    {"firstname":"fred","namelen":4}
    

    JSON对象

    值可以是由大括号分隔的JSON对象。该变量设置为OREF,如下所示:3@%Library.DynamicObject.用大括号表示。可以使用%get()方法通过此OREF检索指定键的值。可以使用%ToJSON()函数将此OREF解析为JSON对象值。下面的示例显示了这一点:

      SET jobj={"firstname":"Fred"}
      WRITE "JSON object reference = ",jobj,!
      WRITE "key value = ",jobj.%Get("firstname"),!
      WRITE "JSON object value = ",jobj.%ToJSON()
    
    
    DHC-APP>SET jobj={"firstname":"Fred"}
     
    DHC-APP>WRITE "JSON object reference = ",jobj,!
    JSON object reference = 3@%Library.DynamicObject
     
    DHC-APP> WRITE "key value = ",jobj.%Get("firstname"),!
    key value = Fred
     
    DHC-APP> WRITE "JSON object value = ",jobj.%ToJSON()
    JSON object value = {"firstname":"Fred"}
    

    有效的JSON对象具有以下格式:

    • 以大括号开头,以大括号结束。空对象{}是有效的JSON对象。
    • 在大括号内,是键:值对或逗号分隔的键:值对列表。键和值组件都是JSON文字,而不是ObjectScript文字。
    • 关键组件必须是JSON引用的字符串文字。它不能是括在括号中的ObjectScript文本或表达式。
    • 值组件可以是JSON字符串或JSON数字文字。这些JSON文字遵循JSON验证标准。值组件可以是括在括号中的ObjectScript文本或表达式。可以将Value组件指定为指定字符串、数字、JSON对象或JSON数组的已定义变量。Value组件可以包含嵌套的JSON对象或JSON数组。值组件还可以是以下三个JSON特殊值之一:TRUEFALSENULL,用小写字母指定为不带引号的文字;这些JSON特殊值不能使用变量指定。

    以下都是有效的JSON对象:{"name":"Fred"}, {"name":"Fred","city":"Bedrock"}, {"bool":true}, {"1":true,"0":false,"Else":null}, {"name":{"fname":"Fred","lname":"Flintstone"},"city":"Bedrock"}, {"name":["Fred","Wilma","Barney"],"city":"Bedrock"}.

    JSON对象可以指定空属性名并为其赋值,如下例所示:Objects:

      SET jobj={}
      SET jobj.""="This is the ""null"" property value"
      WRITE "JSON null property object value = ",jobj.%ToJSON()
    
    
    DHC-APP>SET jobj={}
     
    DHC-APP>SET jobj.""="This is the ""null"" property value"
     
    DHC-APP>WRITE "JSON null property object value = ",jobj.%ToJSON()
    JSON null property object value = {"":"This is the \"null\" property value"}
    

    注意,返回的JSON字符串使用JSON转义序列(\“)表示文字双引号字符。

    JSON数组

    值可以是用方括号分隔的JSON数组。该变量设置为OREF,如下所示:1@%Library.DynamicArray。可以使用%ToJSON()函数将此OREF解析为JSON数组值。下面的示例显示了这一点:

      SET jary=["Fred","Wilma","Barney"]
      WRITE "JSON array reference = ",jary,!
      WRITE "JSON array value = ",jary.%ToJSON()
    
    DHC-APP>SET jary=["Fred","Wilma","Barney"]
     
    DHC-APP>WRITE "JSON array reference = ",jary,!
    JSON array reference = 3@%Library.DynamicArray
     
    DHC-APP>WRITE "JSON array value = ",jary.%ToJSON()
    JSON array value = ["Fred","Wilma","Barney"]
    

    有效的JSON数组具有以下格式:

    • 以左方括号开始,以右方括号结束。空数组[]是有效的JSON数组。
    • 方括号中的元素或逗号分隔的元素列表。每个数组元素可以是JSON字符串或JSON数字文字。这些JSON文字遵循JSON验证标准。数组元素可以是括在括号中的ObjectScript文本或表达式。可以将数组元素指定为指定字符串、数字、JSON对象或JSON数组的已定义变量。数组元素可以包含一个或多个JSON对象或JSON数组。数组元素也可以是以下三个JSON特殊值之一:TRUEFALSENULL,用小写字母指定为不带引号的文字;这些JSON特殊值不能使用变量指定。

    以下是所有有效的JSON数组:[1], [5,7,11,13,17], ["Fred","Wilma","Barney"], [true,false], ["Bedrock",["Fred","Wilma","Barney"]], [{"name":"Fred"},{"name":"Wilma"}], [{"name":"Fred","city":"Bedrock"},{"name":"Wilma","city":"Bedrock"}], [{"names":["Fred","Wilma","Barney"]}].

    示例

    以下示例为同一SET命令指定多个参数。具体地说,该命令为三个变量赋值。请注意,参数按从左到右的顺序进行计算。

       SET var1=12,var2=var1*3,var3=var1+var2
       WRITE "var1=",var1,!,"var2=",var2,!,"var3=",var3
    
    DHC-APP>SET var1=12,var2=var1*3,var3=var1+var2
     
    DHC-APP>WRITE "var1=",var1,!,"var2=",var2,!,"var3=",var3
    var1=12
    var2=36
    var3=48
    

    以下示例显示了SET命令的(Variable-List)=Value形式。它显示了如何将相同的值赋给多个变量。具体地说,该命令将值0赋给三个变量。

       SET (sum,count,average)=0
       WRITE "sum=",sum,!,"count=",count,!,"average=",average
    
    DHC-APP>SET (sum,count,average)=0
     
    DHC-APP> WRITE "sum=",sum,!,"count=",count,!,"average=",average
    sum=0
    count=0
    average=0
    

    下面的示例使用扩展全局变量引用在不同的命名空间中设置带下标的全局变量。

    /// d ##class(PHA.TEST.Command).TestSetNew()
    ClassMethod TestSetNew()
    {
        NEW $NAMESPACE
        SET $NAMESPACE="%SYS"
        SET ^["user"]nametest(1)="fred"
        NEW $NAMESPACE
        SET $NAMESPACE="USER"
        WRITE ^nametest(1)
        KILL ^nametest
    }
    
    
    DHC-APP> d ##class(PHA.TEST.Command).TestSetNew()
    fred
    

    对对象设置命令

    下面的示例包含三个SET命令:第一个命令将变量设置为OREF(对象引用);第二个命令将变量设置为对象属性的值;第三个命令将对象属性设置为一个值:

    /// d ##class(PHA.TEST.Command).TestSetPro()
    ClassMethod TestSetPro()
    {
        SET myobj=##class(%SQL.Statement).%New()
        SET dmode=myobj.%SelectMode
        WRITE "默认选择模式=",dmode,!
        SET myobj.%SelectMode=2
        WRITE "新设置的选择模式=",myobj.%SelectMode
    }
    
    DHC-APP>d ##class(PHA.TEST.Command).TestSetPro()
    默认选择模式=0
    新设置的选择模式=2
    

    请注意,在对象表达式中使用点语法;在对象引用和对象属性名或对象方法名之间放置一个点。

    要为当前对象设置具有对象属性或对象方法值的变量,请使用双点语法:

      SET x=..LastName
    

    如果指定的对象属性不存在,则Caché会发出错误。如果使用双点语法,并且尚未定义当前对象,则Caché会发出错误。

    对对象使用设置时,请勿执行多个指定。例如,避免使用以下语句:

     // 避免如下语法:
       SET (a.Name,b.Name)=z
    

    相反,应为每个分配发出单独的set命令,如下例所示:

      SET a.Name=z
      SET b.Name=z
    

    以下命令将x设置为GetNodeName()方法返回的值:

      SET x=##class(%SYS.System).GetNodeName()
      WRITE "当前系统节点为: ",x
    
    DHC-APP>SET x=##class(%SYS.System).GetNodeName()
     
    DHC-APP>WRITE "当前系统节点为: ",x
    当前系统节点为: LAPTOP-ARLL3DSO
    

    对象的set命令可以采用级联点语法的表达式,如以下示例所示:

       SET x=patient.Doctor.Hospital.Name
    

    在此示例中,patient.Doctor对象属性引用Hospital对象,该对象包含Name属性。因此,此命令将x设置为指定患者的医生所属的医院的名称。对象方法可以使用相同的级联点语法。

    对象的SET命令可以与系统级方法一起使用,例如以下数据类型属性方法:

     SET x=patient.NameIsValid(Name)
    

    在本例中,NameIsValid()方法返回当前Patient对象的结果。NameIsValid()是为Name属性的数据类型验证生成的布尔方法。因此,如果指定的名称是有效名称,则此命令将x设置为1,如果指定的名称不是有效的名称,则此命令将x设置为0。

    使用对象方法设置

    可以在SET表达式的左侧指定对象方法。下面的示例指定%Get()方法:

    /// d ##class(PHA.TEST.Command).TestSetGet()
    ClassMethod TestSetGet()
    {
        SET obj=##class(test).%New()  // 其中test是具有多维属性md的类
        SET myarray=[(obj)]
        SET index=0,subscript=2
        SET myarray.%Get(index).md(subscript)="value"
        IF obj.md(2)="value" {WRITE "success"}
        ELSE {WRITE "failure"}
    }
    

    注意

    每个变量分配都可以是局部变量,进程专用全局变量或全局变量$ PIECE函数,$ EXTRACT函数以及某些特殊变量,包括$ ECODE,$ ETRAP,$ DEVICE,$ KEY,$ TEST, $ X和$ Y

    如果目标变量尚不存在,SET会创建它,然后分配值。如果确实存在,则SET用分配的值替换现有值。

    SET和下标

    可以为局部变量,进程专用全局变量或全局变量设置单个下标值(数组节点)。可以按任何顺序设置下标。如果变量下标级别尚不存在,则SET会创建它,然后分配值。每个下标级别都被视为一个独立变量。仅定义那些下标级别集。例如:

    /// d ##class(PHA.TEST.Command).TestSetKILL()
    ClassMethod TestSetKILL()
    {
        KILL myarray
        SET myarray(1,1,1)="Cambridge"
        WRITE !,myarray(1,1,1)
        SET myarray(1)="address"
        WRITE !,myarray(1)
    }
    
    DHC-APP>d ##class(PHA.TEST.Command).TestSetKILL()
     
    Cambridge
    address
    

    在此示例中,变量myarray(1,1,1)myarray(1)被定义并包含值。但是,变量myarraymyarray(1,1)未定义,并且在调用时返回错误。

    默认情况下,不能设置空下标。例如,SET ^ x(“”)= 123导致错误。但是,可以设置%SYSTEM.Process.NullSubscripts()方法以允许对全局变量和进程专用全局变量使用空下标。不能为局部变量设置空下标。

    下标的最大长度为511个字符。超过此长度将导致错误。

    局部变量的最大下标级别数为255。全局变量的最大下标级别数取决于下标级别名称,并且可能超过255个级别。尝试将局部变量设置为超过255个下标级别(直接或通过间接方式)会导致错误。

    计算顺序

    Caché以严格的从左到右顺序计算SET命令的参数。对于每个参数,它按以下顺序执行求值:

    1. 以从左到右的顺序计算等号左侧的间接寻址或下标的出现,以确定变量名称。
    2. 计算等号右边的表达式。
    3. 将等号右边的表达式分配给变量名,或将等号左边的引用分配给变量名。

    事务处理

    全局变量的SET被记录为当前事务的一部分;在事务回滚期间将回滚此全局变量分配。不会记录局部变量或进程专用全局变量的SET,因此该分配不受事务回滚的影响。

    定义和未定义的变量

    大多数Caché命令和功能都要求在引用变量之前先对其进行定义。默认情况下,尝试引用未定义的变量会生成错误。尝试引用未定义的对象会生成错误。

    可以通过设置%SYSTEM.Process.Undefined()方法来更改引用未定义变量时的Caché行为。

    READ命令和$ INCREMENT函数可以引用未定义的变量并为其分配值。$ DATA函数可以采用未定义或定义的变量,并返回其状态。$ GET函数返回已定义变量的值; (可选)它还可以为未定义的变量分配一个值。

    设置$ PIECE$ EXTRACT

    可以将$ PIECE$ EXTRACT函数与等号两侧的SET一起使用。

    当在等号的右侧使用时,$ PIECE$ EXTRACT从变量中提取子字符串,并将其值分配给等号左侧的指定变量。$ PIECE使用指定的分隔符提取子字符串,而$ EXTRACT使用字符计数提取子字符串。

    例如,假设变量x包含字符串“ HELLO WORLD”。以下命令提取子字符串“ HELLO”并将其分别分配给变量yz

       SET x="HELLO WORLD"
       SET y=$PIECE(x," ",1)
       SET z=$EXTRACT(x,1,5)
       WRITE "x=",x,!,"y=",y,!,"z=",z
    
    DHC-APP>SET x="HELLO WORLD"
     
    DHC-APP>SET y=$PIECE(x," ",1)
     
    DHC-APP> SET z=$EXTRACT(x,1,5)
     
    DHC-APP> WRITE "x=",x,!,"y=",y,!,"z=",z
    x=HELLO WORLD
    y=HELLO
    z=HELLO
    

    在等号左侧使用时,$ PIECE$ EXTRACT将等号右侧表达式中的值插入目标变量的指定部分。目标变量指定部分中的任何现有值都将由插入值替换。

    例如,假设变量x包含字符串“ HELLO WORLD”,而变量y包含字符串“ HI THERE”。在命令中:

       SET x="HELLO WORLD"
       SET y="HI THERE"
       SET $PIECE(x," ",2)=$EXTRACT(y,4,9)
       WRITE "x=",x
    
    DHC-APP>SET x="HELLO WORLD"
     
    DHC-APP>SET y="HI THERE"
     
    DHC-APP> SET $PIECE(x," ",2)=$EXTRACT(y,4,9)
     
    DHC-APP>WRITE "x=",x
    x=HELLO THERE
    

    $ EXTRACT函数从变量y中提取字符串“ THERE”,而$ PIECE函数将其插入第二个字段位置的变量x中,以替换现有的字符串“ WORLD”。变量x现在包含字符串“ HELLO THERE”

    如果目标变量不存在,则系统将根据需要创建目标变量并将其填充定界符(对于$ PIECE)或空格(对于$ EXTRACT)。

    在以下示例中,SET $ EXTRACT用于将z的值插入到字符串xy中,从而覆盖现有值:

    /// d ##class(PHA.TEST.Command).TestSetEXTRACT()
    ClassMethod TestSetEXTRACT()
    {
        SET x="HELLO WORLD"
        SET y="OVER EASY"
        SET z="THERE"
        SET $EXTRACT(x,7,11)=z
        SET $EXTRACT(y,*-3,*)=z
        WRITE "edited x=",x,!
        WRITE "edited y=",y
    }
    
    DHC-APP>d ##class(PHA.TEST.Command).TestSetEXTRACT()
    edited x=HELLO THERE
    edited y=OVER THERE
    

    变量x现在包含字符串“ HELLO THERE”y包含字符串“ OVER THERE”。请注意,由于本示例中的SET $ EXTRACT操作之一使用负偏移量(* -3),因此必须将这些操作作为单独的集进行。如果任何变量使用负偏移,则不能使用单个括号括起来的SET设置多个变量。

    在下面的示例中,假设全局数组^client的结构是根节点包含客户的名称,而下级节点包含街道地址和城市。例如,^CLIENT(2,1,1)将包含数组中存储的第二个客户端的城市地址。

    进一步假设城市节点(x,1,1)包含标识城市、州缩写和邮政编码(邮政编码)的字段值,逗号作为字段分隔符。例如,典型的城市节点值可能是"Cambridge,MA,02142".以下代码中的三个SET命令每个都使用$ PIECE函数将数组节点值的特定部分分配给适当的局部变量。请注意,在每种情况下,$ PIECE都将逗号(“,”)用作字符串分隔符。

    /// d ##class(PHA.TEST.Command).TestSetPiece()
    ClassMethod TestSetPiece()
    {
    ADDRESSPIECE
        SET ^client(2,1,1)="Cambridge,MA,02142"
        SET city=$PIECE(^client(2,1,1),",",1)
        SET state=$PIECE(^client(2,1,1),",",2)
        SET zip=$PIECE(^client(2,1,1),",",3)
        WRITE "城市是 ",city,!,
             "州或省是 ",state,!
            ,"邮编是 ",zip
        QUIT
    }
    
    DHC-APP>d ##class(PHA.TEST.Command).TestSetPiece()
    城市是 Cambridge
    州或省是 MA
    邮编是 02142
    

    $ EXTRACT函数可用于执行相同的操作,但前提是字段的长度是固定的并且长度是已知的。例如,如果已知city字段最多仅包含9个字符,而stateZIP字段分别仅包含2和5个字符,则可以使用$ EXTRACT函数对SET命令进行编码,如下所示:

    /// d ##class(PHA.TEST.Command).TestSetEXTRACT1()
    ClassMethod TestSetEXTRACT1()
    {
    ADDRESSEXTRACT
        SET ^client(2,1,1)="Cambridge,MA,02142"
        SET city=$EXTRACT(^client(2,1,1),1,9)
        SET state=$EXTRACT(^client(2,1,1),11,12)
        SET zip=$EXTRACT(^client(2,1,1),14,18)
        WRITE "城市是 ",city,!,
             "州或省是 ",state,!,
             "邮编是 ",zip
        QUIT
    }
    
    DHC-APP>d ##class(PHA.TEST.Command).TestSetEXTRACT1()
    城市是 Cambridge
    州或省是 MA
    邮编是 02142
    

    请注意9和11以及12和14之间的间隙,以容纳逗号字段分隔符。

    下面的示例将A中的第一个子字符串(最初设置为1)替换为字符串“abc”

    /// d ##class(PHA.TEST.Command).TestSetStringPiece()
    ClassMethod TestSetStringPiece()
    {
        SET A="1^2^3^4^5^6^7^8^9"
        SET $PIECE(A,"^")="abc"
        WRITE !,"A=",A
        QUIT
    }
    
    DHC-APP>d ##class(PHA.TEST.Command).TestSetStringPiece()
     
    A=abc^2^3^4^5^6^7^8^9
    

    下面的示例使用$Extract将A中的第一个字符(同样是1)替换为字符串“abc”

    /// d ##class(PHA.TEST.Command).TestSetStringExtract()
    ClassMethod TestSetStringExtract()
    {
        SET A="123456789"
        SET $EXTRACT(A)="abc"
        WRITE !,"A=",A
        QUIT
    }
    
    DHC-APP>d ##class(PHA.TEST.Command).TestSetStringExtract()
     
    A=abc23456789
    

    下面的示例将A的第三部分到第六部分替换为字符串“abc”,并将变量B中的第一个字符替换为字符串“abc”

    /// d ##class(PHA.TEST.Command).TestSetStringInsert()
    ClassMethod TestSetStringInsert()
    {
        SET A="1^2^3^4^5^6^7^8^9"
        SET B="123"
        SET ($PIECE(A,"^",3,6),$EXTRACT(B))="abc"
        WRITE !,"A=",A,!,"B=",B
        QUIT
    }
    
    DHC-APP>d ##class(PHA.TEST.Command).TestSetStringInsert()
     
    A=1^2^abc^7^8^9
    B=abc23
    

    下面的示例将$X$Y$KEY和先前未定义的局部变量A的第四部分设置为值20。它还将局部变量K设置为$KEY的当前值。A包括前三个部分及其插入符号分隔符(^)。

    /// d ##class(PHA.TEST.Command).TestSetSetVars()
    ClassMethod TestSetSetVars()
    {
        SET ($X,$Y,$KEY,$PIECE(A,"^",4))=20,X=$X,Y=$Y,K=$KEY
        WRITE !,"A=",A,!,"K=",K,!,"X=",X,!,"Y=",Y
        QUIT
    }
    
    DHC-APP>d ##class(PHA.TEST.Command).TestSetSetVars()
     
    A=^^^20
    K=20
    X=20
    Y=20
    

    以下示例将$ECODE$ETRAP设置为空字符串。然后,该示例将局部变量ECET设置为$ECODE$ETRAP的值。

    /// d ##class(PHA.TEST.Command).TestSetEvars()
    ClassMethod TestSetEvars()
    {
        SET ($ECODE,$ETRAP)="",EC=$ECODE,ET=$ETRAP 
        WRITE "EC=",EC,!,"ET=",ET
        QUIT
    }
    
    DHC-APP>d ##class(PHA.TEST.Command).TestSetEvars()
    EC=
    ET=
    

    使用$LIST$LISTBUILD设置

    $LIST函数创建和操作列表。它们对列表中每个元素的长度(和类型)进行编码,而不是使用元素分隔符。然后,它们在列表操作期间使用编码的长度规范来提取指定的列表元素。由于$LIST函数不使用分隔符字符,所以使用这些函数创建的列表不应输入到$ PIECE或其他字符定界符中。

    在等号右侧使用时,这些函数返回以下内容:

    $LIST

    $LIST返回指定列表的指定元素。

    $LISTBUILD

    $LISTBUILD为每个给定参数返回一个包含一个元素的列表。

    当在等号左侧使用SET参数时,这些函数将执行以下任务:

    $LIST

    用等号右侧给出的值替换指定的元素。

    /// d ##class(PHA.TEST.Command).TestSetListBuild()
    ClassMethod TestSetListBuild()
    {
        SET A=$LISTBUILD("red","blue","green","white")
        WRITE "创建列表 A=",$LISTTOSTRING(A),!
        SET $LIST(A,2)="yellow"
        WRITE "编辑列表 A=",$LISTTOSTRING(A)
    }
    
    
    DHC-APP>d ##class(PHA.TEST.Command).TestSetListBuild()
    创建列表 A=red,blue,green,white
    编辑列表 A=red,yellow,green,white
    
    
    /// d ##class(PHA.TEST.Command).TestSetListBuild1()
    ClassMethod TestSetListBuild1()
    {
        SET A=$LISTBUILD("red","blue","green","white")
        WRITE "创建列表 A=",$LISTTOSTRING(A),!
        SET $LIST(A,*-1,*)=$LISTBUILD("yellow")
        WRITE "编辑列表 A=",$LISTTOSTRING(A)
    }
    
    DHC-APP>d ##class(PHA.TEST.Command).TestSetListBuild1()
    创建列表 A=red,blue,green,white
    编辑列表 A=red,blue,yellow
    

    不能在SET $ LIST中使用括号来将相同的值分配给多个变量。

    $LISTBUILD

    在单个操作中提取列表的几个元素。$LISTBUILD的参数是变量,每个变量都接收与它们在$ LISTBUILD参数列表中的位置相对应的列表元素。对于不需要的位置,可以省略变量名。

    在下面的示例中,$LISTBUILD(在等号的右侧)首先用于返回列表。然后使用$LISTBUILD(在等号的左侧)从该列表中提取两个项目并设置适当的变量。

    /// d ##class(PHA.TEST.Command).TestSetSetListBuild()
    ClassMethod TestSetSetListBuild()
    {
        SET J=$LISTBUILD("red","blue","green","white")
        SET $LISTBUILD(A,,B)=J
        WRITE "A=",A,!,"B=",B
    }
    
    
    DHC-APP>d ##class(PHA.TEST.Command).TestSetSetListBuild()
    A=red
    B=green
    

    你可能感兴趣的:(第二十三章 Caché 命令大全 SET 命令)