第十章 Caché 定义和使用属性
可以在任何对象类中定义属性。文字属性保存一个文字值,并基于数据类型类。本章介绍如何定义和使用此类属性。
定义属性
要向类定义中添加属性,请向类中添加如下元素之一:
Property PropName as Classname;
Property PropName as Classname [ Keywords ] ;
Property PropName as Classname(PARAM1=value,PARAM2=value) [ Keywords ] ;
Property PropName as Classname(PARAM1=value,PARAM2=value) ;
其中:
- PropName是属性的名称。
- Classname是此属性所基于的类。如果省略此项,则类名称默认为%String。若要将此属性定义为文字属性,请省略类名或将类名指定为数据类型类的名称,也可以使用自定义数据类型类。
- Keywords 代表系统关键字
- PARAM1、PARAM2等是属性参数。可用参数取决于属性使用的类。本章的后面部分列出了最常见的属性参数。
请注意,属性参数(如果包含)括在括号中,并位于任何属性关键字之前。属性关键字(如果包含)括在方括号中。
实例
例如,类可以使用%Integer数据类型类定义Count属性:
Property Count As %Integer;
因为%Integer是一个数据类型类,所以Count是一个数据类型属性。
可以使用数据类型参数对数据类型属性的允许值设置约束。例如,对于类型为%Integer的属性,可以指定MAXVAL参数:
Property Count As %Integer(MAXVAL = 100);
若要将数据类型属性值设置为等于空字符串,请使用以下表单的代码:
Set object.Property = $C(0)
每个属性都有一个排序规则类型,用于确定值的排序方式(例如大写是否有效果)。字符串的默认排序规则类型是SQLUPPER。
为属性定义初始表达式
默认情况下,创建新对象时,每个属性都等于null。可以指定一个CachéObjectScript表达式作为给定属性的初始值。在创建对象时计算表达式。
要为属性指定初始表达式,请在属性定义中包含 InitialExpression关键字:
Property PropName as Classname [ InitialExpression=expression ] ;
Property PropName As %Integer [ InitialExpression = 1 ];
其中表达式是CachéObjectScript表达式(请注意,不能对此表达式使用任何其他语言)。
根据需要定义属性
此选项仅适用于持久类中的属性。(请注意,此选项适用于任何类型的属性,而不仅仅是文字属性。)
默认情况下,保存新对象时,Caché不要求其属性具有非空值。可以定义属性,以便需要非空值。为此,请在属性定义中包含必需的关键字:
Property PropName as Classname [ Required ] ;
然后,如果尝试保存属性值为空的对象,则Caché会发出以下错误:
ERROR #5659: Property required
Required关键字还影响如何通过SQL访问插入或修改此类的数据。特别是,如果尝试插入或更新记录时缺少该值,则会发生错误。
定义计算属性
在Caché中,可以定义计算属性,其值通过CachéObjectScript计算,可能基于其他属性。通用短语computed properties(或computed fields)包括以下两种变体:
- Always computed (总是计算) - 此属性的值在访问时计算。它从不存储在数据库中。
- Triggered computed (触发计算) - 此属性的值在触发时重新计算(详细信息如下)。
注意:如果属性是在持久类中定义的,则其值存储在数据库中。
在这两种情况下,无论使用对象访问还是SQL查询,都将执行重新计算。
有五个属性关键字(SqlComputed、SqlComputeCode、SqlComputeOnChange、Transient、Calculated)控制是否和如何计算属性。下表总结了各种可能性:
SqlComputed为true(并且定义了SqlComputeCode) | SqlComputed为false | ||
Calculated 为 true | Transient 为 true 或 false | 属性总是计算 | 属性不计算 |
Calculated 为 false | Transient 为 true | ||
Transient 为 true | 属性被触发计算(在这种情况下也可以指定SqlComputeOnChange) |
要定义计算属性,请执行以下操作:
- 在属性定义中包含SqlComputed关键字。(即,将SqlComputed关键字指定为true。)
- 在属性定义中包含SqlComputeCode关键字。对于此关键字的值,请根据以下规则(在大括号中)指定一行设置属性值的CachéObjectScript代码:
- 要引用此属性,请使用{*}
或者如果没有为属性指定SqlFieldName关键字,请使用{property name},其中propertyname是属性名。如果为属性指定了SqlFieldName关键字,请使用{SqlFieldName value},其中sqlfieldnamevalue是该关键字的值。
注意,SqlFieldName可用于所有对象类,尽管它仅对持久类有用。本章后面的一节将讨论关键字。
类似地,要引用另一个属性,如果没有为该属性指定SqlFieldName关键字,请使用{property name},其中propertyname是属性名。如果为属性指定了SqlFieldName关键字,请使用{SqlFieldName value},其中sqlfieldnamevalue是该关键字的值。
代码可以通过通常的完整语法引用类方法、例程或子例程。类似地,它可以使用ObjectScript函数和运算符。
代码可以包含以下伪字段引用变量,这些变量在类编译时转换为特定值:
{%%CLASSNAME}和{%%CLASSNAMEQ} 都转换为映射SQL表定义的类的名称。{%%CLASSNAME}返回一个未加引号的字符串,{%%CLASSNAMEQ}返回一个加引号的字符串。
{%%OPERATION}根据调用触发器的操作,转换为字符串文本,可以是INSERT、UPDATE或DELETE。
{%TABLENAME}转换为表的完全限定名,返回为带引号的字符串。
{%ID}转换为RowID名称。当您不知道RowID字段的名称时,此引用非常有用。
这些名称不区分大小写。
- 该代码不能使用..propertyname或..methodname()形式的语法
例如:
Property FullName As %String [ SqlComputeCode = {set {*}={FirstName}_" "_{LastName}}, SqlComputed ];
/// d ##class(PHA.OP.MOB.Test).AddMyClass()
ClassMethod AddMyClass(WebSocketID)
{
s one=##class(User.MyClass).%New()
s one.PropertyName="11"
s one.PropertyName1="222"
s one.FirstName="Yao"
s one.LastName="Xin"
s sc=one.%Save()
w sc
}
DHC-APP>d ##class(PHA.OP.MOB.Test).AddMyClass()
1
- 如果要始终计算属性,请在属性定义中将Calculated关键字指定为true。或者,如果要使触发的属性成为计算属性,请不要在属性定义中包括Calculated和Transient关键字。 (即,确保两个关键字都为false。)
- 如果该属性被触发计算,则可以选择指定SqlComputeOnChange。
此关键字可以指定一个或多个属性。当这些属性中的任何一个值发生变化时,将重新计算触发的属性。请注意,必须使用属性名称,而不是SqlFieldName给出的名称,本章稍后将对此进行讨论。例如(带有人工换行符):
Property messageId As %Integer [
SqlComputeCode = { set {*}=$Select({Status}="":0,1:$List($List($Extract({Status},3,$Length({Status}))))) },
SqlComputed, SqlComputeOnChange = Status ];
/// d ##class(PHA.OP.MOB.Test).AddMyClass()
ClassMethod AddMyClass(WebSocketID)
{
s one=##class(User.MyClass).%New()
s one.PropertyName="1"
s one.PropertyName1="1"
s one.FirstName="Y"
s one.LastName="X"
s one.Status=""
s sc=one.%Save()
w sc
}
另一个示例(带有人工换行符):
Property Test2 As %String [ SqlComputeCode = { set {*}={Refprop1}_{Refprop2}}, SqlComputed,
SqlComputeOnChange = (Refprop1, Refprop2) ];
SqlComputeOnChange的值还可以包含%% INSERT或%% UPDATE值.
如果要索引此字段,请使用确定性代码,而不是非确定性代码。Caché无法维护不确定性代码结果的索引,因为不可能可靠地删除陈旧的索引键值。(确定性代码每次传递相同的参数时都会返回相同的值。因此,例如,返回h在函数的控制范围之外进行了修改。)
附加:%Persistent 类 使用 NoExtent关键字 不能sql查询
定义多维属性
可以将一个属性定义为多维,这意味着打算将该属性用作多维数组。为此,在属性定义中包括MultiDimensional关键字:
为此,在属性定义中包括MultiDimensional关键字:
Property PropName as Classname [ MultiDimensional ] ;
此属性与其他属性不同,如下所示:
- Caché不为其提供属性方法。
- 验证或保存对象时将忽略它。
- 它不会保存到磁盘,除非应用程序包含专门保存它的代码。
- 不能通过ActiveX或Java公开。
- 不能存储在SQL表中或通过SQL表公开。
多维属性很少见,但提供了一种有用的方式来临时包含有关对象状态的信息。
Property Multis As %String [ MultiDimensional ];
/// d ##class(PHA.OP.MOB.Test).AddMyClass()
ClassMethod AddMyClass(WebSocketID)
{
s one=##class(User.MyClass).%New()
s one.PropertyName="1"
s one.PropertyName1="3"
s one.FirstName="Yao"
s one.LastName="Xin"
s one.Status=""
s one.Multis("11")=11
s one.Multis("aa")="aa"
s one.Multis("Y")="X"
s sc=one.%Save()
w sc
}
DHC-APP>d ##class(PHA.OP.MOB.Test).AddMyClass()
1
通用数据类型类
Caché提供了大量的数据类型类。其中,最常用的类如下:
类名 | 类型 | 注意 |
---|---|---|
%BigInt | 64位整数 | 此类类似于%Integer,但其OdbcType和ClientDataType除外。 |
%Binary | 二进制数据 | 实际的二进制数据在没有任何Unicode(或其他)转换的情况下发送到客户端或从客户端发送。 |
%Boolean | 布尔值 | 能的逻辑值为0(false)和1(true)。 |
%Char | 定长字符 | |
%Counter | 整数,用作唯一计数器 | 如果未为该属性指定任何值,则在保存新对象或通过SQL插入新记录时,将为类型类为%Counter的任何属性分配一个值。 |
%Currency | 货币值 | 定义此类仅用于从Sybase或SQL Server迁移到Caché。 |
%Date | 日期 | 逻辑值为Caché$ HOROLOG格式。 |
%DateTime | 日期时间 | 此类主要用于T-SQL迁移,并将datetime / smalldatetime行为映射到%TimeStamp数据类型。在此类中,DisplayToLogical()和OdbcToLogical()方法提供逻辑以处理T-SQL应用程序支持的不精确的日期时间值。 |
%Decimal | 定点数 | 逻辑值是十进制格式的数字。 |
%Double | IEEE浮点数 | 逻辑值是IEEE浮点数。 |
%EnumString | 字符串 | 这是%String的专用子类,它允许定义一组可能的值(使用DISPLAYLIST和VALUELIST参数)。与%String不同,此属性的显示值在通过ODBC查询此类型的列时使用。 |
%ExactString | 字符串 | 具有精确默认排序规则的%String的子类。 |
%FilemanDate | FileMan格式的日期 | 此类定义为与FileMan一起使用。 |
%FilemanTimeStamp | FileMan格式的时间戳 | 此类定义为与FileMan一起使用。 |
%Float | 浮点数 | 此类已弃用; |
%Integer | 整数 | |
%List | $ List格式的数据 | 逻辑值是$ List格式的数据。 |
%ListOfBinary | $ List格式的数据,每个列表项均为二进制数据 | 逻辑值是$ List格式的数据。 |
%Name | 以“姓氏,名字”形式的名称 | 与%CacheStorage类一起使用时,%Name数据类型具有特殊的索引支持。 |
%Numeric | 定点数 | |
%SmallInt | 小的整数值 | 此类除了OdbcType之外,与%Integer相同。 |
%Status | 错误状态码 | Caché类库中的许多方法都返回%Status类型的值。 |
%String | 字符串 | |
%Text | 可搜寻文字 | 此类支持基于单词的搜索和相关性排名。 |
%Time | 时间 | 逻辑值是午夜之后的秒数。 |
%TimeStamp | 时间戳 | %TimeStamp数据类型的逻辑值为YYYY-MM-DD HH:MM:SS.nnnnnnnnn格式。请注意,如果h是 ZDATETIME来获取%TimeStamp属性的有效逻辑值:$ ZDATETIME(h,3) |
%TinyInt | 非常小的数值 | 此类与%Integer相同,除了其OdbcType及其最大值和最小值。 |
%MV.Date | 多值日期 | 逻辑值是一个多值日期。要将Caché日期转换为MultiValue日期,请减去46385。 |
%MV.Numeric | 数值 | 该数据类型类处理MultiValue掩码的十进制(MD)转换代码。 |
- ODBC:一般指开放数据库连接(Open Database Connectivity,ODBC)是为解决异构数据库间的数据共享而产生的。
- JDBC:(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。
还有许多其他数据类型类,专门用于特殊用途。这些类型中的大多数是此处列出的类的子类。
每个数据类型类都指定几个关键字,这些关键字控制在CachéSQL中如何使用该数据类型以及如何将该数据类型投影到客户端系统:
- SqlCategory —指定当CachéSQL引擎对其执行操作时用于数据类型的SQL类别。
- OdbcType —指定通过ODBC访问数据类型时使用的ODBC类型。
- ClientDataType -指定通过客户端应用程序访问数据类型时使用的Java或ActiveX类型。
因此,当选择数据类型类时,应该选择一个具有适当的客户映射(如果适用)以满足你的需求的类。使用以下小节来帮助选择合适的数据类型类。如果没有合适的类,则可以创建自己的数据类型类。
SqlCategory分组的数据类型类
对于数据类型类,SqlCategory类关键字指定CachéSQL在对该类型的属性值进行操作时使用的SQL类别。SqlCategory控制的操作包括比较操作(例如,大于,小于或等于);其他操作也可以使用它。下表显示了本章中列出的数据类型的SqlCategory值。
值 | Caché 数据类型 |
---|---|
DATE | %Date |
DOUBLE | %Double, %Float |
FMDATE | %FilemanDate |
FMTIMESTAMP | %FilemanTimeStamp |
INTEGER | %BigInt, %Boolean, %Counter, %Integer, %SmallInt, %TinyInt |
MVDATE | %MV.Date |
NAME | %Name |
NUMERIC | %Currency, %Decimal, %Numeric, %MV.Numeric |
STRING | %Binary, %Char, %EnumString, %ExactString, %List, %ListOfBinary, %Status, %String, %Text |
TIME | %Time |
TIMESTAMP | %DateTime, %TimeStamp |
由OdbcType分组的数据类型类
对于数据类型类,OdbcType类关键字控制Caché如何将逻辑数据值与CachéSQL ODBC接口使用的值相互转换。下表显示了本章中列出的数据类型的OdbcType值。
值 | Caché 数据类型 |
---|---|
BIGINT | %BigInt |
BIT | %Boolean |
DATE | %Date, %FilemanDate, %MV.Date |
DOUBLE | %Double, %Float |
INTEGER | %Counter, %Integer |
NUMERIC | %Currency, %Decimal, %Numeric, %MV.Numeric |
TIME | %Time |
TIMESTAMP | %DateTime, %TimeStamp, %FilemanTimeStamp |
VARBINARY | %Binary |
VARCHAR | %Char, %EnumString, %ExactString, %List, %ListOfBinary, %Name, %Status, %String, %Text |
按ClientDataType分组的数据类型类
对于数据类型类,ClientDataType类关键字控制Caché如何将属性(该类型)映射到Java或ActiveX。下表显示了本章中列出的数据类型的ClientDataType值。
值 | Caché 数据类型 |
---|---|
BIGINT | %BigInt |
BINARY | %Binary(或任何不需要数据进行Unicode转换的属性) |
CURRENCY | %Currency |
DATE | %Date |
DOUBLE | %Double %Float |
DECIMAL | %Decimal |
FDATE | %FilemanDate |
FTIMESTAMP | %FilemanTimeStamp |
INTEGER | %Counter, %Integer, %SmallInt, %TinyInt |
LIST | %List, %ListOfBinary |
MVDATE | %MV.Date |
NUMERIC | %Numeric, %MV.Numeric |
TIME | %Time |
TIMESTAMP | %DateTime, %TimeStamp |
VARCHAR | %Char, %EnumString, %ExactString, %Name, %String, %Text |
核心属性参数
根据属性,可以指定该属性的参数以影响其行为。例如,参数可以指定最小值和最大值,用于显示的格式,排序规则,用于特定方案的定界符等等。可以在检查器中指定参数,也可以直接在类定义中键入参数。下面显示了一个示例:
Property MyProperty as MyType (MYPARAMETER="some value");
一些参数可用于所有类型的所有属性。这些参数如下:
CALCSELECTIVITY —控制“音调表”工具是否计算selectivity 属性。通常,最好将此参数保留为默认值(1)。
CAPTION —在客户端应用程序中为此属性使用的标题。
EXTERNALSQLNAME —在链接表中使用,此参数指定此属性链接到的外部表中字段的名称。链接表向导在生成类时为每个属性指定此参数。出于各种原因,例如由于远程数据库字段名称是Caché中的保留字,远程数据库上SQL字段的名称可能需要与Caché服务器上的属性名称不同。
请注意,属性参数EXTERNALSQLNAME的用途与SQLFieldName编译器关键字的用途不同,并且这些项目可以具有不同的值。SQLFieldName在Caché数据库中指定计划的SQL字段名称,而EXTERNALSQLNAME是远程数据库中的字段名称。
EXTERNALSQLTYPE —在链接表中使用,此参数指定此属性链接到的外部表中字段的SQL类型。链接表向导在生成类时为每个属性指定此参数。
JAVATYPE —此属性映射到的Java数据类型。
大多数属性参数是在数据类型类中定义的,因此是特定于类的。请参阅下一节。
类特定的属性参数
上一节列出了可用于所有属性的参数。其他可用参数取决于属性使用的类。下表列出了本章列出的数据类型类所支持的参数。参数分为三列:
- 在许多数据类型类中找到的参数或其他通常遇到的参数
- 仅在XML和SOAP上下文中有意义的参数
- 仅在少数数据类型类中出现且很少遇到的参数。
数据类型类 | 常用参数 | XML和SOAP的参数 | 较少的常用参数 |
---|---|---|---|
%BigInt | DISPLAYLIST, FORMAT, MAXVAL, MINVAL, VALUELIST | XSDTYPE | |
%Binary | MAXLEN, MINLEN | CANONICALXML, MTOM, XSDTYPE | |
%Boolean | XSDTYPE | ||
%Char | COLLATION, CONTENT, DISPLAYLIST, ESCAPE, MAXLEN, MINLEN, PATTERN, TRUNCATE, VALUELIST | XMLLISTPARAMETER, XSDTYPE | |
%Counter | DISPLAYLIST, FORMAT, MAXVAL, MINVAL, VALUELIST | XSDTYPE | |
%Currency* | DISPLAYLIST, FORMAT, MAXVAL, MINVAL, SCALE, VALUELIST | XSDTYPE | |
%Date | DISPLAYLIST, FORMAT, MAXVAL, MINVAL, VALUELIST | XSDTYPE | |
%DateTime | DISPLAYLIST, MAXVAL, MINVAL, VALUELIST | XMLDEFAULTVALUE, XMLTIMEZONE, XSDTYPE | DATEFORMAT |
%Decimal | DISPLAYLIST, FORMAT, MAXVAL, MINVAL, SCALE, VALUELIST | XSDTYPE | |
%Double | DISPLAYLIST, FORMAT, MAXVAL, MINVAL, SCALE, VALUELIST | XSDTYPE | |
%EnumString | COLLATION, CONTENT, DISPLAYLIST, ESCAPE, MAXLEN, MINLEN, PATTERN, TRUNCATE, VALUELIST | XSDTYPE | |
%ExactString | COLLATION, CONTENT, DISPLAYLIST, ESCAPE, MAXLEN, MINLEN, PATTERN, TRUNCATE, VALUELIST | XSDLISTPARAMETER, XSDTYPE | |
%FilemanDate | XSDTYPE | STRICTDATA | |
%FilemanTimeStamp | XSDTYPE | STRICTDATA | |
%Float | DISPLAYLIST, FORMAT, MAXVAL, MINVAL, SCALE, VALUELIST | XSDTYPE | |
%Integer | DISPLAYLIST, FORMAT, MAXVAL, MINVAL, VALUELIST | XSDTYPE | STRICT |
%List | ODBCDELIMITER | XSDTYPE | |
%ListOfBinary | ODBCDELIMITER | XSDTYPE | |
%Name | COLLATION,MAXLEN | XSDTYPE | INDEXSUBSCRIPTS |
%Numeric | DISPLAYLIST, FORMAT, MAXVAL, MINVAL, SCALE, VALUELIST | XSDTYPE | |
%SmallInt | DISPLAYLIST, FORMAT, MAXVAL, MINVAL, VALUELIST | XSDTYPE | |
%Status | XSDTYPE | ||
%String | COLLATION, CONTENT, DISPLAYLIST, ESCAPE, MAXLEN, MINLEN, PATTERN, TRUNCATE, VALUELIST | XMLLISTPARAMETER, XSDTYPE | |
%Text | COLLATION, CONTENT, DISPLAYLIST, ESCAPE, MAXLEN, MINLEN, PATTERN, TRUNCATE, VALUELIST | XMLLISTPARAMETER, XSDTYPE | LANGUAGECLASS, SIMILARITYINDEX |
%Time | DISPLAYLIST, FORMAT, MAXVAL, MINVAL, VALUELIST | XMLTIMEZONE, XSDTYPE | PRECISION |
%TimeStamp | DISPLAYLIST, MAXVAL, MINVAL, VALUELIST | XMLDEFAULTVALUE, XMLTIMEZONE, XSDTYPE | |
%TinyInt | DISPLAYLIST, FORMAT, MAXVAL, MINVAL, VALUELIST | XSDTYPE | |
%MV.Date | DISPLAYLIST, FORMAT, MAXVAL, MINVAL, VALUELIST | XSDTYPE | |
%MV.Numeric | DISPLAYLIST, FORMAT, MAXVAL, MINVAL, SCALE, VALUELIST | XSDTYPE | DESCALE |
此特殊用途的类仅用于迁移到Caché。
注意:术语约束是指对属性值施加约束的任何关键字。例如,MAXVAL,MINVAL,DISPLAYLIST,VALUELIST和PATTERN都是约束。
常用参数
上表中的常用参数如下:
- COLLATION 指定转换属性值以建立索引的方式。
- CONTENT 当在可能被解释为XML或HTML的上下文中使用字符串时,指定字符串的内容。指定“ STRING”(默认),“ ESCAPE”或“ MIXED”。
- DISPLAYLIST 与VALUELIST参数一起用于枚举(多项选择)属性。
- ESCAPE 如果在某些上下文中使用了字符串,则指定要进行转义的类型。使用“ XML”(默认)或“ HTML”。默认情况下,小于号、大于号和&字符被解释为< > and &
- FORMAT 指定显示值的格式。对于FORMAT的值,请使用$FNUMBER函数的format参数中指定的格式字符串。对于%Numeric或%Decimal类型的属性,还可以使用选项“ AUTO”,该选项禁止显示任何尾随零。
- MAXLEN 指定字符串可以包含的最大字符数。默认值为50。与许多其他参数一样,此参数会影响Caché验证数据的方式。请注意,这也会影响该字段如何映射到xDBC客户端。
- MAXVAL 指定数据类型的最大允许逻辑值。
- MINLEN 指定字符串可以包含的最少字符数。
- MINVAL 指定数据类型的最小逻辑值。
- ODBCDELIMITER 指定通过ODBC投影时用于构造%List值的定界符。
- PATTERN 指定字符串必须匹配的模式。PATTERN的值必须是有效的Caché模式匹配表达式。
- SCALE 指定小数点后的位数。
- TRUNCATE 指定是否将字符串截断为MAXLEN个字符,其中1为TRUE,0为FALSE。Normalize()和IsValid()方法使用此参数,但xDBC客户端不使用此参数。
Property MaxLen10 As %String(MAXLEN = 10, TRUNCATE = 1);
/// d ##class(PHA.OP.MOB.Test).AddMyClass()
ClassMethod AddMyClass(WebSocketID)
{
s one=##class(User.MyClass).%New()
s one.PropertyName="1"
s one.PropertyName1="4"
s one.FirstName="Yao"
s one.LastName="Xin"
s one.Status=""
s one.Multis("11")=11
s one.Multis("aa")="aa"
s one.Multis("Y")="X"
s one.MaxLen10="abcdefghiklmnopq"
s sc=one.%Save()
w sc
}
- VALUELIST 用于枚举(多项选择)属性。
不太常用参数
上表中不太常用的参数如下:
- STRICT (仅适用于%Integer)要求该值为整数。默认情况下,如果属性的类型为%Integer,并且指定了非整数数值,则Caché会将其转换为整数。如果某个属性的STRICT为1,则在这种情况下,Caché不会转换该值。相反,验证失败。
- DATEFORMAT (仅针对%DateTime)指定为Display或Odbc输入值指定数字日期格式时日期部分的顺序。有效参数是mdy,dmy,ymd,ydm,myd和dym。默认的DATEFORMAT是mdy。
- PRECISION (仅适用于%Time)指定要保留的小数位数。如果值为“”(默认值),则Caché保留源值中提供的小数位数。如果值为0,则Caché将提供的值舍入到最接近的秒数。
- DESCALE (仅适用于%MV.Numeric)指定要移位的小数位数(与MultiValue MD转换一样)。
- INDEXSUBSCRIPTS (仅适用于%Name)指定属性在索引中使用的下标数量,并使用逗号作为属性值的分隔符; %CacheStorage类使用此数字。值为2表示将属性值的第一个逗号存储为第一下标,而将属性值的第二个逗号存储为第二下标。
- LANGUAGECLASS (仅适用于%Text)指定语言实现类的完全限定名称。
- SIMILARITYINDEX (仅适用于%Text)指定当前属性上的索引名称,该索引具有LANGUAGECLASS参数中指定的类的SimilarityIdx()类方法所期望的结构。
- STRICTDATA (仅适用于%FilemanDate和%FilemanTimeStamp)会影响LogicalToDisplay()和LogicalToOdbc()方法的生成。当STRICTDATA = 1时,不精确或无效的日期不会更改为有效的FileManDate值。默认值为0。例如,如果Logical FileManDate值默认为31110,它将转换为3111001(2011年9月1日)。如果STRICTDATA = 1,则不会进行此转换,并且无效/不精确的逻辑值在转换为显示格式或Odbc格式时会出错。
定义枚举属性
许多属性支持参数VALUELIST和DISPLAYLIST。可以使用它们来定义枚举属性。
要为属性指定有效值的列表,请使用其VALUELIST参数。 VALUELIST的形式是分隔符分隔的逻辑值列表,其中分隔符是第一个字符。例如:
Property Color As %String(VALUELIST = ",red,green,blue");
在此示例中,VALUELIST指定有效的可能值为“红色”,“绿色”和“蓝色”,并以逗号作为分隔符。同样,
Property Color As %String(VALUELIST = " red green blue");
指定相同的列表,但以空格作为分隔符。
该属性仅限于列表中的值,并且数据类型验证代码仅检查该值是否在列表中。如果没有列表,则对值没有特殊限制。
DISPLAYLIST是一个附加列表,如果存在,则表示该属性的LogicalToDisplay()方法将返回的相应显示值。
指定文字属性的值
要为文字属性指定值,请使用SET命令,OREF和点语法,如下所示:
SET oref.MyProp=value
其中oref是OREF,MyProp是相应对象的属性,value是CachéObjectScript表达式,其计算结果为文字值。
例如:
SET patient.LastName="Muggles"
SET patient.HomeAddress.City="Carver"
SET mrn=##class(MyApp.MyClass).GetNewMRN()
set patient.MRN=mrn
文字值必须是属性类型的有效逻辑值。例如,对基于%Boolean的属性使用1或0。对于另一个示例,对于枚举属性,该值必须是VALUELIST参数指定的项之一。
指定多维属性的值
对于多维属性,可以为属性的任何下标指定值。例如:
set oref.MyStateProp("temp1")=value1
set oref.MyStateProp("temp2")=value2
set oref.MyStateProp("temp3")=value3
多维属性对于保存供对象使用的临时信息很有用。这些属性不会保存到磁盘。
Class PHA.OP.MOB.TestTwo Extends PHA.OP.MOB.Test
{
Property Multis As %String [ MultiDimensional ];
}
/// d ##class(PHA.OP.MOB.Test).GetMutils()
ClassMethod GetMutils()
{
s one=##class(PHA.OP.MOB.TestTwo).%New("1")
s one.Multis("11")=11
s one.Multis("aa")="aa"
s one.Multis("Y")="X"
s a=one.Multis("11")
w a,!
s b=one.Multis("aa")
w b,!
s c=one.Multis("Y")
w c,!
}
DHC-APP>d ##class(PHA.OP.MOB.Test).GetMutils()
11
aa
X
注意:可以用作数组。
使用属性方法
每个属性将一组生成的类方法添加到该类。这些方法包括propnameIsValid(),propnameLogicalToDisplay(),propnameDisplayToLogical(),propnameLogicalToODBC(),propnameODBCToLogical()等,其中propname是属性名称。其中一些方法是从%Property类继承的,而其他方法是从属性所基于的数据类型的类继承的。
Caché在内部使用这些方法,也可以直接调用它们。在每种情况下,参数都是属性值。
例如:
/// d ##class(PHA.OP.MOB.Test).GetAddMyClass()
ClassMethod GetAddMyClass()
{
s one=##class(PHA.OP.MOB.TestTwo).%New("1")
s one.Flag="Y"
w one.Flag="Y",! // Y
w ##class(PHA.OP.MOB.TestTwo).GenderLogicalToDisplay(one.Flag) //Yes
}
控制文字属性的SQL映射
如本书前面所述,将持久性类映射为SQL表。对于该类,除以下例外情况外,所有属性都映射到SQL:
- Transient属性
- Calculated 属性
- Private 属性
- Multidimensional 属性
指定字段名称
默认情况下,将属性(如果映射到SQL)映射为与该属性同名的SQL字段。若要指定其他字段名称,请使用属性关键字SqlFieldName。(请注意,如果属性名称是SQL保留字,则必须使用此关键字)。例如,如果有一个名为“select”的%String属性,则可以使用以下语法定义其投影名称:
Property select As %String [ SqlFieldName = selectfield ];
如果属性的名称是SQL保留字,则需要为其映射指定其他名称
指定列号
Caché自动为每个字段分配唯一的列号。要控制列号分配,请指定属性关键字SqlColumnNumber,如以下示例所示:
Property RGBValue As %String [ SqlColumnNumber = 3 ];
为SqlColumnNumber指定的值必须是大于1的整数。如果使用不带参数的SqlColumnNumber关键字,则Caché会分配一个未保留且在表中没有永久位置的列号。
如果任何属性指定了SQL列号,则Caché会为其他属性分配列号。分配的列号的起始值是指定的最高SQL列号之后的数字。
SqlColumnNumber关键字的值是继承的。
数据类型类和属性参数的影响
给定属性使用的数据类型类对SQL映射有影响。具体来说,数据类型的SQL类别(使用SqlCategory关键字定义)控制如何映射属性。在适用的情况下,属性参数也会产生影响:
Property Name As %String(MAXLEN = 30);
此属性投影为字符串字段,最大长度为30个字符。
控制计算属性的SQL映射
在Caché中,可以定义计算属性,其值可以通过CachéObjectScript计算,可能基于其他属性。下表总结了各种可能性,并指出了哪些变体计划用于SQL:
见表: 定义计算属性章节
该表假定该属性未使用其他关键字,这会阻止其进行SQL映射。例如,它假定该属性不是私有的。
Class User.MyClass Extends %Persistent [ SqlTableName = My_Class ]
{
Index IndexName On (PropertyName, PropertyName1) [ IdKey ];
Property PropertyName As %String(MAXLEN = 50);
Property PropertyName1 As %String(MAXLEN = 50);
Property FirstName As %String(MAXLEN = 50);
Property LastName As %String(MAXLEN = 50);
Property FullName As %String [ SqlComputeCode = {set {*}={FirstName}_" "_{LastName}}, SqlComputed ];
Property Status As %String;
Property messageId As %Integer [ SqlComputeCode = { set {*}=$Select({Status}="":0,1:$List($List($Extract({Status},3,$Length({Status}))))) }, SqlComputed, SqlComputeOnChange = Status ];
Property Test2 As %String [ SqlComputeCode = { set {*}={FirstName}_{FullName}}, SqlComputed, SqlComputeOnChange = (FirstName, FullName) ];
Property Multis As %String [ MultiDimensional ];
Property MaxLen10 As %String(MAXLEN = 10, TRUNCATE = 1);
Property Flag As %String(DISPLAYLIST = ",Yes,No", MAXLEN = 3, TRUNCATE = 1, VALUELIST = ",Y,N") [ InitialExpression = "N" ];
Property qty As %Float(MAXVAL = 999999999999, MINVAL = -99999999999) [ InitialExpression = 0 ];
}