清除过滤器
公告
Claire Zheng · 十一月 22, 2021
亲爱的社区开发者们,大家好!
现在参与Gartner Peer Insight同业评审对我们的产品做出评价,可获得价值 $25 美元的礼品卡。评论观点需中立客观(InterSystems员工不允许参加)并被Gartner审核通过。点击此处开始: https://gtnr.it/3ulVX4K 。
对流程不熟悉的同学,可以参考一下我们此前发布的一篇旧贴。
调研仅花费您很少时间,欢迎大家积极参与! 活动已经截止了。。。
公告
Claire Zheng · 三月 11, 2021
亲爱的社区开发者们,
我很高兴地向大家介绍一位我们的新版主@姚鑫
@姚鑫是东华医为的一名开发工程师。
以下是@姚鑫的自我介绍:
大家好,我非常热衷于与开发者们分享我的技术经验。作为一名移动端全栈开发工程师,我发表了《Caché 23种设计模式》《Caché 算法与数据结构》《Caché 从入门到精通》《疯狂 Caché》《Caché 命令大全》《Caché 函数大全》《Caché 变量大全》《Caché SQL 必知必会》等一系列文章集。
在CSDN(中国最大的开发者社区之一),我被认证为博客专家,CSDN优秀讲师。
在掘金网这个帮助开发者成长的知名社区,获得了2020年掘金十大年度人气作者称号。
我很荣幸能够加入InterSystems开发者社区(中文版)并参与到社区管理、运营中,希望可以同使用InterSystems技术的开发者更好地交流、共同成长。
感谢@姚鑫,恭喜你成为新版主! 感谢@姚鑫!期待更多大作! 欢迎新版主@姚鑫 欢迎新版主@姚鑫期待将来分享更多关于IRIS数据平台的经验
文章
Lele Yang · 六月 8, 2021
如果您在升级了系统之后,打开SMP时看到如下报错,ERROR #5001: 对象的服务器版本与客户端发送的版本不一致: %ZEN.Component.vgroup
一般情况下,这个报错是由浏览器缓存中残留的过期信息造成的,可以通过清除浏览器缓存来解决。
如果清除浏览器缓存之后仍然未能解决此问题,请您前往系统安装目录, 如:d:\InterSystems\IRIS\CSP\broker,查看css/js文件的时间戳在本次更新安装之后是否并没有相应地更新,如果没有,请您做以下尝试,1)在IRIS中更改数据库IRISLIB, 之前的版本是CACHELIB, 取消只读装载,方法如下,打开管理门户SMP, 系统管理->配置->本地数据库,选择要更改的数据库,取消"只读方式挂载",点击【保存】。2)重新编译%Zen组件,w ##class(%SYSTEM.OBJ).Compile("%ZEN.Component.vgroup")此时,再次前往,d:\InterSystems\IRIS\CSP\broker,会看到相关的css/js文件时间戳已经更新。3)恢复上述数据库的只读装载。
如果以上办法仍然未能解决您的问题,建议您联系WRC,寻求Support的进一步帮助。
文章
Michael Lei · 八月 10, 2023
InterSystems 常见问题解答
※如果您想比较使用Mirror、Shadow或其他机制复制的数据库,请使用此方法。
您可以使用 DATACHECK 实用程序来比较Global。请参阅下面的文档。DataCheck 概述 [IRIS]
***
Routines比较使用系统例程 %RCMP 或管理门户。
以下是如何在管理门户中使用它。
例如,假设以下Routine位于 USER 命名空间中。
test() public{ quit "hello" }
假设以下Routine位于 USER2 命名空间中。
test() public{ quit "Hello" }
下面是在连接到 USER 命名空间的终端中运行 %RCOM 的结果。
* 在Compare : 中写入Routine名称以及要与: 进行比较的Routine名称要指定另一个命名空间中的Routine,请指定|“命名空间名称”|例程名称.MAC。
用户>执行 ^%RCMP比较:comptest.mac 与:|"USER2"|comptest.macCompare: // [备注] 如果没有可比较的内容,请按 Enter忽略评论差异?否 => 否忽略前导空格?否 => 否显示结果于Device: c:\temp\comp.txt // [备注] 指定文件名时的文件输出 参数? (“WNS”)=>comptest.MAC |“USER2”|comptest.MAC****************************************************** ******************************用户>
对比结果如下。
常规比较 2021 年 2 月 2 日 2:31 PM来自目录:c:\intersystems\iris\mgr\user\
comptest.MAC |“USER2”|comptest.MAC****************************************************** ******************************竞争测试.MAC+2 退出“你好”......................|“USER2”|comptest.MAC+2 退出“你好”****************************************************** **************************
文章
姚 鑫 · 七月 10, 2022
# 第一章 嵌入式Python概述(一)
嵌入式 `Python` 允许将 `Python` 与 IRIS 数据平台的本地编程语言 `ObjectScript` 一起使用。当使用嵌入式 `Python` 在 `IRIS` 类中编写方法时,`Python` 源代码与编译后的 `ObjectScript` 代码一起编译为在服务器上运行的目标代码。与使用网关或 `Python`的 `Native SDK` 相比,这允许更紧密的集成。还可以导入 `Python` 包,无论它们是自定义的还是公开的,并在`ObjectScript` 代码中使用它们。 `Python` 对象是 `ObjectScript` 中的一等公民,反之亦然。
- 使用来自 `ObjectScript` 的 `Python` 库 - 此方案假设 `ObjectScript` 开发人员,并且希望利用 `Python` 开发人员社区可用的众多 `Python` 库的强大功能。
- 从 `Python` 调用 `IRIS API` — 此方案假定您是一名 `Python` 开发人员,对 IRIS 不熟悉,并且想知道如何访问 `API`。
- 一起使用 `ObjectScript` 和 `Python` — 这个场景假设在一个由 `ObjectScript` 和 `Python` 开发人员组成的混合团队中,并且想知道如何一起使用这两种语言。
将需要 `2021.2` 或更高版本的正在运行的 `IRIS` 实例,以及取决于操作系统的一些先决条件。还需要知道如何访问终端,即 `IRIS` 命令行工具。
本文档中的一些示例使用来自 `GitHub` 上 `Samples-Data` 存储库的类:`https://github.com/intersystems/Samples-Data`。 建议创建一个名为 `SAMPLES` 的专用命名空间并将样本加载到该命名空间中。如果想查看或修改示例代码,则需要设置集成开发环境 (`IDE`)。推荐使用 `Visual Studio Code`。
本篇并不试图提供嵌入式 `Python` 或使用 `IRIS` 进行编程的全面概述。
# 使用 ObjectScript 中的 Python 库
使用 `Embedded Python`,`ObjectScript` 开发人员可以轻松地使用来自 `IRIS` 的众多可用 `Python` 库(通常称为“包”)中的任何一种,从而无需开发自定义库来复制现有功能。 `IRIS` 在 `/mgr/python` 目录中查找已安装的 `Python` 包
从 `ObjectScript` 准备 `Python` 包以供使用是一个两步过程:
1. 从命令行,从 `Python` 包索引(或其他索引)安装所需的包。
2. 在 `ObjectScript` 中,导入已安装的包以加载包并将其作为对象返回。然后,可以像使用实例化的 `ObjectScript` 类一样使用该对象。
## 安装 Python 包
在将 `Python` 包与 `Embedded Python` 一起使用之前,请从命令行安装。使用的命令会有所不同,具体取决于使用的是 `Windows` 还是基于 `UNIX` 的系统。 建议将软件包安装到目录 `/mgr/python`。
在 `Windows` 上,使用 `/bin` 目录中的 `irispip` 命令:`irispip install --target \mgr\python `.
例如,可以在 `Windows` 机器上安装 `numpy` 包,如下所示:
```java
C:\InterSystems\IRIS\bin>irispip install --target C:\InterSystems\IRIS\mgr\python numpy
```
在基于 `UNIX` 的系统上,使用 `pip3` 命令:`pip3 install --target /mgr/python `。
例如,可以在 Linux 机器上安装 `numpy` 包,如下所示:
```java
$ pip3 install --target /InterSystems/IRIS/mgr/python numpy
```
注意:如果基于 `UNIX` 的系统没有安装 `pip3`,请使用系统的包管理器安装包 `python3-pip`。
## 导入 Python 包
`%SYS.Python` 类包含从 `ObjectScript` 使用 `Python` 所需的功能。可以在任何 `ObjectScript` 上下文中使用 `%SYS.Python`,例如类、终端会话或 `SQL`。
要从 ObjectScript 导入 `Python` 包或模块,请使用 `%SYS.Python.Import()` 方法。
例如,假设在 `USER` 命名空间中,以下命令会在终端中导入数学模块:
```java
USER>set pymath = ##class(%SYS.Python).Import("math")
```
数学模块与标准 `Python` 版本打包在一起,因此无需在导入之前安装它。通过在 `pymath` 对象上调用 `zwrite`,可以看到它是内置数学模块的一个实例:
```java
USER>zwrite pymath
pymath=1@%SYS.Python ; ;
```
注意:包是 `Python` 模块的集合,但是当导入包时,创建的对象始终是模块类型。
现在,可以像访问任何 `ObjectScript` 对象一样访问数学模块属性和方法:
```java
USER>write pymath.pi
3.141592653589793116
USER>write pymath.factorial(10)
3628800
```
# 示例
此示例使用 `geopy` 包来访问 `OpenStreetMap` 的 `Nominatim` 地理编码工具。地理编码是获取基于文本的位置描述(例如地址或地名)并返回地理坐标(例如纬度和经度)以精确定位地球表面位置的过程。
首先,从命令行安装 `geopy`,如下 `Windows` 示例所示:
```java
C:\InterSystems\IRIS\bin>irispip install --target C:\InterSystems\IRIS\mgr\python geopy
Collecting geopy
Using cached geopy-2.2.0-py3-none-any.whl (118 kB)
Collecting geographiclib=1.49
Using cached geographiclib-1.52-py3-none-any.whl (38 kB)
Installing collected packages: geographiclib, geopy
Successfully installed geographiclib-1.52 geopy-2.2.0
```
在基于 UNIX 的系统上,使用:
```java
$ pip3 install --target /InterSystems/IRIS/mgr/python geopy
```
然后在终端中运行以下命令来导入和使用模块:
```java
USER>set geopy = ##class(%SYS.Python).Import("geopy")
USER>set args = { "user_agent": "Embedded Python" }
USER>set geolocator = geopy.Nominatim(args...)
USER>set flatiron = geolocator.geocode("175 5th Avenue NYC")
USER>write flatiron.address
Flatiron Building, 175, 5th Avenue, Flatiron District, Manhattan, New York County, New York, 10010, United States
USER>write flatiron.latitude _ "," _ flatiron.longitude
40.74105919999999514,-73.98964162240997666
USER>set cityhall = geolocator.reverse("42.3604099,-71.060181")
USER>write cityhall.address
Government Center, Cambridge Street, Downtown Crossing, West End, Boston, Suffolk County, Massachusetts, 02203, United States
```
此示例将 `geopy` 模块导入 `ObjectScript`。然后它使用 `Nominatim` 模块创建一个地理定位器对象。该示例使用地理定位器的 `geocode()` 方法在给定字符串的情况下查找地球上的位置。然后它调用 `reverse()` 方法来查找给定纬度和经度的地址。
需要注意的一点是 `Nominatim()` 采用命名关键字参数,ObjectScript 不直接支持这种结构。解决方案是创建一个包含参数列表的 `JSON` 对象(在这种情况下将 `user_agent` 关键字设置为值“嵌入式 Python”),然后使用 `args...` 语法将其传递给方法。
与前面示例中导入的数学模块相比,对 `geopy` 对象调用 `zwrite` 表明它是安装在 `C:\InterSystems\iris\mgr\python` 中的 `geopy` 包的一个实例:
```java
USER>zwrite geopy
geopy=2@%SYS.Python ; ;
```
文章
姚 鑫 · 二月 2, 2022
# 第四十二章 SQL函数 DATEADD
一个日期/时间函数,它返回一个时间戳,计算方法是在一个日期或时间戳中添加或减去若干日期部件单位(如小时或天)。
# 大纲
```java
DATEADD(datepart,integer-exp,date-exp)
```
# 参数
- `datepart` - 日期或时间部分的名称(或缩写)。
可以用大写或小写指定该名称,也可以不加引号。
可以将`datepart`指定为文字或主机变量。
- `integer-exp` - 任意数字类型的数字表达式。
该值被截断为整数(正或负)。
该值指示将添加到(或从)`date-exp`中减去的`datepart`单元的数量。
- `date-exp` - 要修改的日期/时间表达式。它可以是日期字符串,也可以是时间戳字符串(`%PosiTime`或`%Timestamp`数据类型),也可以是`CURRENT_DATE`之类的函数。返回的值始终是时间戳,数据类型格式为`%PosiTime`或`%Timestamp`。
# 描述
`DATEADD`函数通过将指定的日期部分递增指定的单元数来修改日期/时间表达式。
例如,如果`datepart`为`“month”`且整数`-exp`为`5`,则`DATEADD`将`date-exp`递增`5`个月。
还可以通过为`integer-exp`指定一个负整数来减少日期部分。
计算出的日期将作为完整的日期/时间表达式(时间戳)返回。返回的数据类型取决于`Date-EXP`的数据类型。如果`Date-EXP`为`%Library.PosiTime`(编码的`64`位有符号整数),则`DATEADD`返回数据类型`%Library.PosiTime`。否则,`DATEADD`返回数据类型`%Library.TimeStamp(yyyy-mm-dd hh:mm:ss.fff)`。
`DATEADD`始终返回有效日期,并考虑一个月的天数,并计算闰年。例如,将1月31日递增一个月将返回2月28日(该月中的最高有效日期),除非指定的年份是闰年,在这种情况下将返回2月29日。将闰年日期2月29日递增一年将返回2月28日。将闰年日期2月29日递增四年返回2月29日。
如果指定包含小数秒的`date-exp`,则返回值也包括小数秒。如果省略`date-exp`的时间部分,`DATEADD`将返回默认时间`00:00:00`。如果省略`date-exp`的日期部分,`DATEADD`将返回默认日期`1900-01-01`。
`DATEADD`和`TIMESTAMPADD`处理季度(`3`个月间隔);`DATEDIFF`和`TIMESTAMPDIFF`不处理季度。
可以使用`TIMESTAMPADD ODBC`标量函数执行类似的时间/日期修改操作。
也可以使用`DATEADD()`方法调用从ObjectScript调用此函数:
```java
$SYSTEM.SQL.Functions.DATEADD(datepart,integer-exp,date-exp)
```
# Datepart Argument
日期部分参数可以是以下日期/时间组件之一:全名(日期部分列)或其缩写(缩写列)。这些日期部分组件名称和缩写不区分大小写。
Date Part| Abbreviations |integer-exp = 1
---|---|---
year| yyyy, yy| Increments year by 1.
quarter |qq, q| Increments month by 3.
month |mm, m| Increments month by 1.
week| wk, ww| Increments day by 7.
weekday |dw| Increments day by 1.
day |dd, d| Increments day by 1.
dayofyear |dy, y| Increments day by 1.
hour |hh| Increments hour by 1.
minute |mi, n| Increments minute by 1.
second |ss, s| Increments second by 1.
millisecond |ms| Increments by .001 of a second.
microsecond |mcs| 0–999999 (with precision of 6)
nanosecond| ns| 0–999999999 (with precision of 9)
递增或递减日期部分会导致适当修改其他日期部分。例如,午夜过后的小时递增会自动递增日期,这又可能会递增月份,依此类推。
日期部分可以指定为带引号的字符串或不带引号。这些语法变体执行的操作略有不同:
- `QUOTES`:`DATEADD('month',12,$HOROLOG)`:在创建缓存查询时,日期部分被视为文字。 SQL执行文字替换。这会产生更普遍可重用的缓存查询。
- 无引号:`DATEADD(MONTH,12,$HOROLOG)`:在创建缓存查询时,日期部分被视为关键字。没有文字替换。这会产生更具体的缓存查询。
如果将无效的日期部分值指定为文字,则会发出`SQLCODE-8`错误代码。但是,如果提供无效的日期部件值作为主机变量,则不会发出`SQLCODE`错误,并且`DATEPART`函数返回值为`NULL`。
# 日期表达式格式
`Date-exp`参数可以采用以下任何格式,并且可以包括或省略小数秒:
- %Date logical value (+$H)
- %PosiTime(%Library.PosiTime)逻辑值(编码的64位有符号整数)
- (%Library.TimeStamp)逻辑值(YYYY-MM-DD HH:MM:SS)
- %String(或兼容)值
%STRING(或COMPATIBLE)值可以采用以下任何格式:
- 99999,99999 ($H format)
- /SQL-Server-date Sybase/SQL-Server-time
- Sybase/SQL-Server-time Sybase/SQL-Server-date
- Sybase/SQL-Server-date (default time is 00:00:00)
- Sybase/SQL-Server-time (default date is 01/01/1900)
Sybase/SQL-Server-Date是以下五种格式之一:
```
mmdelimiterdddelimiter[yy]yy dd Mmm[mm][,][yy]yy dd [yy]yy Mmm[mm] yyyy Mmm[mm] dd yyyy [dd] Mmm[mm]
```
其中,分隔符是斜杠(`/`)、连字符(`-`)或句点(`.`)。
`Sybase/SQL-Server-Time`表示以下三种格式之一:
```
HH:MM[:SS:SSS][{AM|PM}] HH:MM[:SS.S] HH['']{AM|PM}
```
请注意,提供`DATEADD`是为了与`Sybase`和`Microsoft SQL Server`兼容。
# 范围和值检查
`DATEADD`对输入值执行以下检查。如果值未通过检查,则返回空字符串。
- 日期字符串必须完整且格式正确,包含适当数量的元素和每个元素的数字,以及适当的分隔符。年份必须指定为四位数。
- 日期值必须在有效范围内。年份:`0001`到`9999`。月份:`1到12天`:`1到31`。时间:`0点到23点`。分钟:`0到59分钟`。秒:`0到59`。
- 返回的递增的`year`值必须在`0001`到`9999`之间。
超出此范围将返回``。
- 一个月中的天数必须与月和年相匹配。
例如,日期`“02-29”`仅在指定的年份为闰年时有效。
- 小于`10`的日期值可以包括或省略前导零。
不允许使用其他非规范整数值。
因此,`Day`值为`“07”`或`“7”`是有效的,但`“007”`、`“7.0”`或`“7a”`无效。
下面的例子为指定的日期添加了1周:
```sql
SELECT DATEADD('week',1,'2018-02-26') AS NewDate
2018/3/5 0:00:00
```
它返回`2018-03-05 00:00:00`,因为增加1周会增加7天。
注意,`DATEADD`提供了省略的时间部分。
下面的例子为时间戳添加了`5`个月:
```sql
SELECT DATEADD(MM,5,'2017-11-26 12:00:00') AS NewDate
2018/4/26 12:00:00
```
它返回`2018-04-26 12:00:00`,因为增加`5`个月也会增加一年。
下面的例子也在时间戳上增加了`5`个月:
```sql
SELECT DATEADD('mm',5,'2018-01-31 12:00:00') AS NewDate
2018/6/30 12:00:00
```
它返回`2018-06-30 12:00:00`。
这里`DATEADD`修改了日值和月值,因为简单地增加月值将导致6月31日,这是一个无效的日期。
下面的例子为时间戳添加了`45`分钟:
```sql
SELECT DATEADD(MI,45,'2018-02-26 12:00:00') AS NewTime
2018/2/26 12:45:00
```
下面的示例还为时间戳添加了`45`分钟,但在本例中,添加的内容增加了日,从而增加了月:
```sql
SELECT DATEADD('mi',45,'2018-02-28 23:30:00') AS NewTime
2018/3/1 0:15:00
```
下面的例子将原始时间戳减去`45`分钟:
```sql
SELECT DATEADD(N,-45,'2018-01-01 00:10:00') AS NewTime
2017/12/31 23:25:00
```
下面的例子为当前日期添加了`60`天,并根据月份的不同长度进行调整:
```sql
SELECT DATEADD(D,60,CURRENT_DATE) AS NewDate
2022/4/4 0:00:00
```
在下面的例子中,第一个`DATEADD`为指定的日期添加了`92`天,第二个`DATEADD`为指定的日期添加了`1 / 4`天:
```sql
SELECT DATEADD('dd',92,'2018-12-20') AS NewDateD,
DATEADD('qq',1,'2018-12-20') AS NewDateQ
```
![image](037D6F5B02E0464AA1D43B8F18DCA3BD)
第一季将于`2019-03-22 00:00:00`回归;
第二季将于`2019-03-20 00:00:00`回归。
每增加`1 / 4,month`字段就会增加`3`,如果需要,还会增加`year`字段。
它还校正给定月份的最大天数。
上面的例子都使用日期部分的缩写。
但是,也可以用它的全名来指定日期部分,就像下面的例子一样:
```sql
SELECT DATEADD('day',92,'2018-12-20') AS NewDate
2019/3/22 0:00:00
```
下面的嵌入式SQL示例使用主机变量来执行与前面示例相同的`DATEADD`操作:
```java
ClassMethod DateAdd()
{
s x="day"
s datein="2019-12-20"
&sql(SELECT DATEADD(:x,92,:datein)
INTO :dateout)
w "in: ",datein,!,"out: ",dateout
}
```
```java
DHC-APP>d ##class(PHA.TEST.SQLCommand).DateAdd()
in: 2019-12-20
out: 2020-03-21 00:00:00
DHC-APP>
```
文章
姚 鑫 · 四月 5, 2021
# 第十七章 使用触发器
本章介绍如何在Intersystems SQL中定义触发器。触发器是响应某些SQL事件执行的代码行。本章包括以下主题:
# 定义触发器
有几种方法可以为特定表定义触发器:
- 在将投影到SQL表的持久性类定义中包含触发定义。例如,`MyApp.person`类的此定义包括`Loggevent`触发器的定义,在每个成功的数据插入到`MyApp.person`表之后,将在每个成功的数据插入后调用:
```java
Class MyApp.Person Extends %Persistent [DdlAllowed]
{
// ... Class Property Definitions
Trigger LogEvent [ Event = INSERT, Time = AFTER ]
{
// Trigger code to log an event
}
}
```
- 使用SQL创建触发命令创建触发器。这在相应的持久性类中生成触发对象定义。 SQL触发器名称按照标识符命名约定进行操作。 IntersystemsIris®数据平台使用SQL触发名称生成相应的触发类实体名称。
必须拥有`%create_trigger`管理级别权限来创建触发器。必须具有删除触发器的`%drop_trigger`管理级别权限。
**类的最大用户定义触发器数为200。**
注意:Intersystems Iris不支持收集投影的表上的触发。用户无法定义这样的触发器,并且作为子表的集合的投影不认为涉及该基本集合的触发。
Intersystems Iris不支持修改`Security.Roles`和`Security.Users`表的触发器。
# 触发器的类型
触发器由以下内容定义:
- 导致它执行的事件类型。触发器可以是单个事件触发器或多事件触发。定义单个事件触发器以在指定表上发生插入,更新或删除事件时执行。定义多事件触发器以执行当在指定的表中发生多个指定的事件中的任何一个时执行。可以使用类定义或创建触发命令定义插入/更新,更新/删除或插入/更新/删除多事件触发器。事件类型在Class定义中指定了所需的事件触发器关键字。
- 触发器执行的时间:在事件发生之前或之后。
这是由可选的`Time trigger`关键字在类定义中指定的。
默认为`Before`。
- 可以将多个触发器与同一事件和时间相关联;在这种情况下,可以使用`order trigger`关键字来控制触发多个触发器的顺序。先触发顺序较低的触发器。
如果多个触发器具有相同的`Order`值,则不指定它们的触发顺序。
- 可选的`Foreach trigger`关键字提供了额外的粒度。
该关键字控制触发器是每一行触发一次(`Foreach = row`),还是每一行或对象访问触发一次(`Foreach = row/object`),还是每语句触发一次(`Foreach = statement`)。
没有`Foreach trigger`关键字定义的触发器每一行触发一次。
如果触发器是用`Foreach = row/object`定义的,那么触发器也会在对象访问期间的特定点被调用,如本章后面所述。
可以使用`INFORMATION.SCHEMA.TRIGGERS`的`ACTIONORIENTATION`属性列出每个触发器的`Foreach`值
下面是可用的触发器及其等价的回调方法:
- `BEFORE INSERT` (等价于 `%OnBeforeSave()`)
- `AFTER INSERT` (等价于 `%OnAfterSave()`)
- `BEFORE UPDATE` (等价于 `%OnBeforeSave()`)
- `AFTER UPDATE` (等价于 `%OnAfterSave()`)
- `BEFORE UPDATE OF specified column(s)`
- `AFTER UPDATE OF specified column(s)`
- `BEFORE DELETE` (等价于 `%OnDelete()`)
- `AFTER DELETE` (等价于 `%OnAfterDelete()`)
注意:当触发器执行时,它不能直接修改正在处理的表中的属性值。
这是因为InterSystems IRIS在字段(属性)值验证代码之后执行触发代码。
例如,触发器不能将LastModified字段设置为正在处理的行中的当前时间戳。
但是,触发器代码可以对表中的字段值发出更新。
更新执行自己的字段值验证。
## AFTER Triggers
在`INSERT`、`UPDATE`或`DELETE`事件发生后执行`AFTER`触发器:
- 如果`SQLCODE=0`(事件成功完成),InterSystems IRIS将执行`AFTER`触发器。
- 如果`SQLCODE`是负数(事件失败),系统间IRIS就不会执行`AFTER`触发器。
- 如果`SQLCODE=100`(没有发现要插入、更新或删除的行),则系统间IRIS执行`AFTER`触发器。
## 递归触发器
触发器执行可以是递归的。
例如,如果表`T1`有一个对表`T2`执行插入操作的触发器,表`T2`也有一个对表`T1`执行插入操作的触发器。
当表`T1`有一个调用例程/过程的触发器,并且该例程/过程执行对`T1`的插入操作时,也可以发生递归。
触发器递归的处理取决于触发器的类型:
- 行和行/对象触发器:InterSystems IRIS不阻止行触发器和行/对象触发器递归地执行。
处理触发器递归是程序员的责任。
如果触发代码不处理递归执行,则可能发生runtime ``错误。
- 语句触发器:InterSystems IRIS阻止`AFTER`语句触发器递归执行。
如果InterSystems IRIS检测到该触发器在执行堆栈中已经被调用,它将不会发出AFTER触发器。
没有错误发出;
触发器不会被第二次执行。
InterSystems IRIS不会阻止`BEFORE`语句触发器递归地执行。
在触发递归之前处理是程序员的责任。
如果`BEFORE`触发器代码不处理递归执行,可能会发生runtime ``错误。
# Trigger Code
每个触发器包含执行触发操作的一行或多行代码。
每当与触发器关联的事件发生时,SQL引擎就会调用这段代码。
如果触发器是使用CREATE触发器定义的,则可以用ObjectScript或SQL编写此操作代码。
(InterSystems IRIS将SQL编写的代码转换为类定义中的ObjectScript。)
如果触发器是使用Studio定义的,那么这个操作代码必须用ObjectScript编写。
因为触发器的代码不是作为过程生成的,所以触发器中的所有局部变量都是公共变量。
这意味着触发器中的所有变量都应该用一个新语句显式声明;
这可以防止它们与调用触发器的代码中的变量发生冲突。
## %ok, %msg, and %oper 系统变量
- `%ok`:仅在触发器代码中使用的变量。
如果触发代码成功,它设置`%ok=1`。
如果触发代码失败,它设置`%ok=0`。
如果在触发器执行期间发出`SQLCODE`错误,InterSystems IRIS将设置`%ok=0`。
当`%ok=0`时,触发器代码中止,触发器操作和调用触发器的操作被回滚。
如果插入或更新触发器代码失败,并且表中定义了一个外键约束,InterSystems IRIS将释放外键表中相应行上的锁。
触发代码可以显式设置`%ok=0`。
这会创建一个运行时错误,中止触发器的执行并回滚操作。
通常,在`设置%ok=0`之前,触发器代码显式地将`%msg`变量设置为用户指定的字符串,用于描述这个用户定义的触发器代码错误。
`%ok`变量是一个必须显式更新的公共变量。
在完成非触发代码`SELECT`、`INSERT`、`UPDATE`或`DELETE`语句后,`%ok`的值与之前的值没有变化。
`%ok`仅在执行触发器代码时定义。
`%msg`:触发代码可以显式地将`%msg`变量设置为描述运行时错误原因的字符串。
设置变量`%msg`。
`%oper`:仅在触发器代码中使用的变量。
触发器代码可以引用变量`%oper`,该变量包含触发触发器的事件(插入、更新或删除)的名称。
## {fieldname}语法
在触发器代码中,可以使用特殊的`{fieldname}`语法引用字段值(对于属于触发器关联的表的字段)。
例如,下面是`MyApp`中`LogEvent`触发器的定义。
`Person`类包含一个对`ID`字段的引用,如`{ID}`:
```java
Class MyApp.Person Extends %Persistent [DdlAllowed]
{
// ... Definitions of other class members
/// This trigger updates the LogTable after every insert
Trigger LogEvent [ Event = INSERT, Time = AFTER ]
{
// get row id of inserted row
NEW id,SQLCODE,%msg,%ok,%oper
SET id = {ID}
// INSERT value into Log table
&sql(INSERT INTO LogTable
(TableName, IDValue)
VALUES ('MyApp.Person', :id))
IF SQLCODE
文章
姚 鑫 · 六月 10, 2021
# 第三章 指定输出的字符集
# 指定输出的字符集
若要指定要在输出文档中使用的字符集,可以设置Writer实例的Charset属性。选项包括`“UTF-8”`、`“UTF-16”`以及InterSystems IRIS支持的其他字符集。
# Writing the Prolog
XML文件的序言(根元素之前的部分)可以包含文档类型声明、处理指令和注释。
## 影响Prolog的属性
在`writer`实例中,以下属性会影响`prolog`:
### Charset
控制两件事`:XML`声明中的字符集声明和(相应的)输出中使用的字符集编码。
### NoXmlDeclaration
控制输出是否包含XML声明。在大多数情况下,默认值是0,这意味着已经编写了声明。如果没有指定字符集,并且输出定向到字符串或字符流,则默认为1,并且不写入任何声明。
## 生成文档类型声明
在根元素之前,可以包含文档类型声明,该声明声明了文档中使用的模式。
要生成文档类型声明,需要使用`WriteDocType()`方法,该方法有一个必选参数和三个可选参数。
就本文档而言,文档类型声明包括以下可能的部分:
```java
```
如这里所示,文档类型有一个名称,根据XML规则,该名称必须是根元素的名称。
声明可以包含外部子集、内部子集或两者。
external_subset 部分指向其他地方的DTD文件。
本节的结构是以下任何一种:
```java
PUBLIC public_literal_identifier
PUBLIC public_literal_identifier system_literal_identifier
SYSTEM system_literal_identifier
```
这里`public_literal_identifier`和`system_literal_identifier`是包含DTD uri的字符串。
注意,DTD可以同时具有公共标识符和系统标识符。
下面是一个文档类型声明示例,它包含一个同时使用公共标识符和系统标识符的外部子集:
```java
```
internal_subset部分是一组实体声明。
下面是一个文档类型声明的示例,它只包含一组内部声明:
```java
!ENTITY city (#PCDATA)>
!ENTITY player (#PCDATA)>
] >
```
`WriteDocType()`方法有四个参数:
- 第一个参数指定文档类型的名称,用于在这个XML文档中使用。
这是必需的,而且必须是有效的XML标识符。
还必须将此名称用作本文档中根级别元素的名称。
- 可选的第二个和第三个参数指定声明的外部部分,如下所示:
WriteDocType参数
第二个参数 | 第三个参数| 其他部分
---|---|---
“publicURI” |null| PUBLIC “publicURI”
“publicURI” |“systemURI”| PUBLIC “publicURI” “systemURI”
null |“systemURI”| SYSTEM “systemURI”
- 可选的第四个参数指定声明的内部部分。如果此参数非空,则将其括在方括号`[]`中,并适当地放在声明的末尾。没有添加其他字符。
## 编写处理指令
要将处理指令写入`XML`,请使用`WriteProcessingInstruction()`方法,该方法有两个参数:
1. 处理指令(也称为目标)的名称。
2. 指令本身是一个字符串。
该方法将以下内容写入XML:
```java
```
例如,要编写以下处理指令:
```java
```
为此,可以按如下方式调用`WriteProcessingInstruction()`方法:
```java
set instructions="type=""text/css"" href=""mystyles.css"""
set status=writer.WriteProcessingInstruction("xml-stylesheet", instructions)
```
## 指定默认命名空间
在编写器实例中,可以指定默认命名空间,该命名空间仅应用于没有`Namespace`参数设置的类。有几个选项:
- 可以在输出方法中指定默认命名空间。四个主要的输出方法(`RootObject()`、`RootElement()`、`Object()`或`Element()`)都接受名称空间作为参数。只有在类定义中未设置`Namespace`参数时,才会将相关元素分配给`Namespace`。
- 可以为编写器实例指定总体默认命名空间。为此,请为编写器实例的`DefaultNamespace`属性指定值。
```java
Class Writers.BasicDemoPerson Extends (%RegisteredObject, %XML.Adaptor)
{
Parameter XMLNAME = "Person";
Property Name As %Name;
Property DOB As %Date;
}
```
默认情况下,如果我们只是导出此类的对象,我们会看到如下所示的输出:
```java
Persephone MacMillan
1976-02-20
```
相反,如果我们在编写器实例中`将DefaultNamespace`设置为`"http://www.person.org",`然后导出一个对象,则会收到如下所示的输出:
```java
Persephone MacMillan
1976-02-20
```
在本例中, `` 元素使用默认名称空间,否则不会分配给名称空间。
问题
Johnny Wang · 七月 13, 2021
各位老师好!
如下两图,是HL7信息体,在形成消息之前,我们一般会先制定文档,包括消息题、消息段、阈值;但是最终在Ensemble中形成的消息是怎么一个过程? 制定好的消息文档可以转换成IRIS可以读取的格式,导入到IRIS中成为消息Schema结构。在处理消息时,可以配置接口应用我们指定的消息Schema结构去处理消息。更多细节可参见文档:HL7 Schemas and Available Tools | Routing HL7 Version 2 Messages in Productions | InterSystems IRIS for Health 2023.1
问题
天恒 周 · 八月 6, 2022
cache的题目资源,类似于Oracle的OCP试题那种,能反应出对基础概念的掌握。 回答您的问题:
1. 我们海外在招募考试平台测试者,您可以直接给certification@intersystems.com 发邮件申请,具体内容可以参考:https://community.intersystems.com/post/beta-testers-needed-our-upcoming-intersystems-iris-system-administration-specialist;
2. 我们国内也即将推出初中高级的培训认证体系,敬请关注。
这还有网上的一些体验题目:https://community.intersystems.com/sites/default/files/post-associated-docs/sysadmin_practice_questions_0.pdf
谢谢您的关注! 好的,感谢!
公告
Claire Zheng · 十二月 22, 2022
2022年12月24日-25日,卫生健康信息标准应用管理培训班 (第二期)将于线上举办,此次培训班由国家卫生健康委统计信息中心指导、由《中国卫生信息管理杂志》社、深圳市卫生健康信息协会主办,InterSystems协办。详细日程请点击此处了解。您可以通过以下方式参与:
报名观看(可申请学分)
视频号(可观看直播)
如需要回看,请扫描“可申请学分”的二维码观看
文章
Weiwei Gu · 九月 14, 2023
昨天,我在一个客户网站提供从 Studio 迁移到 VS Code 的定制咨询时,就遇到了这种情况。
该站点的服务器已配置为使用delegated authentication,但尚未针对 /api/atelier Web 应用程序设置“delegated”复选框,而 InterSystems ObjectScript 扩展包的成员正是使用该复选框进行连接的。
一旦我们的应用程序设置了其复选框并单击了服务器管理器刷新按钮,就可以在服务器上枚举命名空间。
文章
Qiao Peng · 五月 25, 2022
%SYS.Journal.Record 类有一个查询(query), List, 可以列出Journal文件中记录的数据修改历史。例如,要查询谁对global节点^QP(1,2)做过修改,可以使用如下代码。它查询Journal文件(输入参数pFilePath)中的global节点(输入参数pSearchGlobal)的操作:
ClassMethod SearchGlobal(pSearchGlobal = "^QP(1,2)", pFilePath = "C:\InterSystems\IRISHealth\mgr\journal\20220525.003")
{
Set tRS = ##class(%ResultSet).%New("%SYS.Journal.Record:List")
Set tSC = tRS.Execute(pFilePath)
While (tRS.Next())
{
Set address = tRS.Data("Address")
Set globalNode = tRS.Data("GlobalNode")
Set newValue = tRS.Data("NewValue")
Set type = tRS.Data("TypeName")
Set processid = tRS.Data("ProcessID")
Set time = tRS.Data("TimeStamp")
Set globalRef = tRS.Data("GlobalReference")
If globalNode=pSearchGlobal
{
W !
W time,!
W processid,!
W address,!
W type," ",globalRef,"=",newValue,!
}
}
}
公告
Qiao Peng · 三月 3, 2021
InterSystems API Manager (IAM) 版本1.5已正式发布。
IAM容器,包括从原有IAM版本升级的所有相关工件, 现在可以在 WRC 软件发布网址 组件区下载。
该版本的小版本号是 IAM 1.5.0.9-4。
InterSystems API Manager 1.5 使管理API通讯、与你的环境集成、加载API用户更加容易。它包含很多新特性,包括:
改进的用户体验
新的开发者门户工具
对Kafka connectivity的支持
这个版本基于Kong Enterprise version 1.5.0.9。之前的IAM版本包括一个贴牌版本的Kong Enterprise, 在本版本中的Kong Enterprise不再贴牌。 这个变化让我们可以更快的节奏带给您新的版本,并更有效地利用Kong提供的文档和其它资源。
请在 这里 查看IAM 1.5 的文档。这个文档仅说明IAM特殊的元素。产品中的文档链接直接打开Kong Enterprise的文档。
从IAM 0.34-1 升级需要通过3个中间版本累积升级,在 文档中有详细的说明。
IAM 仅以OCI (Open Container Initiative) 或 Docker 容器格式发放。容器镜像可运行在Linux x86-64 和 Linux ARM64的OCI 兼容的运行引擎上, 详情请参考 支持的平台。
Best Regards,
Stefan 欢迎开发者们多关注!
公告
Claire Zheng · 三月 18, 2021
中文社区的开发者们,大家好!
我们调整了开发者社区的积分规则,将其调整为双倍积分!自2021年3月18日起,如果您在社区贡献了文章或问题,将获得:
在英文社区获得200积分在西语、葡语、日语和中文社区将获得400积分*
针对译文帖子,将获得100积分
另外,你还可以从特定文章/评论中获得更多积分,详见下表:
第1篇文章
第5篇文章
第10篇文章
第25篇文章
第50篇文章
1,500 分
7,500 分
15,000 分
40,000 分
75,000分
第1个问题
第5个问题
第10个问题
第25个问题
第50个问题
500 分
2,000 分
5,000 分
15,000 分
30,000 分
而且你将可以获得奖励徽章!在 这篇文章里, 你可以看到对应等级和徽章(把鼠标放在徽章上查看如何获得)。
*我们将在一段时间内提升西语/葡语/中文/日语社区的积分
更多关于Global Masters倡导中心的信息:
如何加入InterSystems Global Masters倡导中心?
Global Masters徽章:规则解读
如果您还没有加入InterSystems Global Masters倡导中心 , 现在就加入吧!
如果您有任何疑问,欢迎跟帖回复!