IRIS知识图谱
2025-01-05 12:00:00 0 举报
AI智能生成
IRIS知识图谱
作者其他创作
大纲/内容
语法规则
区分大小写
变量名
变量下标
类名
方法名
属性名
例程名
宏名
宏包含文件(.inc文件)
标签名
锁名
嵌入式代码指令标记字符串
嵌入式`SQL`主机变量名
不区分大小写
命令
系统函数
系统特殊变量
命名空间
`SQL`语句
预处理器指令(`#include`)
嵌入式代码指令(`&html`、`&js`、`&sql`)
空格
不需要空格
标签
标签必须出现在第一列,前面没有空格字符。
如果一行有标签,则标签与该行上的任何代码或注释之间必须有空格。
如果标签有参数列表,则在标签名称和参数列表的左括号之间不能有空格。参数列表中的参数之前、之间或之后可以有空格。
多行注释
多行注释的第一行前面必须有一个或多个空格。多行注释的第二行和后续行不需要前导空格。
需要空格
命令及其第一个参数之间必须且只有一个空格。
如果命令使用后置条件,则命令与其后置条件之间没有空格。
在任何一对命令参数之间可以有任意数量的空格。
如果一行包含代码和单行注释,则它们之间必须有空格。
通常,每个命令都显示在自己的行上,不过可以在同一行上输入多个命令。在这种情况下,它们之间必须有至少两个空格。
如果命令是无参数的,那么它后面必须跟两个空格。
`Studio`提供内置的语法检查,标记任何非法使用的空格。
注释
/**/
可以显示在一行内,也可以跨行显示。
//
指定该行的其余部分是注释,可以是该行的第一个元素,也可以跟在其他元素之后。
;
指定该行的其余部分为注释,可以是该行的第一个元素,也可以跟在其他元素之后。
;;
为`;`注释类型的特殊类型。(不推荐)
///
用作紧随其后的类或类成员的类引用内容。对于类本身,类定义开始之前的`///`注释提供类引用内容的类描述,这也是类的`Description`关键字的值。
#;
可以从任何列开始,但必须是该行的第一个元素。该注释不出现在 `INT` 代码中。(推荐)
##;
可以从任何列开始。可以是行中的第一个元素,也可以跟在其他元素之后。 该注释不会出现在 INT 代码中。 `##;`可以在 `ObjectScript` 代码、嵌入式 `SQL` 代码中使用,或者与 `#Define`、`#Def1Arg` 或 `##Continue` 宏预处理器指令在同一行。
字面常量
概念
字面常量就是组成变量的表达式,由字符串或数值的字符组成的常量值。
标识符
概念
标识符是变量、例程或标签的名称。通常,合法标识符由字母和数字字符组成,标识符区分大小写。
注意事项
标识符的第一个字符可以是百分号(`%`)字符。一般以`%`字符开头的名称为系统保留。
`IRIS`中没有保留关键字,可以使用任何有效的标识符作为变量名、函数名或标签。
最好避免使用命令名、函数名或其他此类字符串的标识符。
`ObjectScript`代码包括对嵌入式`SQL`的支持,避免使用`SQL`保留字命名任何函数、对象、变量或类。
标签
概念
标签即子例程
注意事项
第一个字符必须是字母数字字符或百分比字符(`%`)。
最多`31`个字符。长于`31`个字符与标签的前`31`个字符匹配。
可以使用`$ZNAME`函数来验证标签名称是否合法。
标签是程序的入口点,但没有定义封闭的代码块。意味着一旦标签的代码执行,将继续到下一个标签的代码块,除非执行被停止或重定向到其他地方。
三种方式可以停止执行代码
执行遇到退出`QUIT`或返回`RETURN` 。
执行遇到右大括号(`}`)。
执行遇到下一个过程块(带有参数括号的标签)。
基础数据类型
`ObjectScript`是一种无类型语言。不必声明变量的类型。
字符串
概念
字符串是由一组零个或多个字符,可以包含任何字符,包括字母、数字、标点符号、空格和控制字符由等组成,包裹在一组引号(`""`)中。
注意事项
如果要在字符串中包含引号字符`"`,使用两个`""`表示一个`"`。除了双引号字符没有其他需要转义的字符。
可以使用`_`连接运算符将两个字符串连接成单个字符串,字符串中可以可以使用`$CHAR`函数输入非打印字符,非打印字符不一定都可以显示。
使用等于(`=`)和不等于(`'=`)运算符来比较两个字符串时,字符串比较区分大小写。
运算符比较数字字符串和数字时需要注意,字符串比较,而不是数字比较。
只有包含规范形式的数字的字符串才等于其相应的数字。(`-0`不是规范数字。)
`<`、`>`、`<=`或`>=`运算符不能用于执行字符串比较。这些运算符将字符串视为数字,并始终执行数字比较。使用这些运算符进行比较时,将为非数字字符串视为`0`。
字符串中连接`$char(0)`,显示相同,比较时实则不相等。
最大字符串大小是可配置的。如果启用了长字符串,则最大字符串大小为`3,641,144`个字符。否则,最大字符串大小为`32,767`个字符。默认情况下启用长字符串。
字符串文字的长度以字符串中的字符数而不是字节数来度量。
不包含任何值的字符串称为空字符串。由两个引号字符`""`表示。空字符串被视为已定义的值。它的长度为`0`,空字符串与`null`(`$CHAR(0)`)组成的字符串不同。
数字
概念
数字类型:包含从`0`到`9`的十进制数字,并且必须至少有一个数字字符,可以包含任意数量前导加号`+`和减号`-`。
数字字符串
用引号括起来的字符串数字,数字字符串在功能上与相应的数字相同。(`"-0"`不是规范数字。)
科学记数法
用`E`记数法表示的数字,`E`后面可指定`+`加号或`-`负号表示正负的`10`次密。
数字规范形式
规范形式将所有前导零和尾随零都将被删除。
混合数字字符串
以数字字符开头,后跟一个或多个非数字字符的字符串。
混合数字字符串在算术运算时解析为可运算的数值,数值部分是从起始到非数字字符,之后的字符串的其余部分将省略。
注意事项
使用可以`$FNUMBER`或`$JUSTIFY`系统函数将规范形式去掉的小数的`0`恢复。
对于算术、大于、小于运算,非规范形式的数字字符串在功能上与相应的数字相同。
可以使用连接运算符(`_`)将一个数字连接到另一个数字。首先将每个数字转换为其规范形式,然后对结果执行字符串连接。
小数
两种不同表示形式
Decimal标准小数
默认小数,提供最高级别的精度`-18`位十进制数字。
IEEE双精度浮点小数
IEEE浮点数使用二进制表示法进行编码。精度为`53`个二进制位,相当于`15.95`个十进制数字的精度。支持特殊值`INF`(无穷大)和`NaN`(非数字)
最大值
数字的最大整数是`2`的`64`位带符号位表示的最大数字,取值范围是`19`位整数`-9223372036854775808`和`9223372036854775807`。
超过最大数的运算,产生大于这些19位整数的数字的算术运算将其低位数字替换为零。
除了`19`位的舍入之外,大于308或309位的整数还会导致`<MAXNUMBER>`错误。取整行为也会在146或147位发生变化,具体取决于整数。
对象
概念
对象值引用内存中对象的实例。可以将对象引用分配给任何局部变量。
注意事项
使用`$ISOBJECT`函数确定变量是否包为对象。
将对象值赋给变量会增加对象的内部引用计数。
当对象的引用数量为`0`时,会自动销毁该对象等于调用其`%OnClose()`方法并将其从内存中移除。
布尔
概念
如果表达式的计算结果为非零数值,则将其解释为`1`(`TRUE`),如果计算结果为零数值,则将表达式解释为`0`(`FALSE`)。将非数字字符串计算为`0`。
位串
概念
位串表示具有`0`、`1`编号位的逻辑集合。字符串中的位从位号`1`开始编号。其余未显示的位为`0`。
日期
相关函数
$HOROLOG
`$HOROLOG` 变量 - 包含当前进程的本地日期和时间。
$NOW
`$NOW` 函数 - 返回当前日期的本地日期和时间,以小数秒为单位。
$ZDATE
`$ZDATE` 函数 - 验证日期并将其从内部逻辑格式转换为指定的显示格式。
$ZTIME
`$ZTIME` 函数 - 验证时间,并将其从内部逻辑格式转换为指定的显示格式。
$ZDATETIME
`$ZDATETIME` 函数 - 验证日期和时间,并将其从内部逻辑格式转换为指定的显示格式。
$ZTIMESTAMP
`$ZTIMESTAMP` 变量 - 包含协调世界时间格式的当前日期和时间。
$ZTIMEZONE
`$ZTIMEZONE` 变量 - 包含格林威治子午线的时区偏移量。
$ZHOROLOG
`$ZHOROLOG` 变量 - 启动库以来经过的秒数。
$ZDATEH
`$ZDATEH` 函数 - 验证日期并将其从显示格式转换为内部逻辑格式。
$ZTIMEH
`$ZTIMEH` 函数 - 验证时间并将其从显示格式转换为内部逻辑格式。
$ZDATETIMEH
`$ZDATETIMEH` 函数 - 验证日期和时间,并从显示格式转换为内部逻辑格式。
系统函数
编码相关函数
$ASCII
$CHAR
$ZISWIDE
$ZHEX
$ZCONVERT
位相关函数
$BIT
$BITCOUNT
$BITFIND
$BITLOGIC
$ZBOOLEAN
$FACTOR
$NCONVERT
$SCONVERT
条件相关函数
$CASE
$SELECT
替换相关替换
$CHANGE
$REPLACE
$TRANSLATE
反射相关函数
$CLASSMETHOD
$CLASSNAME
$METHOD
$PARAMETER
$PROPERTY
判空相关函数
$DATA
$GET
循环相关函数
$ORDER
$QUERY
$NEXT
浮点相关函数
$DECIMAL
$DOUBLE
数字格式化相关函数
$NUMBER
$INUMBER
$NORMALIZE
$FNUMBER
字符串相关函数
$FIND
$LENGTH
$REVERSE
$JUSTIFY
分隔截取相关函数
$EXTRACT
$PIECE
自增相关函数
$INCREMENT
$SEQUENCE
判断相关函数
$ISOBJECT
$ISVALIDNUM
$ISVALIDDOUBLE
数组相关函数
$LIST
$LISTBUILD
$LISTDATA
$LISTFIND
$LISTFROMSTRING
$LISTGET
$LISTLENGTH
$LISTNEXT
$LISTSAME
$LISTTOSTRING
$LISTUPDATE
$LISTVALID
正则表达式相关函数
$LOCATE
$MATCH
$ZSTRIP
时间相关函数
$NOW
$ZDATE
$ZDATEH
$ZDATETIME
$ZDATETIMEH
$ZTIME
$ZTIMEH
全局变量相关函数
预取相关函数
$PREFETCHOFF
$PREFETCHON
排序相关函数
$SORTBEGIN
$SORTEND
下标相关函数
$QLENGTH
$QSUBSCRIPT
计算相关函数
$ZABS
$ZEXP
$ZLN
$ZLOG
$ZPOWER
$ZSQR
三角相关函数
$ZARCCOS
$ZARCSIN
$ZARCTAN
$ZCOS
$ZCOT
$ZCSC
$ZSEC
$ZSIN
$ZTAN
校验相关函数
$ZCRC
$ZCYC
动态库相关函数
$ZF
$ZF(-100)
$ZF(-1)
$ZF(-2)
$ZF(-3)
$ZF(-4)
$ZF(-5)
$ZF(-6)
文件相关函数
$ZSEEK
$ZSEARCH
字节相关函数
$ZWPACK
$ZWBPACK
$ZWUNPACK
$ZWBUNPACK
$ZWASCII
$ZWCHAR
$ZLASCII
$ZLCHAR
$ZDASCII
$ZDCHAR
$ZQASCII
$ZQCHAR
代理对相关函数
$WEXTRACT
$WFIND
$WLENGTH
$WREVERSE
$WASCII
$WCHAR
$WISWIDE
工具相关函数
$ZUTIL
其他函数
$COMPILE
$NAME
$STACK
$TEXT
$VIEW
$XECUTE
$ZNAME
$ZVERSION(1)
$ZZENKAKU
$ZPOSITION
$ZWIDTH
$RANDOM
位串
todo
第5讲 数据类型 - 位串
对象 - 需要完善
常见父类对象
%RegisteredObject
%Persistent
%SerialObject
None
类成员
参数Parameters
方法Methods
Properties属性
Storage definitions
Indices
SQL triggers sql
关键字
继承
编译类
部署类
包
类参数
方法
Code Methods
Call Methods
Method Generators代码生成器
铸造方法
重写继承的方法
##super()
注册对象
简介
使用
持久性对象
简介
使用
其他属性
嵌入式对象
属性
使用和覆盖属性方法
使用集合
使用流
关系
父子
一对多
外键
方法和触发器生成器
使用类查询
使用XData块
类映射
类回调方法生命周期
定义数据类型类
实施动态调度
对象特性功能
…
i%
$this
##super
##class
Populate实用程序
%Dictionary类
简介
ObjectScript
`ObjectScript` 是一种对象编程语言,设计用于在`ISC`公司的`IRIS`数据平台上快速开发复杂的业务应用程序。
`ObjectScript`是基于`ISO 11756-1999`标准M编程语言开放升级而来。 与原生`M`开发编程语言相比,集成了面向对象编程的支持。
特点
强大的内置函数可用于处理字符串。
对面相对象的支持,包括方法,属性和多态性。
用于在应用程序中控制流程的各种命令。
一组用于处理`I/O`设备的命令。
支持多维数组:局部变量和`Global`(全局变量,持久数据)。
支持高效的嵌入式`SQL`。
支持间接引用(反射)以及运行时和编译时计算和执行。
IRIS
`IRIS` 是一种集成对象编程语言的数据库,最底层是多维数组存储,又可以使用对象和`SQL`来访问,也就是说有三套接口来同时瞄准一套数据和元数据,最大化开发灵活性了。
`ObjectScript`源代码被编译为在`IRIS`虚拟机中执行的目标代码。该目标代码针对通常在业务应用程序中发现的操作进行了高度优化,包括字符串操作和数据库访问。
以下环境中使用`ObjectScript`
从终端`Terminal`的命令行中进行交互。
作为`IRIS`对象类方法的实现语言。
创建`ObjectScript`例程:`IRIS`中包含并执行的各个程序。
作为`IRIS SQL`中存储过程和触发器的实现语言。
作为`Web Server Pages`应用程序中的服务器端脚本语言。
变量
概念
变量是内存运行时值的位置的名称,也就是说变量存在内存中。
必须使用`SET`命令定义变量,变量是非类型化的。也就是说,没有指定的数据类型,可以接受任何数据值。也可以理解为泛型。
类别
局部变量
概念
只有创建它的进程或方法才能访问的变量,该变量在进程结束或方法结束时自动删除。
注意事项
当在事务里时不会将局部变量`SET`或`KILL`视为日志记录的事务事件,回滚事务对局部变量没有影响。
限制
局部变量名称限制为`31`个字符。可以指定长度超过`31`个字符的名称,但仅使用前`31`个字符。因此,局部变量名在其前`31`个字符内必须是唯一的。
#Dim
可以使用`#Dim`预处理器指令定义变量与变量类型,通过`#Dim`定义的变量可获得该对应类型的帮助提示。
进程私有Global
概念
只有当前进程访问并在进程结束时删除的变量。
场景
进程私有全局变量一般用于存储临时的大量数据,一般用于汇总数据等。
进程私有`Global`名称的几种形式
^||name
推荐使用的形式
^|"^"|name
^["^"]name
^["^",""]name
注意事项
事务回滚对进程私有`Global`没有影响。
`^GETPPGINFO`
作用
使用`^GETPPGINFO`工具以块为单位显示当前进程私有`Global`及其空间分配,`^GETPPGINFO`列出进程私有`Global`的下标或值。可以通过指定进程`ID`来显示特定进程的进程私有`Global`,也可以通过指定`“*”`通配符字符串来显示所有进程的进程私有`Global`。
注意事项
必须在`%SYS`命名空间中才能调用`^GETPPGINFO`。
场景
将进程私有`Global`导出。
%SYS>d ^GETPPGINFO("*","MNN","E:/temp/ppg.txt")
限制
进程私有`Global`名称限制为`31`个字符,不包括前缀字符。可以指定长度超过`31`个字符的名称,但仅使用前`31`个字符。因此,进程专用全局名称在其前`31`个字符内必须是唯一的。
Global
概念
存储在数据库中的持久数据。`Global`可以从任何进程访问,并在创建它的进程结束后也一直保存在磁盘中。`Global`指定于某个命名空间。
注意事项
`Global`的`set`或`kill`操作视为日志记录的事务事件,回滚事务将撤消这些操作。
相关函数
$ZREFERENCE
使用`$ZREFERENCE`特殊变量来确定最近使用的全局变量的名称。
$QSUBSCRIPT
使用`$QSUBSCRIPT`函数返回指定全局变量节点的名称。
$QLENGTH
使用`$QLENGTH`函数返回下标的数量。
限制
`Global`名称限制为`31`个字符,不包括前缀字符。可以指定长度超过`31`个字符的名称,但仅使用前`31`个字符。因此,全局名称的前`31`个字符必须是唯一的。
数组变量
概念
具有一个或多个下标的变量。局部变量、进程私有`Global`、`Global`和对象属性都可以用作带下边的数组变量。
带下标的局部变量或对象属相称为多维数组。
数组变量也可称为下标变量。
限制
下标的最大长度为`511`个编码字节。
局部变量的最大下标级别数为`255`。
全局变量或进程私有全局变量的最大下标级别数为`253`。
多维数组
概念
多维数组是由一个或多个元素组成的局部变量,每个元素都有唯一的下标。可以混合使用不同种类的下标。
注意事项
多维数组的下标是正数或负数、字符串及其组合。下标可以包括任何字符,包括`Unicode`字符。数字下标作为规范数字存储和引用。字符串下标作为区分大小写的文字存储和引用。规范数字和包含该规范数的字符串是等价的下标
操作多维数组
`SET`将值放入数组中。
`KILL`删除全部或部分数组结构。
`Merge`将数组结构的全部或部分复制到第二个数组结构。
`$ORDER`和`$QUERY`允许迭代数组的内容。
`$DATA`允许测试数组中是否存在节点。
多维树形结构
多维数组的整个结构称为树;它从顶部开始,向下生长。词根`array`,在顶部。根及其任何其他下标形式称为节点。下面没有节点的节点称为叶。下面有节点的节点称为父代或祖先。具有父节点的节点称为子节点。父母相同的孩子被称为兄弟姐妹。所有同级在添加到树中时都会自动按数字或字母顺序排序。
稀疏多维存储
多维数组是稀疏的。这意味着上面的示例仅使用七个保留的内存位置,每个定义一个节点。此外,由于不需要声明数组或指定它们的维度,因此还有额外的内存优势:没有提前为它们保留空间;它们在需要之前不使用空间;它们使用的所有空间都是动态分配的。
效率对比
多维数组 > 进程私有`Global` > `Global`
多维数组的效率差不多是前两者的一倍。
系统特殊变量
概念
特殊的内置变量,包含操作环境的特定属性值。
对象属性
概念
与对象实例相关联并存储在其中的值。
百分比变量
概念
以`%`字符开头的变量称为“百分比变量”,百分比变量与局部变量具有不同的作用域,可将百分比变量视为当前进程内的全局变量。
注意事项
注:只有以“`%Z`”或“`%z`”开头的变量才可用于应用程序代码;其他所有百分比变量将保留给系统使用。
场景
通常再取固定配置的时候会用到它,来提升程序运行效率。
入口函数的全局设置,例如%session,%request等。
注意事项
大多数命令和函数在使用之前都需要定义变量。如果变量未定义,则默认情况下,引用它会生成`<UNDEFINED>`错误。
`$increment`、`$get`、`$data`系统函数可以使用未定义的变量。
进程私有`Global`、`Global`、局部变量,百分比变量可以有相同的名称,但是是不同的变量,也不会相互覆盖。
ProcedureBlock关键字
在默认情况下,程序块中使用的局部变量都视为私有变量,其用作用于仅在当前方法中使用。不能在默认情况下对私有变量使用`new`命令。
如果在 `Not ProcedureBlock` 类里的方法一定要初始化`new`命令,否则因为变量覆盖可能会发生死循环。
变量类型转换
Number to String
使用表示数字值的字符串。
String to Number
字符串的前导数字字符被解释为数字。
Object to Number
使用给定对象引用的内部对象实例编号。
Object to String
使用`n@cls`形式的字符串,其中`n`是内部对象实例编号,`cls`是给定对象的类名。
Number to Object
不允许
String to Object
不允许
表达式
概念
表达式是可以计算为生成单个值的代码集。
函数
概念
函数是执行操作并返回值的例程。在命令行中调用函数。此调用向函数提供参数值,该函数使用这些参数值执行某些操作。然后,该函数向调用命令返回结果。
注意事项
如果不需提供返回值,可以用`DO`或 `JOB`命令。
函数可以指定参数或没有参数。函数的参数用逗号分隔。参数如果设置了默认值,也可以省略。如果省略某个参数,将使用该参数的默认值。由于参数是有按位置的,因此不能省略指定参数列表中的参数,需要用逗号占位。
通常,参数可以指定为字符串、变量或另一个函数的返回值。在少数情况下,参数必须作为字符串提供。
大多数情况下,必须先定义变量,然后才能将其指定为函数参数,否则会生成错误。在少数情况下,不必定义参数变量。
函数参数是向函数提供值的输入变量。函数不修改作为输入参数提供的变量的值。在少数情况下,函数既返回值又设置输出参数。
系统函数:不能修改这些函数。这些函数以`$`符号开头。大部分系统函数名称都有缩写。
**注:一般例程里叫做函数,类里叫做方法。**
类别
Routines
例程
概念
例程是可调用编写的代码块,它是`ObjectScript`程序。其名称由用于保存它的`.mac`文件的名称确定。
调用语法
d ^RoutineName
无返回值
s x = $$^RoutineName
有返回值
注意事项
如果直接用变量接收`.mac`文件名称返回值,默认调用`.mac`文件第一个子例程方法,并且该方法不能为标签方法。
Subroutines
子例程
概念
子例程是例程内的命名代码块。
通常,子例程以`LABEL`开头,以`QUIT`语句结束,可以接受参数,不返回值。
调用语法
d Subroutine^Routine
声明语法
label [ ( param [ = default ][ , ...] ) ]
code
QUIT
code
QUIT
Functions
函数、外部函数
内部函数
系统提供的函数称为内部函数
例如:$$maxval^%apiSQL
外部函数
自定义的函数称为外部函数
概念
函数是例程中的命名代码块。
通常,函数以`LABEL`开头,以`QUIT`语句结束。可以接受参数,有返回值。
调用语法
s rval = $$Function() /* 返回值 */
d Function^Routine /* 忽略返回值 */
s x = $$Function^RoutineName(params)
声明语法
label ( [param [ = default ]] [ , ...] )
code
QUIT expression
code
QUIT expression
区别
与子例程的区别就是有返回值。
注意事项
当方法添加关键字`PRIVATE`时,该例程以外的程序调用不到。会报错`<NOLINE>`错误。只能在当前`mac`中使用。默认是公共的,
Label
标签
概念
标签是例程或类方法内的命名代码块。
没有接受参数,无返回值。
调用语法
d label
d label^Routine
注意事项
定义的标签如果没有退出命令例如`quit`,`retrun`是可以顺序执行之后的标签,直到遇到退出命令。
Procedures
程序、过程
概念
`Procedures`过程是一种特殊的ObjectScript例程。
可以设置公共,私有方法属性。
可以接受若干参数。
自动将在其创建的变量设置为作用域中的局部变量。
可以设置是否返回值。
可以引用和设置外部的变量。
区别
子例程始终是公共的,不能返回值。
函数始终是公共的,需要显式声明局部变量(否则将覆盖外部变量),并且必须具有返回值。
例程是`ObjectScript`程序。可以包括一个或多个过程、子例程和函数,以及三者的任意组合。
声明语法
label([param[=default]][,...]) [[pubvar[,...]]] [access] {
code
}
code
}
`label` 过程名称。
`param` 程序的每个参数的变量。
`default` 它前面的参数的可选默认值。
`pubvar` 公共变量。
`access` 可选关键字,用于声明过程是公共的还是私有的。有两个可用值:`public`,`Private`。
`code` 代码,用大括号括起来。
注意事项
默认情况下,过程是私有的,这意味着只能从同一例程中的其他地方调用。可以创建公共的过程,在过程名称后使用`Public`关键字。可以从其他例程调用公共过程。
声明公共变量。可用于所有过程和方法;即此过程或方法调用的过程和方法以及调用此过程或方法的过程和方法。应该以这种方式定义数量相对较少的变量,以充当应用程序的环境变量。要定义公共变量,请将它们列在过程名称及其参数后面的方括号中。
过程中可以定义标签,其中标签都是该过程的私有标签,并且只能从该过程内访问。
在过程中不允许重复标签,在例程中与过程中允许重复标签。具体地说,在不同的过程中允许重复标签。
过程比以前在子例程和用户定义函数中提供的编码更先进。过程参数在过程内的作用域中自动是局部的。它们不需要`NEW`命令来确保它们不会覆盖其他值,因为它们是过程专用的,此外,公共变量的显式声明允许引用应用程序中的全局变量。
公有变量与私有变量
在过程中,局部变量可以是“公共的”或“私有的”。公共列表(`Pubvar`)声明过程中公共变量,过程中的所有其他变量为私有变量。
私有变量在进入过程时未定义,在退出过程时销毁。
公有变量列表为空,则所有变量都是私有的。在这种情况下,方括号是可选的。
Methods
实例方法
概念
实例方法,必须初始化对象才能调用的方法。
调用语法
ClassMethod Method()
{
s m = ..%New()
d m.Method1()
}
Method Method1()
{
w "实例方法!"
}
{
s m = ..%New()
d m.Method1()
}
Method Method1()
{
w "实例方法!"
}
ClassMethods
类方法、静态方法
概念
类方法(静态方法),可直接调用,不需要初始化对象。
声明语法
ClassMethod ClassMethod()
{
w "类方法!"
}
{
w "类方法!"
}
注意是想
类方法源代码`int`文件实际上可作为例程`Routine`文件。如果类加上关键字`[Not ProcedureBlock]`,则方法为子例程函数,反之为方法为过程。
Program
程序
概念
程序员写的一个完整程序代码。可以包含多个类,方法,例程,过程,某个功能模块的统称。
SystemFunctions
内部函数、系统方法
概念
系统函数由名称前的 `$` 字符前缀和名称后的括号标识。也称为内部函数。
区别
Label
不带括号,没有返回值。
Subroutines
带括号,没有返回值。
Routines
`.mac`文件、`int`文件。
Functions
带括号,有返回值。
Procedures
带大括号。
Methods
实例方法。
ClassMethods
静态方法。
SystemFunctions
系统方法。
参数
概念
当执行方法时,会按位置将实际列表中的参数映射到形式列表中的相应参数。因此,实际列表中第一个参数的值放在形式列表中的第一个变量中,第二个值放在第二个变量中,依此类推。这些参数的匹配是按位置进行的,而不是按名称进行的。因此,用于实际参数和形式参数的变量不需要相同的名称。方法通过引用其正式列表中的相应变量来访问传递的值。
注意事项
如果实际参数列表中的参数少于形式参数列表中的参数,则形式参数列表中没有匹配的元素是未定义的。可以为未定义的形式参数指定默认值。
如果实际参数列表中的参数多于形式参数列表中的参数,则会出现`<PARAMETER>`错误。
在标签或例程当中,如果形式参数列表中的变量比实际参数列表中的参数多,则不定义额外的变量。
详见第22讲 调用命令 - do命令,考虑把do命令重复的内容给删除掉。
类方法隐式创建并声明方法中使用的变量为私有变量,这样调用代码中已存在的同名变量就不会被覆盖。它将这些变量的现有值放在程序堆栈上。当它调用`QUIT`命令时,会对每个形式变量执行隐式`kill`命令,并从堆栈恢复它们以前的值。
限制
实际参数的最大数量为254个。
种类
传值参数
概念
若要按值传递,请在实际参数列表中指定值、表达式或局部变量。对于表达式,首先计算表达式,然后传递结果值。对于局部变量,传递变量的当前值。所有指定的变量名都必须存在,并且必须具有值。
引用参数
注意事项
通过引用传递,指定的变量或数组名称不必在方法引用之前声明存在。
按引用传递多维数组是将数组名称传递给方法的唯一方式。注:不能通过引用传递下标变量。
形参列表:接收引用传递的变量不需要在形参列表中使用特殊语法。形式参数列表中不允许使用句点前缀。在例程或标签在形参列表中,允许在变量名之前使用与号(`&`)前缀;按照习惯,此`&`前缀用于表示此变量是通过引用传入。前缀`&`是可选,不执行任何操作;使源代码更易于阅读和维护的有用约定。
在类方法中指示参数应该通过引用传递,并且不希望传入值,在方法签名中在参数名之前包含添加`Output`修饰符。
在类方法中要指示应通过引用传递参数,请在方法签名中参数名称之前添加`ByRef`修饰符。
语法
.name
实际参数列表:实际参数列表中局部变量或数组名称前面的句点是必填项。它指定变量是通过引用传递的,而不是通过值传递的。
可变参数
概念
可以指定接受可变数量的参数。
`ObjectScript`通过创建下标变量来处理传递数量可变的参数,为每个传递的变量创建一个下标。变量包含传递的参数数量。变量下标包含传递的值。
语法
arg...
可以通过在最后一个参数的名称后附加三个点来实现。此参数必须是参数列表中的最后一个参数。
注意事项
在标签函数使用可变参数。可以接收通过引用传递的可变数量的值。
运算符
运算符符号表
运算符优先级
**`ObjectScript`中的运算符优先级严格从左到右**;在表达式中,操作按出现的顺序执行。
这与其他语言不同,在其他语言中,某些运算符具有比其他运算符更高的优先级。
可以在表达式中使用括号,圆括号将包含的表达式分组,以强制某些操作先于其他操作进行或相互嵌套来更改计算顺序。
**一元运算符优先于二元算术运算符。** 首先执行数字表达式并执行一元操作。然后,对表达式求值并生成结果。
逻辑运算符
相关运算符
单逻辑运算符
&
与
!
或
双逻辑运算符
&&
与
||
或
Not运算符
'
非
`NOT`运算符取反布尔值。如果布尔值为`TRUE`(`1`),则`NOT`运算符将布尔值取反赋值`FALSE`(`0`)。如果布尔值为`FALSE`(`0`),`NOT`运算符将布尔值取反赋值`TRUE`(`1`)。
注意事项
**注:推荐使用双逻辑运算符,假设有多个`AND`测试提条件,如果第一个表达式布尔结果为`0`,那么剩余的右侧表达式不在进行逻辑运算。可以避免不必要的表达式计算耗时。**
算术运算符
相关运算符
加法运算符
+
加法运算符产生两个数值解释的操作数之和。讲使用任何前导有效数字字符作为操作数的数字值,并生成操作数的数字值之和的值。
减法运算符
-
减法运算符产生两个数值解释的操作数之间的差值。将任何前导的有效数字字符解释为操作数的数字值,并生成减法后值。
乘法运算符
*
乘法产生两个数值解释的操作数的乘积。使用任何前导数字字符作为操作数的数字值,并生成乘积。
除法运算符
/
除法产生将两个数值解释的操作数相除的结果。使用任何前导数字字符作为操作数和乘积的数字值,结果就是商。
注意事项
操作数没有前导数字字符,则认为其值为零。不允许将数字除以零。返回`<Divide>`错误消息.
求幂运算符
**
求幂运算符产生左操作数的指数化值,该值是右操作数的幂。
注意事项
开方时可能会产生开不尽的意外结果。
可以使用`zpower`函数来代替`**`。
规则
0 ** 0
`0`的零幂等于`0`。但是,幂指数是`IEEE`双精度数,则零的零幂为`1`。
0 ** n
0`的任意正数`n`的幂是`0`。包括`0 ** $DOUBLE("INF")`。将`0`取负数的幂会导致错误:负数会生成`<ILLEGAL VALUE>`错误;`$double`负数会生成`<DIVIDE>`错误。
Num ** 0
任何非零数的零幂都是`1`。包括`$DOUBLE("INF") ** 0`。
1 ** n
`1`的任意次幂是`1`。
-num ** .N
负数的小数的幂会生成`<ILLEGAL VALUE>`错误。
$DOUBLE("INF") ** n
无穷大数字的`0`次方是`1`。无穷大与任何正数的幂都是`INF`。无穷大与任何负数的幂均为`0`。
$DOUBLE("NaN")
求幂运算符两侧的`NaN`始终返`NaN`。
Num ** nnn
大于`1`且具有较大正指数值的正数或负数会生成`<MAXNUMBER>`错误。
Num ** -nnn
大于1且具有较大负指数值的正数或负数返回0。
.Num ** -nnn
小于`1`且具有较大正指数值的正数或负数返回0。
.Num ** -nnn
小于`1`且具有较大负指数值的正数或负数会生成`<MAXNUMBER>`错误。
整除运算符
\
整数除法运算符产生左操作数除以右操作数的整数结果。不返回余数,也不四舍五入结果。
取余运算符
#
取余运算符在两个数值解释的操作数上产生算术模运算符的值。当两个操作数为正时,模运算是左操作数整数除以右操作数的余数。
一元运算符
对其操作数进行数值解释。如果操作数是字符串将字符串的前导数字字符被解释为数字。
关系运算符
数值关系运算符
概念
数值关系运算符使用操作数的数值来生成布尔结果。
相关运算符
小于运算符
小于运算符测试左操作数是否在数值上小于右操作数,并返回其布尔值。
大于运算符
大于运算符测试左操作数是否在数值上大于右操作数,并返回其布尔值。
大于等于运算符
大于等于运算符测试左操作数是否在数值上大于等于右操作数,并返回其布尔值。
小于等于运算符
小于等于运算符测试左操作数是否在数值上小于等于右操作数,并返回其布尔值。
字符串关系运算符
概念
字符串关系运算符使用操作数的字符串来生成布尔结果。
相关运算符
等于运算符
等于运算符测试两个操作数的字符串相等。如果两个操作数是具有相同字符序列且没有中间字符的相同字符串,则返回结果`TRUE`(`1`);否则返回结果`FALSE`(`0`)。
注意事项
数字字符串在数值上相等,并不意味着在等于测试中相等。
`IEEE`双精度小数(`$DOUBLE`数)与标准浮点数(`$DECIMAL`数)之间的精确比较,无需舍入。`$DOUBLE`和`$DECIMAL`数字之间的等于比较可能会不相等。
不等于运算符
通过将`NOT`运算符与等于运算符`=`一起使用来指定不等于运算。并返回其布尔值。
包含运算符
包含运算符测试右操作数中的字符是否在左操作数的字符串中。如果左操作数包含右操作数的字符串,则结果为`TRUE`(`1`)。如果左操作数不包含右操作数的字符串,则结果为`FALSE`(`0`)。如果右操作数为`""`空字符串,则结果为`TRUE`(`1`)。
不包含运算符
通过将`NOT`运算符与包含运算符一起使用,如果左操作数不包含右操作数的字符串,则返回`TRUE`,如果左操作数包含右操作数的字符串,则返回`FALSE`。
跟随运算符
跟随运算符测试左操作数中的字符的`ASCII`是否在右操作数中的字符`ASCII`之后。
跟随运算符对比每个字符串都从最左边的字符开始。在左操作数中找到与右操作数中相应位置的字符不同的字符或两个操作数中都没有更多的字符比较时结束。
以下情况返回TRUE
如果左操作数中的第一个字符的ASCII值高于右操作数中的对应字符。
如果右操作数比左操作数短,其余字符相同。
以下情况返回FLASE
左操作数中第一个唯符的ASCII值低于右操作数中相应字符的ASCII值。
左操作数比右操作数短,其余字符相同。
左操作数与右操作数相同。
非跟随运算符
通过将`NOT`运算符与跟随运算符一起使用来指定非跟随运算。
排序运算符
排序规则
在排序规则中,空字符串首先排序,然后是按数字顺序排列的规范数字,首先是负数,然后是零和正数,最后是非数字值。
测试左操作数是否右操作数之后排序。
非排序运算符
通过将`NOT`运算符与排序运算符一起使用来指定非排序运算。
模式匹配
概念
模式匹配运算符测试左操作数中的字符是否由右操作数中的模式正确匹配。它返回一个布尔值。匹配返回`1`,不匹配返回`0`。
模式匹配运算符
是一种用问号(`?`)分隔模式字符串开头的语法。
模式代码
A
描述
匹配任何大写或小写字母字符。
范围
`包括ASCII值65到90(A到Z)、97到122(a到z)、170、181、186、192到214、216到246和248到255`。
C
描述
匹配任何控制字符
范围
`ASCII值0到31和扩展ASCII值127到159`。
E
描述
匹配任何字符,包括非打印字符、空格字符和控制字符。
L
描述
匹配任何小写字母字符。
范围
`包括ASCII值97到122(a到z)、170、181、186、223到246和248到255`。
N
描述
匹配数字字符0到9。
范围
`ASCII 48`到`57`。
P
描述
匹配任何标点符号。
范围
`包括ASCII值32到47、58到64、91到96、123到126、160到169、171到177、180、182到184、187、191、215和247`。
U
描述
匹配任何大写字母字符。
范围
`包括ASCII值65到90(A到Z)、192到214和216到222`。
注意事项
模式代码不区分大小写。
如果模式匹配仅匹配了字符串的一部分,则模式匹配将返回`FALSE(0)`。也就是说,当模式匹配完成时不能有任何剩余的字符串。
模式复杂性
具有多个交替和不确定的模式匹配在应用于长字符串时,会递归到系统堆栈中的多个级别。在极少数情况下,这种递归可能会上升到几千个级别,从而可能会引起堆栈溢出和进程崩溃。当这种极端情况发生时,会发出`<Complex Pattern>`错误。
如果出现此类错误,建议简化模式,建议使用正则表达式而不应该使用模式匹配。
模式可以出现的次数
定义模式可指定目标操作数中出现的次数范围
n.n
省略第一个`n`的默认为零。
0到n
省略第二个`n`的则匹配第一个`n`到无穷字符。
n到任意数字
都省略匹配任意数量字符。
0到任意数字
可以匹配`N`次模式代码。
种类
组合模式
格式
Pattern1Pattern2
使用组合模式时,将对照目标操作数由`pattern1`后跟`pattern2`组成的序列进行匹配。
多组模式
可以将`n`个模式组合成任意长度的序列。
交替模式
测试操作数是否与一组指定模式序列中的一个或多个匹配。它为模式匹配提供了逻辑或功能。
多重模式解释
当一个模式与一个操作匹配时,可能有多种模式解释。
非模式匹配运算符
可以通过将`NOT`运算符与模式匹配运算符一起组合来使用。
'?
间接寻址
概念
间接操作符(`@`)允许间接为变量赋值。间接寻址是一种通过数据字段的内容提供部分或全部命令行、命令或命令参数的动态运行时替换的技术。`ObjectScripit`在执行相关命令之前执行替换。
间接寻址运算符
间接寻址由间接运算符(`@`)指定。
注意事项
尽管与其他方式相比,间接寻址方式可以更高效更通用的编码,但不是必需的。可以通过`XECUTE`命令达到间接寻址的效果。
只有在明显优势的情况下才应该使用间接寻址。间接寻址会性能产生影响,因为`ObjectScripit`在运行时而不是在编译阶段执行所需的计算。此外,如果使用复杂的间接寻址,应确保清楚的代码逻辑。间接寻址有时很难理解。
在类中使用标签或例程间接寻址时要指定`Not ProcedureBlock`。
间接寻址符不能与点语法一起使用。这是因为点语法是在编译时解析的,而不是在运行时解析的。
五种类型
执行哪种类型的间接寻址取决于`@variable`出现的上下文。
名称间接寻址
概念
在名称间接寻址中,间接寻址计算结果为变量名、行标签或例程名称。在执行该命令之前将变量的内容替换为预期的名称。
注意事项
当使用间接寻址引用行标签时,间接的值必须是语法上有效的行标签。
名称间接寻址只能访问公共变量。
使用间接地址引用命名变量时,间接地址的值必须是完整的`Glbalo`或局部变量名,包括任何必要的下标。
如果使用间接方式获取或设置对象属性值,会引起错误。不要使用此方式调用,因为会绕过属性访问器方法(`<PropertyName>Get`和`<PropertyName>Set`)。相反,可以使用`$CLASSMETHOD`、`$METHOD`和`$PROPERTY`)函数。
场景
动态替换标签
模式匹配间接寻址
模式匹配间接寻址是间接寻址的一种特殊形式。间接运算符替换模式匹配。间接的值必须是有效的模式。
场景
将间接与模式匹配结合使用是应用程序中使用的模式匹配的便捷方式。在这种情况下,可以将模式存储在单独的变量中,然后在实际模式匹配测试期间间接引用银边。 只需要修改模式匹配变量本身。
参数间接寻址
概念
在参数间接寻址中,间接寻址计算命令参数。参数间接寻址是名称间接寻址的一部分。
场景
先定义变量字符串,后计算表达式
下标间接寻址
下标间接寻址是名字间接寻址的扩展形式。在下标间接寻址中,间接寻址的值必须是局部变量或`Gloabl`数组节点的名称。下标间接在语法上不同于其他形式的间接。下标间接使用以下格式的两个间接运算符:
@array@(subscript)
`$TEXT`参数间接寻址
`$TEXT`参数间接只允许在`$TEXT`函数参数的上下文中使用。间接地址的值必须是有效的`$TEXT`参数。
命令
种类
条件相关命令
if
概念
`IF`将表达式作为参数,并计算该表达式为`true`或`false`。如果为`true`,则执行表达式后面的代码块;如果为`false`,则不执行该代码块。通常用值`1`和`0`表示这些值。
**注:对数值执行条件判断时,如果其计算结果为`0`(零),则将其计算为`false`,如果计算结果为非零值,则计算为`true`。**
语法
IF expression1,... { code }
一个带有若干条件表达式的`if`子句。
任意数量的`ELSEIF`子句,每个子句都有若干条件表达式。
最多只有一个`ELSE`子句。没有条件表达式。
注意事项
传统的`IF`命令是面向行的。要执行的命令必须在同一程序行中。不使用花括号,并且行格式是固定的。新的`IF`命令是块结构的;执行的块由在`IF`命令后的花括号内找到的命令组成。 `IF`的新版本不使用`$TEST`特殊变量。
**注意:该面向行的点语法`ELSE`关键字可以缩写为`E`。(不能缩写为面向块的`ELSE`关键字。)`IF`和`ELSE`的新旧形式在语法上是不同的,不应结合使用;因此,点语法`IF`不应与块语法的`ELSE`配对。**
如果在`IF`代码块中使用`GOTO`,注意避免死循环。
`IF`中使用`QUIT`的集中情况
如果`IF`代码块未嵌套在循环结构中,或未嵌套在`TRY`或`CATCH`块中,则`QUIT`退出当前方法。
如果`IF`代码块嵌套在循环结构(如`FOR`代码块)中,则`QUIT`退出循环结构块,并继续执行循环结构代码块后面的命令。
如果`IF`代码块位于`TRY`块或`CATCH`块内,则`QUIT`将退出`TRY`或`CATCH`块,并继续执行`TRY`或`CATCH`块后面的命令。
else
语法
ELSE { code }
概念
ELSE 不是单独的命令,而是面向块的 IF 命令的子句。您可以将单个 ELSE 子句指定为 IF 命令的最后一个子句,也可以省略 ELSE 子句
esle if
语法
ELSEIF expression,... { code }
概念
ELSEIF 不是单独的命令,而是面向块的 IF 命令的一个子句。
循环相关命令
for
概念
`FOR`是面向块的命令。通常,由一个计数器和一个用大括号括起来的可执行代码块组成。此代码块的执行次数由计数器确定,计数器在每个循环体的顶部进行测试。
语法
FOR var=forparameter { code }
`forparameter`可以是是以下值
expr
start:increment
start:increment:end
FOR var=forparameter1,forparameter2,... { code }
使用 `FOR var=expr`时,执行`for`循环的次数等于`expr`中逗号分隔值的次数。
FOR var=expr
使用 `FOR var=expr`时,执行`for`循环的次数等于`expr`中逗号分隔值的次数。
FOR var=start:increment
使用 `FOR var=start:increment`,在这种形式的`for`命令中,没有结束值;循环必须包含`QUIT`、`RETURN`或`GOTO`命令才能终止循环。
FOR var=start:increment:end
使用 `FOR var=start:increment:end` ,参数`START`、`INCREMENT`和`END`分别指定起始值、增量值和结束值。
循环继续执行,直到`var`值的增量超过`end`结束值或者直到遇到`QUIT`、`RETURN`或`GOTO`。
无参数for
不带参数的`for`无限执行循环代码块,直到由代码块内的命令退出。重复括号内的命令,直到遇到退出循环的`Quit`、`Return`或`GOTO`命令。
注意事项
错误也会中断`for`循环。
点语法(不推荐,废弃结构),传统的`FOR`命令是面向行的。它执行的循环由在同一程序行中跟随它的命令组成。不使用花括号,并且行格式是固定的。
while
概念
如果`expression`的计算结果为`TRUE`,则将执行括号之间的代码块。如果`expression`不为`TRUE`,则不执行括号内的代码块,并执行紧跟大括号的下一个命令。所以只要`expression`的计算结果为`TRUE`,`WHILE`就可以重复执行。
语法
WHILE expression
do while
概念
`DO WHILE`执行代码,然后计算表达式。如果表达式的计算结果为`True`,则`DO WHILE`循环并重新执行代码。如果表达式不为`true`,则不重新执行代码,并执行`Do While`后面的下一个命令。
注意事项
**注意:`Do While`始终以面向块的形式编写。要执行的代码放在`do`和`While`关键字之间,并用大括号括起来。**
区别
`While`、`Do While`和`For`之间的区别在于, `While`必须在执行循环之前测试表达式,但`Do While`必须在执行循环之后测试表达式,而`For`可以在循环内测试表达式。这意味着,如果代码块有两个部分,其中第二个部分的执行取决于表达式的求值,则`for`构造最合适;否则,选择取决于表达式求值应该在代码块之前还是之后。
调用相关命令
do
无参数`do`
无参数`do`命令执行同一程序中紧随其后的代码块。这段代码的每一行都用句点(`.`)表示。然后,执行该代码块之后的下一个命令。可以嵌套无参数`DO`块。后置条件表达式可以附加到无参数`DO`命令关键字,以指定是应该执行还是跳过紧跟在`DO`命令后面的代码块。
带参数的`do`
带参数的`do`命令调用在其他地方定义的一个或多个代码块的执行。`do`命令可以指定多个代码块作为逗号分隔的列表执行。
语法
DO:pc doargument,...
注意事项
在方法或例程内部使用`do`调用子例程或标签,利用了调用例程及其被调用子例程共享相同变量环境。在`do`命令之后,子例程所做的任何变量改变都会自动对原环境代码有效。
`do`命令调用的代码块不能向`do`命令返回值;任何返回值都被忽略。
如果`do`调用附加了后置条件的对象方法,则对象方法参数的最大数量为`253`。
`DO`入口点的最大总参数值为`382`;`DO`方法或使用名称间接寻址方式的`DO`的最大总参数值为`380`。这个总数最多可以包括`254`个实际参数和`128`个条件参数。可以使用`…`语法指定可变数量的参数。
通过从`do`命令的实际参数列表中省略相应的参数,可以不定义任何变量。但是,对于每个省略的实际参数,必须包括一个逗号作为占位符。
如果后置条件表达式附加到参数后,如果后置条件表达式为`TRUE`,则将执行该参数。如果后置条件表达式为`FALSE`,则跳过该参数并继续计算下一个参数或下一个命令。请注意,从左到右处理表达式。
调用类方法,请使用以下结构:
DO ##class(PackageName.ClassName).ClassMethodName()
调用实例方法,需要实例化对象调用`%New()`
DO InstanceName.InstanceMethodName()
`^routine`方式
DO ^CodeToInvoke
`CodeToInvoke`可以是系统例程或用户定义的例程。插入符号`“^”`必须紧跟在例程名称之前
`label+offset`
`label+offset`方式,在类方法里要加`[ Not ProcedureBlock ]`关键字,如果是默认`ProcedureBlock`则该调用方式失效。
`label+offset^routine`
^routine
job
概念
`JOB`在后台运行代码。创建的进程独立于当前进程在后台运行。
语法
JOB:pc jobargument,...
`jobargument`是以下参数之一:
routine(routine-params):(process-params):timeout
routine(routine-params)[joblocation]:(process-params):timeout
##class(className).methodName(args):(process-params):timeout
..methodName(args):(process-params):timeout
$CLASSMETHOD(className,methodName,args):(process-params):timeout
`process-params` 用于设置`JOB`环境中的各种元素的位置参数的冒号分隔列表。前面的冒号和括号是必需的。所有位置参数都是可选的。最多可以为`process-params`指定个六位置参数。这六个参数是:`(nspace:switch:principal-input:principal-output:priority:os-directory)`。
由于参数是位置参数,因此必须按显示的顺序指定它们。如果省略指定参数之前的参数,则必须包括冒号作为其占位符。
`timeout` - 在超时并中止`JOB`之前等待`JOB`进程启动的秒数。前面的冒号是必需的。必须将超时指定为整数值或表达式。如果`JOB`进程超时,则将中止该进程,并将`$test`特殊变量设置为。
注意事项
`JOB`只能按值传递参数,不能按引用传递参数。不能按多维数组传递参数。这与`do`命令不同,在`do`命令中,可以按值和按引用,按多维数组传递参数。
不能将对象引用传递给`JOB`进程。 这是因为对调用上下文中存在的对象的引用不能在新的`JOB`上下文中引用。传递`OREF`会导致将空字符串(`""`)传递到`JOB`进程。
启动`JOB`进程后,会为其分配单独的内存分区,并为其分配唯一的`JOB`编号(也称为进程`ID`或`PID`)。`JOB`进程号存储在`$JOB`特殊变量中。
`$ZPARENT`包含`JOB`处理当前进程的进程的`PID`(进程`ID`),如果当前进程不是通过`JOB`命令创建的,则为`0`。
`$ZCHILD` 包含`JOB`命令创建的最后一个进程的`PID`,无论是否成功。确认`JOB`是否启用成功,必须要判断`$zchild`前后的值与超时。
通过使用`$ZCHILD`,可以通过比较运行`JOB`命令前后的`$ZCHILD`值来确定远程`JOB`的执行状态。如果`BEFORE`和`AFTER`值不同,并且`AFTER`值为非零,则`AFTER` `$ZCHILD`值是新创建的`JOB`的`PID`,表示进程已成功创建。如果`AFTER`值为零,或者`AFTER`值与`BEFORE`值相同,则不会创建`JOB`。
不即使释放`JOB`开启的多进程会造成`license`爆满的情况。
`$ZCHILD`只能告诉`JOB`已创建;它不会告诉`JOB`是否成功运行。确定进程是否运行无错误并运行到完成的最佳方法是在正在运行的代码中提供某种类型的日志记录和错误捕获。`JOB`机制不会以任何方式通知父进程进程错误或进程终止,无论成功与否。
启动失败原因
a. 没有空闲分区。
b. 内存不足,无法使用`process-params`指定的特征创建分区。
c. 超过许可的进程数量。
通信
`JOB`之间的通信,按值传递的参数只能在一个方向上进行,并且只能在`JOB`启动时进行。为了使进程相互通信,必须使用双方同意的`Global`。这类变量通常称为临时`Global`,使用临时`Global`目的是允许进程之间交换信息。
进程可以使用`%SYSTEM.Event`类方法在`JOB`之间通信。
设置临时`Global`。
场景
多进程使用
消息队列
goto
概念
转移控制权
语法
GOTO:pc
GOTO:pc goargument,...
GOTO:pc goargument,...
location:pc
可以省略`if`命令,并在参数上使用后置条件用逗号分隔的列表编写`goto`代码。
两种形式
无参数
不带参数的`goto`在在当前执行的代码中遇到错误或`Break`命令后恢复继续运行的程序。
只能在终端提示符下使用无参数`GOTO`。
有参数
带有参数`location`的`goto`将代码控制权转移到指定位置。
`Goto`显示`Offset`如何计算代码行。`line`只计算插入的标签行和注释行,不计算空行。
注意事项
如果在`For`、`If`、`Do While`或`While`循环中使用`GOTO`,则可以转到所有代码块外部的位置或当前代码块内的位置,或者从嵌套的代码块转到包围它的代码块中的位置。不能从一个代码块转到另一个代码块中的位置,无论是独立的代码块还是嵌套在当前代码块中的代码块。
转到代码块外部的位置将终止循环。转到代码块中的某个位置不会终止循环。从嵌套代码块到封闭代码块的`GOTO`会终止内部(嵌套)循环,但不会终止外部循环。
与do命令区别
与`do`命令不同,`goto`无条件地转移控制权。`do`在调用的方法中遇到`QUIT`时,会将控制传递给最近的`DO`之后的命令。
当在`GOTO`转移后遇到退出时,不会将控制权交还给`GOTO`之后的命令。如果前面有一个`DO`,则它将控制权返回给最近一个`DO`之后的命令。如果前面没有`DO`,则直接结束。
xecute
概念
`XECUTE`命令执行指定的命令。
`XECUTE`执行`ObjectScript`命令行,每个命令行由一个`xecutearg`指定。这些`xecutearg`按从左到右的顺序执行,每个执行都由可选的后置条件表达式控制。
语法
XECUTE:pc xecutearg,...
X:pc xecutearg,...
X:pc xecutearg,...
("(fparams) cmdline",params):pc
如果要传递参数,则`fparams`形参列表必须在`cmdline`命令之前。
形式参数列表,用逗号分隔并用括号括起来。形参名称必须是有效的标识符。因为这些形参是在另一个上下文中执行,所以它们只能在它们的`xecutearg`中是唯一的;对发出`XECUTE`的程序或另一个`xecutearg`中同名的局部变量没有影响。但是,`fparams`的数量必须等于或超过指定的`params`数量,否则会生成`<PARAMETER>`错误。
要从调用程序传递到`fparams`的实际参数,以逗号分隔的列表形式指定。参数必须是调用程序中定义的变量。
可以使用通过引用变量传递参数。这个用法从`cmdline`传出值非常有用。
"cmdline":pc
每个`cmdline`的计算结果必须为包含若干`ObjectScript`命令的字符串。
`"cmdline":pc` 多参数后置表达式方式。根据后置表达式的布尔值,执行为`True`的`Xecute`命令。
注意事项
在使用`Xecute`命令之前,可以使用`%Library.Routine`类的`CheckSynTax()`方法对`xecutearg`命令行字符串执行语法检查。
因为`cmdline`是一个字符串,所以不能跨多个代码行断开。可以将单个`cmdline`参数分成多个字符串使用连接运算符连接在一起。
可以将单个`cmdline`参数分为多个单独的逗号分隔的`cmdline`参数。
`cmdline`的最大长度不能超过最大字符串长度。
可以在`cmdline`内、连接的`cmdline`字符串之间或逗号分隔的`cmdline`参数之间嵌入`/*text*/`注释。
`cmdline`可以计算为空字符串(`""`)。在这种情况下,不执行任何操作,并继续执行下一个`xecutearg`或下一条命令。
`Xecute`命令调用标签与方法。类方法中如果调用标签则类方法要加上关键字`[ Not ProcedureBlock ]`,否则`<NOLINE>`错误。
如果在`[ Not ProcedureBlock ]`的关键字类里,直接用`Xecute`赋值变量,则变量默认为全局变量。不需要引用传递出来。
如果`XECUTE`命令包含`DO`命令,则执行`DO`参数中指定的方法。当方法结束时时,会将控制返回到紧跟在`do`参数之后的命令。
`Xecute`命令,使用`for`循环。如果`XECUTE`参数包含`FOR`命令,则`FOR`的作用域是该参数的其余部分。当`XECUTE`参数中最外层的`for`终止时,`XECUTE`参数也将终止。
`XECUTE`支持在`XECUTE`参数中使用`XECUTE`命令。但是,应该谨慎使用`XECUTE`的嵌套调用。
在`XECUTE`内调用的代码的执行时间可能比在程序主体中遇到的相同代码的执行时间慢。这是因为每次处理`XECUTE`时,都会编译用`XECUTE`命令指定的源代码或包含在引用的全局变量中的源代码。
`XECUTE`命令不能用于定义标签。如果定义标签或例程。请使用`%Routine`类。
退出相关命令
continue
概念
`Continue`命令在`For`、`While`或`Do While`命令之后的代码块内使用。`Continue`作用是跳过循环体中剩余的语句并到循环末尾而强行执行下一次循环。
语法
CONTINUE:pc
注意事项
Continue命令只在块级语法有效。
`Continue`不接受任何参数。
quit
概念
`QUIT` 命令终止当前上下文的执行,退出到封闭的上下文。在方法中调用时,`Quit`将返回调用方法,如果没有调用方法,则终止该程序。当从`FOR`、`DO WHILE`或`WHILE`控制流结构、`TRY`或`CATCH`块或传统`DO`结构(点语法)内调用时,`QUIT`会退出该结构并继续执行该结构之外的下一个命令。
语法
QUIT:pc expression
Q n
在`Terminal`下,`QUIT n`从程序堆栈中清除指定数量的级别。可以使用`$STACK`特殊变量来确定程序堆栈上的当前级别数。
在`Terminal`下,不带参数的`QUIT`从程序堆栈中清除所有级别。
注意事项
`quit`在传统`DO`结构内调用时,`for`循环点语法与块语法`quit`相当于`continue`命令。
`QUIT`可用于退出旧语法的`DO`结构(无参数`DO`,后跟代码行,每行代码前加一个句点)。使用无参数`DO`结构代码块后面的命令继续执行。这种无参数的`DO`语法被认为已过时,不应用于新的编码。
带参数的`QUIT`不能用于从`FOR`,`DO WHILE`或`WHILE`命令循环中退出。带参数的`QUIT`也不能用于从`TRY`块或`CATCH`块中退出。
如果`IF`代码块未嵌套在循环结构内,则`QUIT`终止当前程序。
当遇到带有参数的标签时,将执行隐式`QUIT`。
在每个例程标签的末尾执行一个隐式`QUIT`,也可以显式指定`Quit`以提高程序的可读性。
retrun
概念
`Retrun`命令用于终止方法的执行。在大多数情况下,与`QUIT`命令用法相同。在`FOR`、`DO WHILE`、`WHILE`循环命令与`TRY`-`CATCH`块中使用时,`RETURN`和`QUIT`有所不同。
语法
RETURN:pc expression
retrun n
在`Terminal`下,`retrun n`从程序堆栈中清除指定数量的级别。可以使用`$STACK`特殊变量来确定程序堆栈上的当前级别数。
在`Terminal`下,不带参数的`retrun`从程序堆栈中清除所有级别。
注意事项
`Retrun`在版本`2010`没有此命令,之后的版本才有。
`Retrun`命令在传统的`For`循环点语法中与`Quit`功能一样。
区别
在`for`循环中
`continue`退出本次循环。
`quit`退出循环。
`retrun`退出结束当前运行方法。
对比`for`循环传统点语法与块语法使用`ret`与`quit`的优势。
块语法`ret`可直接退出返回值。
点语法则需要用循环外变量去接收,在去判断返回值。
`QUIT`和`RETURN`命令都终止代码块或方法的执行。在没有参数的情况下,它们只需退出从中调用它们的代码。有参数情况下,它们将参数用作返回值。退出当前上下文,退出到封闭上下文。`Return`将当前程序退出到程序被调用的位置。
赋值相关命令
set
概念
`set`命令为变量赋值。可以为单个变量赋值,也可以同时为多个变量赋值。
如果指定的变量不存在,则`SET`会创建该变量并赋值。如果存在指定的变量,则`SET`将用指定的值替换先前的值。由于`SET`按从左到右的顺序执行,因此可以为一个变量赋值,然后将该变量赋值给另一个变量。
语法
SET variable = expression
SET variable1 = expression1, variable2 = expression2, variable3 = expression3
可以执行的赋值次数没有限制
SET (variable1, variable2, variable3) = expression
可执行的最大赋值数量是`128`。超过此数字会引起`<SYNTAX>`错误。
效率
kill
概念
`kill`命令从内存中删除变量,也可用于从磁盘中删除`Global`。
语法
KILL expression
KILL x
KILL x,y,z
KILL (x)
注意事项
删除多维数组,进程`Global`,`Global`节点时,会自动删除该节点的所有从属节点,以及该节点。
`Kill`参数用括号包括的形式会删除除指定变量之外的所有局部变量。但是不能指定进程私有全局变量、全局变量或特殊变量,多维数组。
不带参数的`kill`命令将删除所有局部变量。但不会删除进程私有`Gloabl`、`Gloabl`或系统特殊变量。
使用参数传递对KILL影响
按值传递变量 - 在被调用的方法的上下文之外`kill`变量是无效的,`kill`变量仅在当前方法的上下文中有效果,当退出方法时自动恢复保存的值。
引用传递变量 - 执行`kill`变量,也会`kill`相应的实际变量。返回到调用方法时,实际变量将不会恢复。
**注:当遇到使用参数传递(无论是通过值传递还是通过引用传递)的方法时,会隐式地为形参列表中的每个变量执行一个`new`命令。当退出方法时,会隐式地为形参列表中的每个变量执行`kill`命令。在按引用传递变量的情况下,在执行`kill`之前更新相应的实际变量。**
zkill
概念
`ZKILL`命令删除指定数组节点的值,而不会杀死该节点的后代。
与`kill`相反
new
概念
`NEW`命令创建一个新的局部变量上下文。`NEW`命令在旧上下文中保留现有的局部变量值,然后启动一个新的上下文,在新上下文中没有为局部变量赋值,变量为未定义状态。
场景
`NEW`最常在`do`命令调用的方法中使用。一般在方法开头使用初始化变量。
语法
NEW
为所有局部变量启动新上下文
NEW x
为指定的局部变量启动新上下文
NEW x, y, z
为列出的局部变量启动新上下文
NEW (y)
为除指定变量之外的所有局部变量启动新上下文
NEW (y, z)
为除列出的变量之外的所有局部变量启动新上下文
`NEW`命令不能用于的内容
Globals - 全局变量
Process-Private Globals - 进程私有全局变量
Local variable subscripts - 多维数组
系统特殊变量
`$ESTACK`、`$ETRAP`、`$NAMESPACE`和`$ROLES`除外。
注意事项
在类方法中,默认都是私有变量不能`NEW`。如果要使用`NEW`命令需要在类添加关键字`Not ProcedureBlock`。
`NEW`括号包裹的参数形式,最多可以指定`255`个变量作为逗号分隔的列表。 超过此数字发出`<SYNTAX>`错误。
当方法中,使用`new`命令如果超过`31`次也就是`31`级别,会引起`<MAXSCOPE>`错误。
merge
概念
将`Global`或多维数组节点并到目标变量。
`MERGE`命令将数据源复制到目标变量,并将数据源的所有后代复制到目标的后代。`MERGE`命令不修改数据源。
`MERGE` 简化了将变量的子树复制到另一个变量的过程。这两个变量都可以是带下标的局部变量、进程私有`Global`或`Global`。子树是指定变量的后代的所有变量。
场景
`Merge`为当前的节点复制技术提供了命令替代方案:带有`$ORDER`引用的`SET`命令。
输出相关命令
write
概念
显示输出到当前设备。
语法
WRITE:pc writeargument,...
`writeargument`可以是以下表达式
expression
`expression` 可选 - 写入输出设备的值。任何有效的`ObjectScript`表达式,包括文字,变量,对象方法和对象属性,其结果均为数字或带引号的字符串。
f
`f` 可选 - 一个或多个格式控制字符,用于将输出放置在目标设备上。格式控制字符包括`!`,`#`、`?n`和`/助记符`。参数用逗号分隔。
格式控制字符
`!` - 将一行移至第`0`列(`$Y`递增`1`,`$X`设置为`0`),相当与换行。
`#` - 将清除当前屏幕,并从新屏幕的顶部`0`列开始。(`$Y`和`$X`重置为0。)
`?n` - 后跟一个整数或者计算结果为整数的表达式。它将输出定位在第`n`列位置(从第`0`列开始计数)
可以指定格式控制字符的任意组合,而无需插入逗号,但是必须使用逗号将格式控制与表达式分开。
*integer
`*integer` 可选 - 星号整数代码,表示要写入输出设备的字符。对于`ASCII`,范围是`0`到`255`之间的整数;对于`Unicode`,范围是`0`到`65534`之间的整数。任何有效的`ObjectScript`表达式,其计算结果为适当范围内的整数。
*-integer
`*-integer` 可选 - 指定设备控制操作的星号负整数代码。
无参数WRITE
无参数`Write`列出所有定义的局部变量的名称和值。不列出进程私有`Global`、`Global`或特殊变量。
按以下格式列出定义的局部变量,每行一个变量。
varname1=value1
varname2=value2
varname2=value2
无参数`Write`将所有类型的局部变量值显示为带引号的字符串。规范数字和对象引用除外,显示标准数字时不带引号。
位字符串值和列表值显示为带引号的字符串,数据值以编码形式显示。
无参数`WRITE`区分大小写的字符串排序顺序显示局部变量。
无参数`WRITE`使用数字排序规则以下标树顺序显示局部变量的下标。
无参数`WRITE`执行控制字符。显示定义控制字符的局部变量。
zwrite
概念
`ZWRITE` 命令列出变量的名称及其值。在当前设备上以规范顺序以 `varname=value` 格式列出这些变量及其后代,每行一个变量。
语法
ZWRITE:pc expression,...
`expression` 可选 - 要显示的变量或表达式,或要显示的逗号分隔的变量或表达式列表。
这些参数按从左到右的顺序求值。每个参数可以指定一个变量或一个表达式。如果`expression`是用逗号分隔的列表,则每个变量或表达式将显示在单独的行上。
注意事项
不带表达式参数的`ZWRITE`在功能上与不带参数的WRITE相同。
在`Terminal`中不带参数的`ZWRITE`以`ASCII`名称顺序列出所有已定义的局部变量。
`ZWRITE`将数字字符串显示为规范数字。 `ZWRITE`显示一个数字字符串,其中包含规范形式的数字作为不带引号的规范数字。`ZWRITE`将非规范形式的数字字符串显示为带引号的字符串。
`ZWRITE`忽略未定义的变量。不会发出错误。如果在以逗号分隔的变量列表中指定一个或多个未定义变量,则`ZWRITE`会忽略未定义变量并返回已定义变量。如果为`WRITE`,`ZZDUMP`或`ZZWRITE`指定了未定义的变量,则会发出`<UNDEFINED>`错误。
如果变量具有已定义的子节点,则`ZWRITE`会按照下标顺序为每个子节点写一条单独的`varname = value`行。当指定根节点时,即使未定义根节点,`ZWRITE`也会显示其所有子节点。
`ZWRITE`显示所有字符。包含使用`$CHAR`函数显示不可打印字符,将每个不可打印字符表示为串联的`$c(n)`值。但不执行非打印控制字符。
如果表达式是多维属性,则`ZWRITE`将不显示该属性的后代。要使用`ZWRITE`显示整个多维属性,请将其`merge`到局部变量中并显示该数组或者`ZWRITE`对象。
可以为`ZWRITE`指定列表结构(`%List`)作为变量或表达式。 `ZWRITE`将列表结构显示为`$lb(element1,element2)`。
`ZWRITE`显示`Global`及其所有后代节点的内容。
`ZWRITE`显示`JSON`动态数组和`JSON`动态对象作为对象引用。引用的对象类为`%Library.DynamicArray`和`%Library.DynamicObject`。
可以将`ZWRITE`的位串指定为变量或表达式。如果`ZWRITE`参数是位串(使用`$BIT`函数创建),则`ZWRITE`将二进制串的十进制表示形式显示为`$ZWCHAR($zwc)`两字节字符。
`ZWRITE`对对象`OREF`的使用与解读
`ZWRITE`显示对象`oref`。如果指定了对象引用,则显示`ZWRITE variable=<OBJECT REFERENCE>[oref]`或 `<OBJECT REFERENCE>[oref]` 还显示对象属性的“常规信息`general information`”,“属性值`attribute values`”和“混合引用`swizzled references`”和“计算引用`calculated references`”,每行一个属性。
`general information` - 通用信息,包含引用次数,类型。
`attribute values` - 可以直接用点语法使用属性。
`swizzled references` - 为其他引用对象,如果不为空可以用点语法使用该对象。如果该对象里面有其他属性,可以使用连续点语法使用属性。
`calculated references` 表示该字段为由其他字段或方法计算而来。
zzdump
概念
`ZZDUMP`以十六进制转储格式显示表达式。在查看包含控制字符的字符串时很有用。
语法
ZZDUMP:pc expression,...
注意事项
`ZZDUMP` 显示单个变量长度超过`16`换行,第二个转储行(`0010:`)的位置为十六进制,第三个转储行(`0020:`),以此类推。
`ZZDUMP`返回字符串变量的十六进制转储。请注意,每个逗号分隔的表达式都被视为`ZZDUMP`的单独调用。对于空字符串变量,不会返回十六进制转储。
`ZZDUMP`表达式中的有一个字符是宽字符(`Unicode`),则该表达式中的所有字符都表示为宽字符。
zzwrite
概念
`ZZWRITE `命令计算一个表达式并在当前设备上显示一个值。该表达式可以是文字、局部变量、进程私有`Global`、`Global`或特殊变量。
语法
ZZWRITE:pc expression,...
注意事项
没有参数的`ZZWRITE`是空操作。它不执行任何操作,也不发出错误`。ZZWRITE`可以计算以逗号分隔的表达式列表。它以指定的顺序显示结果,每行一个表达式。 `ZZWRITE`将每个表达式的结果显示为`%val = value`。
`ZZWRITE`也可以显示对象`oref`具体信息与`##class(%SYSTEM.OBJ).Dump()`显示相同。
`ZZWRITE`使用参数显示与`ZWRITE`相同的数据值,但有以下差异:
未定义的变量:`ZZWRITE`对未定义的变量发出`<UNDEFINED>`错误。 `ZWRITE`忽略未定义的变量。
下标:`ZZWRITE`显示指定下标节点的值。 `ZWRITE`以下标树的顺序显示下标节点和所有定义的子节点。
变量名称:`ZZWRITE`将每个表达式或变量的值显示为`%val = value`。 `ZWRITE`将局部变量,进程私有`Global`和`Global`显示为`varname = value`,并将文字值,表达式和特殊变量显示为`value`。
区别
无参数
无参数 `WRITE`显示每个定义的局部变量的名称和值,每行一个变量。列出公有变量和私有变量。不列出`Global`、进程私有`Global`或特殊变量。按排序顺序列出变量。以下标树顺序列出下标变量。
无参数 `ZWRITE`在功能上与无参数`WRITE`相同。
无参数 `ZZDUMP`是生成`<SYNTAX>`错误的无效命令。
无参数 `ZZWRITE`是返回空字符串的无操作。
有参数
见,输出命令百讲表格
异常相关命令
catch
throw
try
ztrap
事务相关命令
tcommit
trollback
tstart
调试相关命令
break
zbreak
IO命相关令
close
open
read
use
挂起相关
hang
halt
例程相关命令
print
zprint
zinsert
zload
zremove
zsave
zzprint
其他命令
lock
view
znspace
概念
命令是`ObjectScript`编程中的基本代码单元。
`ObjectScript`中的所有执行任务都由命令执行。
每个命令都包含一个命令关键字,后跟若干个命令参数,可能有一个参数,也可能有多个参数。
命令始终以关键字开头。
后置表达式
后置条件是控制命令是否执行该命令或命令参数的可选表达式。如果后置条件表达式的计算结果为`TRUE`,则执行命令或命令参数。后置条件表达式的计算结果为`FALSE`,则不执行命令或命令参数,并从下一个命令或命令参数继续执行。
除了控制流命令(`IF`、`ELSEIF`和`ELSE`;`FOR`、`WHILE`和`DO WHILE`)和块结构错误处理命令(`TRY`、`THROW`、`CATCH`)之外,所有ObjectScript命令都可以采用后置条件表达式。
如果命令关键字和该命令一个或多个参数都指定了后置条件,则首先计算关键字的后置表达式。
向命令添加后置条件,在命令关键字后面紧跟一个冒号(`:`)和表达式,后置条件表达式的命令的语法为:
Command:pc
注意事项
命令名称不区分大小写。大多数命令名称都可以用缩写形式表示。例如:`“WRITE”`, `“Write”`, `“write”,` `“W”`, `“w”` 都是`WRITE`命令的有效形式。
命令关键字不是保留字。因此,可以使用命令关键字作为变量、方法、标签或其他标识符指定的名称。
代码行上的第一个命令必须缩进;命令关键字不能出现在第`1`列中。在`Terminal`命令行提示符或从`XECUTE`命令发出命令时,不需要缩进。
可执行代码行可以包含若干个命令,每个命令都有自己的命令关键字。一行中的多个命令由若干个空格分隔。在同一行上,命令可以跟在标签之后;标签和命令之间可以有若干空格分隔。
如果命令采用后置条件表达式,则命令关键字和后置条件之间不能有空格,并且后置条件和第一个参数的开头之间必须有一个空格。
大多数命令允许指定多个参数。命令的多个参数指定为该命令后面的逗号分隔列表。
多个参数命令参数严格按照从左到右的顺序执行。
不带参数的命令称为无参数命令。**后置条件表达式不被视为参数。**
例如:`HALT`、`CONTINUE`、`TSTART`和`TCOMMIT`是无参数命令。
如果与其他命令在相同的代码行上使用无参数命令,则必须在无参数命令与其后面的命令之间保持两个以上空格。
嵌入式
嵌入式HTML
嵌入式`HTML`允许在`ObjectScript`程序中包含`HTML`代码。
了解
示例
&html< <b>加粗</b> >
嵌入式JavaScript
嵌入式`JavaScript`允许在`ObjectScript`程序中包含`JavaScript`代码。
了解
示例
&javascript< var s= s+2 >
嵌入式`SQL`
嵌入式`SQL`允许在`ObjectScript`程序中包含`SQL`代码。语法为`&sql()`
掌握
示例
&sql( SELECT Name INTO :n FROM Sample.Person )
0 条评论
下一页