清除过滤器
公告
Claire Zheng · 九月 5, 2022
亲爱的社区开发者们,
我很高兴地向大家介绍一位我们的新版主 @Tete.Zhang (张特特)!
@Tete.Zhang (张特特) 目前任职于InterSystems中国,在WRC部门任职资深技术支持专家一职。
以下是@Tete.Zhang (张特特)的自我介绍:
在2015年夏天实习结束后,我于2016年正式作为技术支持工程师加入InterSystems,从那时起,我在InterSystems全球支持中心北美分部工作了六年,2022年,我调职至北京,服务于InterSystems中国,希望能为成长中的中国市场出一份力。
很高兴可以在社区与大家相遇,希望能与大家一起努力,创造更精彩的社区!
再次欢迎我们的新版主 @Tete.Zhang (张特特)👏🏼👏🏼👏🏼👏🏼👏🏼
期待你在DC成长为一名优秀版主!
文章
Claire Zheng · 一月 13, 2023
在InterSystems 2022年全球峰会上,InterSystems HealthShare 产品管理总监 Jonathan Teich 及其团队解读了医疗与医疗IT行业的趋势,并分享了HealthShare的最新产品策略与路线图,演示了一些易用且具有前瞻性的功能和用例。
文章
姚 鑫 · 三月 8, 2021
# 第五章 SQL定义表(三)
# 使用DDL定义表
可以使用标准DDL命令在InterSystems SQL中定义表:
InterSystems SQL中可用的DDL命令
- `ALTER`命令 `ALTER TABLE`,`ALTER VIEW`
- `CREATE` 命令 `CREATE TABLE`,`CREATE VIEW`,`CREATE INDEX`,`CREATE TRIGGER`
- `DROP` 命令 `DROP TABLE`,`DROP VIEW`,`DROP INDEX`,`DROP TRIGGER`
可以通过多种方式执行DDL命令,包括:
- 使用动态SQL。
- 使用嵌入式SQL。
- 使用DDL脚本文件。
- 使用ODBC调用。
- 使用JDBC调用。
## 在嵌入式SQL中使用DDL
在ObjectScript方法或例程中,可以使用嵌入式SQL来调用DDL命令。
例如,以下方法创建一个`Sample.Employee`表:
```java
/// d ##class(PHA.TEST.SQL).CreateTable()
ClassMethod CreateTable() As %String
{
&sql(CREATE TABLE Sample.Employee (
EMPNUM INT NOT NULL,
NAMELAST CHAR (30) NOT NULL,
NAMEFIRST CHAR (30) NOT NULL,
STARTDATE TIMESTAMP,
SALARY MONEY,
ACCRUEDVACATION INT,
ACCRUEDSICKLEAVE INT,
CONSTRAINT EMPLOYEEPK PRIMARY KEY (EMPNUM)))
IF SQLCODE=0 {WRITE "Table created" RETURN "Success"}
ELSEIF SQLCODE=-201 {WRITE "Table already exists" RETURN SQLCODE}
ELSE {WRITE "Serious SQL Error, returning SQLCODE" RETURN SQLCODE_" "_%msg}
}
```
```java
DHC-APP>d ##class(PHA.TEST.SQL).CreateTable()
Table already exists
```
调用此方法时,它将尝试创建`Sample.Employee`表(以及相应的`Sample.Employee`类)。如果成功,则将`SQLCODE`变量设置为0。如果失败,则`SQLCODE`包含指示错误原因的SQL错误代码。
这样的DDL命令失败的最常见原因是:
- `SQLCODE -99`(违反权限):此错误表明没有执行所需DDL命令的权限。通常,这是因为应用程序尚未确定当前用户是谁。可以使用`$SYSTEM.Security.Login()`方法以编程方式执行此操作:
```java
DHC-APP>w $SYSTEM.Security.Login("yx","123456")
0
```
`SQLCODE -201`(表或视图名称不是唯一的):此错误表明正在尝试使用已经存在的表的名称创建新表。
## 使用类方法执行DDL
在ObjectScript中,可以使用`Dynamic SQL%SQL.Statement`对象使用`Dynamic SQL`准备和执行DDL命令。
下面的示例定义了一个使用动态SQL创建表的类方法:
```java
ClassMethod DefTable(user As %String,pwd As %String) As %Status [Language=objectscript]
{
DO ##class(%SYSTEM.Security).Login(user,pwd)
SET myddl=2
SET myddl(1)="CREATE TABLE Sample.MyTest "
SET myddl(2)="(NAME VARCHAR(30) NOT NULL,SSN VARCHAR(15) NOT NULL)"
SET tStatement=##class(%SQL.Statement).%New()
SET tStatus=tStatement.%Prepare(.myddl)
IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
SET rset=tStatement.%Execute()
IF rset.%SQLCODE=0 {WRITE "Created a table"}
ELSEIF rset.%SQLCODE=-201 {WRITE "table already exists"}
ELSE {WRITE "Unexpected error SQLCODE=",rset.%SQLCODE}
}
```
与嵌入式SQL示例一样,如果当前没有用户登录,则此方法将失败。
## 通过导入和执行DDL脚本定义表
可以使用`IRIS()`方法从终端会话中交互式地导入InterSystems SQL DDL脚本文件,也可以使用`DDLImport(“ IRIS”)`方法作为后台作业来导入InterSystems SQL DDL脚本文件。此方法可以导入和执行多个SQL命令,使可以使用txt脚本文件来定义表和视图,并用数据填充它们。
如果要将表从另一供应商的关系数据库迁移到InterSystems IRIS,则文本文件中可能包含一个或多个DDL脚本。 InterSystems IRIS提供了几种`%SYSTEM.SQL`方法来帮助将此类表加载到InterSystems IRIS中。可以使用通用的`DDLImport()`方法或特定供应商的`%SYSTEM.SQL`方法。供应商特定的SQL转换为InterSystems SQL并执行。错误和不支持的功能记录在日志文件中。
例如,从ObjectScript命令行加载一个Oracle DDL文件:
1. 使用InterSystems IRIS启动器菜单中的“终端”命令启动终端会话。
2. 切换到希望在其中加载表定义的名称空间:
```java
SET $namespace = "MYNAMESPACE"
```
3. 调用所需的DDL导入方法:
```java
DO $SYSTEM.SQL.Oracle()
```
并按照终端上显示的说明进行操作。

# 定义分片表
创建分片表有三个要求。
1. 许可证密钥必须支持分片。使用管理门户,系统管理,许可,许可证密钥显示当前许可证或激活新许可证。
2. 必须在IRIS实例上启用分片。必须具有`%Admin_Secure`特权才能启用分片。使用“管理门户”,“系统管理”,“配置”,“系统配置”,“分片配置”来选择“启用分片”按钮。这使当前的InterSystems IRIS实例可以在分片群集中使用。选择“为任何角色启用此实例”或“仅对碎片主机角色启用此实例”。按确定。重新启动您的InterSystems IRIS实例。
3. 必须在IRIS实例上部署分片群集。此分片群集包含一个分片主名称空间。如果未为分片配置当前名称空间,则尝试定义分片表失败,并显示错误#9319:当前名称空间%1没有配置分片。
然后,可以在Shard Master命名空间中定义一个分片表,该表已定义为分片集群的一部分。可以使用`CREATE TABLE`通过指定分片键来定义分片表。或者,可以创建一个持久化类,该持久化类投影到分片表。
# 通过查询现有表定义表
可以使用`$SYSTEM.SQL.QueryToTable()`方法基于一个或多个现有表来定义和填充新表。指定一个查询和一个新的表名称。现有表名和/或新表名可以是合格的或不合格的。该查询可以包含`JOIN`语法。该查询可以提供列名别名,这些别名将成为新表中的列名。
1. `QueryToTable()`复制现有表的DDL定义,并为其指定指定的新表名。它复制查询中指定的字段的定义,包括数据类型,`maxlength`和`minval / maxval`。它不复制字段数据约束,例如默认值,必需值或唯一值。它不会将引用从字段复制到另一个表。
如果查询指定`SELECT *`或`SELECT%ID`,则将原始表的`RowID`字段复制为数据类型为整数的非必需,非唯一数据字段。 `QueryToTable()`为新表生成唯一的`RowID`字段。如果复制的`RowID`名为`ID`,则生成的`RowID`名为`ID1`。
`QueryToTable()`为此新表创建一个对应的持久化类。持久类定义为DdlAllowed。新表的所有者是当前用户。
不管源表中的这些设置如何,新表都将使用`Default Storage = YES`定义,并且`Supports Bitmap Indices = YES`。
为新表创建的唯一索引是`IDKEY`索引。没有位图范围索引生成。复制字段的索引定义不会复制到新表中。
2. `QueryToTable()`然后使用查询选择的字段中的数据填充新表。它将表格的“范围大小”设置为100,000。它估计`IDKEY`块计数。运行“音调表”以设置实际的“范围大小”和“块计数”,以及每个字段的“选择性”和“平均字段大小”值。
`QueryToTable()`既创建表定义,又用数据填充新表。如果只希望创建表定义,请在查询`WHERE`子句中指定一个不选择任何数据行的条件。例如,`WHERE Age < 20 AND Age > 20`.
下面的示例从S`ample.Person`复制`“名称”`和`“年龄”`字段,并创建一个AVG(Age)字段。这些字段定义用于创建名为`Sample.Youth`的新表。然后,该方法`where Age < 21`. 的那些记录的`Sample.Person`数据填充`Sample.Youth`。`AvgInit`字段包含创建表时所选记录的合计值。
```java
DO $SYSTEM.SQL.QueryToTable("SELECT Name,Age,AVG(Age) AS AvgInit FROM Sample.Person WHERE Age < 21","Sample.Youth",1,.errors)
```
```java
DHC-APP> DO $SYSTEM.SQL.QueryToTable("SELECT Name,Age,AVG(Age) AS AvgInit FROM Sample.Person WHERE Age < 21","Sample.Youth",1,.errors)
Preparing query...
Creating class...
Compiling class...
Copying data...
```

# 外部表
在InterSystems SQL中,还可以具有“外部表”,这些表在SQL词典中定义但存储在外部关系数据库中。外部表的行为就像它们是本机InterSystems IRIS表一样:可以对它们发出查询并执行`INSERT`,`UPDATE`和`DELETE`操作。 InterSystems SQL网关提供对外部数据库的访问,该网关使用ODBC或JDBC提供透明的连接。
# List表
`INFORMATION.SCHEMA.TABLES`持久类显示有关当前名称空间中所有表(和视图)的信息。它提供了许多属性,包括模式和表名称,表的所有者以及是否可以插入新记录。 `TABLETYPE`属性指示它是基表还是视图。
以下示例返回当前名称空间中所有表和视图的表类型,架构名称,表名称和所有者:
```java
SELECT Table_Type,Table_Schema,Table_Name,Owner FROM INFORMATION_SCHEMA.TABLES
```

`INFORMATION.SCHEMA.CONSTRAINTTABLEUSAGE`持久类为为当前名称空间中的每个表定义的每个主键(显式或隐式),外键或唯一性约束显示一行。 `INFORMATION.SCHEMA.KEYCOLUMNUSAGE`为定义为当前名称空间中每个表的这些约束之一的一部分的每个字段显示一行。
# 列出列名和数字
可以通过以下四种方式列出指定表的所有列名(字段名):
- `GetColumns()`方法。这列出了所有列名和列号,包括隐藏的列。 `ID(RowID)`字段可以隐藏也可以不隐藏。 `x__classname`列始终是隐藏的;除非使用`Final class`关键字定义了持久类,否则它将自动定义。
- 管理门户网站SQL界面(系统资源管理器,SQL)架构内容的“目录详细信息”选项卡。它列出了所有列名和列号(包括隐藏的列)以及其他信息,包括数据类型和指示列是否被隐藏的标志。
- `SELECT TOP 0 * FROM`表名。这将按列号顺序列出所有非隐藏的列名。请注意,由于隐藏的列可以按列号顺序出现在任何位置,因此您无法通过计算这些非隐藏的列名来确定列号。
- `INFORMATION.SCHEMA.COLUMNS`持久类为当前名称空间中每个表或视图中的每个非隐藏列列出一行。 `INFORMATION.SCHEMA.COLUMNS`提供了大量属性,用于列出表和视图列的特征。请注意,`ORDINALPOSITION`与列号不同,因为不计算隐藏字段。 `GetColumns()`方法同时计算隐藏字段和非隐藏字段。
下面的示例使用`INFORMATION.SCHEMA.COLUMNS`列出一些列属性:
```java
SELECT TABLE_NAME,COLUMN_NAME,ORDINAL_POSITION,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH,
COLUMN_DEFAULT,IS_NULLABLE,UNIQUE_COLUMN,PRIMARY_KEY
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='Sample'
```

## GetColumns()方法
要以列号顺序列出表中的列名,可以使用`GetColumns()`方法,如下所示:
```java
/// d ##class(PHA.TEST.SQL).GetColumn()
ClassMethod GetColumn()
{
SET stat=##class(%SYSTEM.SQL).GetColumns("Sample.Person",.byname,.bynum)
IF stat=1 {
SET i=1
WHILE $DATA(bynum(i)) {
WRITE "name is ",bynum(i)," col num is ",i,!
SET i=i+1
}
}
ELSE { WRITE "GetColumns()无法找到指定的表" }
}
```
`GetColumns()`列出所有已定义的列,包括隐藏的列。如果表引用了嵌入式`%SerialObject`类,则`GetColumns()`首先列出持久性类中的所有列,包括引用`%SerialObject`的属性,然后列出所有`%SerialObject`属性。在下面的`GetColumns()`结果中显示了这一点:
```java
DHC-APP>d ##class(PHA.TEST.SQL).GetColumn()
name is ID col num is 1
name is Age col num is 2
name is DOB col num is 3
name is FavoriteColors col num is 4
name is Home col num is 5
name is Name col num is 6
name is Office col num is 7
name is SSN col num is 8
name is Spouse col num is 9
name is x__classname col num is 10
name is Home_City col num is 11
name is Home_State col num is 12
name is Home_Street col num is 13
name is Home_Zip col num is 14
name is Office_City col num is 15
name is Office_State col num is 16
name is Office_Street col num is 17
name is Office_Zip col num is 18
```
还可以使用此方法确定指定列名的列号,如下所示:
```java
/// d ##class(PHA.TEST.SQL).GetColumn1()
ClassMethod GetColumn1()
{
SET stat=##class(%SYSTEM.SQL).GetColumns("Sample.Person",.byname)
IF stat=1 {
WRITE "Home_State is column number ",byname("Home_State"),!
} ELSE {
WRITE "GetColumns()无法找到指定的表"
}
}
```
```java
DHC-APP>d ##class(PHA.TEST.SQL).GetColumn1()
Home_State is column number 12
```
公告
Claire Zheng · 十一月 18, 2021
亲爱的社区开发者们,大家好!
我们欢迎您来参加 2021年欧洲医疗编程马拉松 ,这一赛事时间为2021年11月19日-21日,免费参赛,线上赛道(On-line Track)的申请截止日期延长至11月15日。
我们将有一个InterSystems的挑战:“用FHIR创新”。InterSystems赛道的奖金设置如下:
🥇第一名: 1500 EUR🥈第二名: 1000 EUR🥉第三名: 500 EUR我们为所有参加InterSystems挑战的人准备了奖品!参考下图,了解我们的挑战细节:)你愿意参加吗?请在下面的投票中告诉我们!
InterSystems挑战赛: 用FHIR创新
无论是IoMT的实现、更容易的患者参与,还是用于分析解决方案的临床数据的可用性,FHIR(医疗数据交换的标准)都可以推动创新。利用FHIR提供的合成数据来改善对患者及其治疗的了解,或者仅仅是在FHIR服务的帮助下,使您的解决方案在实践中立即可用,以收集和提供数据。
为您的解决方案使用一个或多个InterSystems FHIR服务,例如云中的FHIR存储库或HealthShare消息转换服务,并有资格获得InterSystems奖。InterSystems将为参与者提供免费访问服务以及在线和现场技术援助和指导。
在这次编程马拉松中,每个团队将由3位成员组成。如果你没有队伍,组织者会在比赛前安排好队伍。在这里上了解更多关于编程马拉松的信息。
期待与您相聚!如果你计划参加,请在下面告诉我们!
文章
Jeff Liu · 四月 1, 2024
此视频帮助大家了解InterSystems如何帮助CRO来加快临床数据采集和更快地推广市场。
演讲嘉宾:
Jim Coutcher, Senior Director/Principal, Global Head of Enriched Studies, Real World Solutions, IQVIAQi Li, Physician Executive, InterSystemsMatt Stannard, life Sciences Advisor, InterSystems
欢迎大家来我们的 Bilibili主页观看更多视频!
文章
Nicky Zhu · 十月 18, 2021
目录
技术概要: 基于角色的访问控制 1
基于角色的访问控制:为什么它很重要? 1
基于角色的访问控制:如何在 InterSystems IRIS 中工作 1
简要概念概述 1
示例用例 2
基于角色的访问控制:探索它 3
用前须知 3
发现管理门户(Management Portal)页面访问所需的资源 3
创建和分配您自己的管理者角色 4
创建用户并分配新角色 5
尝试管理门户(Management Portal)中的角色 6
了解有关基于角色的访问控制的更多信息 7
技术概要:基于角色的访问控制
本文档向您介绍基于角色的访问控制,解释它在 InterSystems IRIS®数据平台中的工作原理,并帮助您亲自探索。
要浏览所有的技术概要(First Look),包括可以在 InterSystems IRIS 免费的评估实例上执行的那些,请参见 InterSystems First Looks(《InterSystems 技术概要》)。
基于角色的访问控制:为什么它很重要?
当您首次开始使用一个新的数据库平台时,有件事情可能很快就会变得清晰起来:您可能不希望企业中的所有用户都查看和更改系统上的所有内容。
InterSystems IRIS 和所有的数据库平台一样,允许您精细指定 InterSystems IRIS 的每个用户可以执行的操作。我们用来控制用户授权(authorization)执行操作的机制被称为基于角色的访问控制(role-based access control)。
如果您已经熟悉了基于角色的访问控制,InterSystems IRIS 方案很可能与您以前使用过的一些方案相似。您会在下一节找到有关我们如何处理它的更多细节。
如果您是基于角色的访问控制的新手,这意味着比旧的访问控制方法节省时间,因为旧的访问控制方法没有提供执行系统操作的权限分组。
如果没有基于角色的访问控制,为每个用户逐个分配使用 InterSystems IRIS 的各个方面的权限可能需要数小时甚至数天。然后,如果有新员工需要访问,您将不得不重复这个过程。
基于角色的访问控制允许您在初始配置 InterSystems IRIS 时将权限分组到角色中。然后,您可以为每个系统用户分配一个或多个现成的角色。您还可以使用或修改一组预定义的角色<span id="2_Role-Based_Access_Control:_How_It_Work" class="anchor"></span>。
此外,通过基于角色的访问控制,如果用户需要使用一组新的权限,则可以将该组权限分组为一个角色,并将该角色分配给用户。而且您可以随时改变角色内的权限列表。
基于角色的访问控制: 如何在 InterSystems IRIS 中工作
InterSystems IRIS 为基于角色的访问控制提供了一个完整的解决方案,我们将在本节中对此进行描述。InterSystems IRIS 支持的每一种认证机制,包括 LDAP、Kerberos 和 OS-based,都可以使用本地 InterSystems 基于角色的访问控制。如果您愿意,您可以使用 LDAP 而不是 InterSystems IRIS 进行角色分配。
简要概念概述
把 InterSystems IRIS 中的信息和功能视为您要保护的资产 ,就像您为属于您的资产投保一样。
基于角色的访问控制:如何在 InterSystems IRIS 内部工作
在 InterSystems IRIS 中被视为资产的项目包括:
数据库,将数据和代码作为对象存储。
服务,控制用户连接到 InterSystems IRIS 的能力。
某些管理权限。
InterSystems IRIS 应用程序,包括管理门户(Management Portal)中的各个页面,它是 InterSystems IRIS 的系统管理用户界面。
在 InterSystems IRIS 中,每项资产(asset)都由一个资源**(resource)来表示,一个资源(resource)可以表示多个资产(asset)。
资源(resource)充当它所代表的资产(asset)的看门人:根据资源类型,它与 "读取"、"写入"(包括读取),和在某些情况下的 "使用"(执行)权限(permission) 配对。例如,数据库只存在两种类型的权限:读取,允许查看数据和执行例程;写入,允许修改数据。
资源与权限的配对被称为权限(privilege),权限按角色(role)分组。
最后,角色(role)被分配给 InterSystems IRIS 中的用户(user) 。每个用户(user)在首次使用 InterSystems IRIS 进行认证时,都会有一个或多个角色(role)分配给他们。可以在会话期间向用户添加或删除角色(role)。
基于角色(role)的访问控制的具体授权方式取决于您所选择的认证机制。在线文档中完全涵盖了授权的这方面内容。
提示:对于内部测试和暂存系统,您可能不希望设置基于密码的认证或基于角色(role)的不同级别的访问控制。如果您使用 "最低(minimal)" 安全性来安装您的实例,这个选项是可用的,默认情况下,它给拥有实例的管理门户(Management Portal) URL 的任何人提供完全管理权限。
示例用例
如上所述,管理门户(Management Portal)中的各个页面是 InterSystems IRIS 中您可以保护的资产(asset)。管理门户( Management Portal)允许用户(user)查看和执行 InterSystems IRIS 基本方面的操作,如 globals、命名空间,甚至资源(resource)和角色(role)本身。
下面的屏幕截图显示了当实例的管理员使用安装时创建的 _SYSTEM 帐户登录时,管理门户(Management Portal)的外观和行为。 _SYSTEM 用户可以访问 System Administration(系统管理) > Security(安全)> Users(用户) ,让他们可以查看和修改任何用户(user)及其角色(role)。
您可能想限制某些管理门户(Management Portal)用户的角色(role)分配,使他们不能查看或修改用户(user)帐户或任何其他对安全至关重要的信息。在下一节,我们将告诉您如何做到这一点。
基于角色的访问控制: 探索它
下面的示例向您展示了如何设置两种类型的"管理者"角色,以便在管理门户(Management Portal)中使用。第一个角色将能够访问允许修改用户和角色定义等安全相关项的页面。第二个角色将没有这个访问权限。
然后您会看到拥有这些角色的用户如何与管理门户(Management Portal)交互。
重要提示: 为了让您体验 InterSystems IRIS,而又不陷入细节的困境,我们保持了简单的探索。例如,我们让您尽可能多地使用默认设置。
但是,当您把 InterSystems IRIS 引入您的生产系统时,您需要做很多不同的事情,特别是(但不限于)安全方面。
所以请确保不要把这种对 InterSystems IRIS 的探索与真实的情况相混淆!本文档末尾提供的参考资料将使您对在生产中使用 InterSystems IRIS 的情况有一个很好的了解。
用前须知
要使用该程序,您需要一个正在运行的 InterSystems IRIS 实例。您的选择包括多种类型的已授权的和免费的评估实例;该实例不需要由您正在工作的系统托管(尽管它们必须相互具有网络访问权限)。关于如何部署每种类型的实例的信息(如果您还没有可使用的实例),请参见 InterSystems IRIS Basics: Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 Deploying InterSystems IRIS(部署 InterSystems IRIS)。使用同一文档中的 InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)和 .Net IDE 中的信息将 Visual Studio 连接到您的 InterSystems IRIS 实例。
发现管理门户(Management Portal)页面访问所需的资源
对管理门户(Management Portal)中的每个页面的访问都受到至少一种资源的保护。您可以通过以下方式发现所需的资源:
使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中URL described for your instance(为您的实例描述的 URL),在浏览器中打开您的实例的管理门户(Management Portal)。
通过点击相应菜单项中的每一个单词,导航至 System Administration(系统管理) > Security(安全)。
基于角色的访问控制:探索它
提示: 在管理门户(Management Portal)中,带有子页面的菜单项在其名称旁边包含 >>。页面没有这样的标记。
在 Users(用户) 菜单项中,点击"用户(Users)"一词右侧的任何位置。这个操作显示查看 Users(用户)页面所需的资源,即 %Admin_Secure。(Security(安全) 和 Encryption(加密) 子菜单中的所有页面都需要 %Admin_Secure 资源上的使用权限("U")。)
导航至 System Administration(系统管理) > Configuration(配置) > System Configuration(系统配置)。
点击"内存和启动(Memory and Startup)"右侧的任何位置。您会看到,查看该页面所需的资源是 %Admin_Manage。
创建和分配您自己的管理者角色
对于管理门户(Management Portal)的 System Administration(系统管理)菜单内的页面,您需要具有
%Admin_Secure 和 %Admin_Manage 资源权限的角色。
鉴于这种结构,您可能希望创建两个反映管理级别的角色,一个是可以访问除安全相关页面以外的所有页面,另一个是可以执行所有操作,包括安全相关的操作。您可以使用预定义的 %Managerrole 作为模板。
使用 _SYSTEM 帐户登录管理门户(Management Portal)。
导航至 System Administration(系统管理) > Security(安全) > Roles(角色) ,并点击 Go。您将看到安装了 InterSystems IRIS 的角色列表,包括 %Manager 角色。
点击 %Manager 链接。 General(常规) 标签显示具有此角色的用户可用的权限(与权限配对的资源)。
在权限中,您会看到 %Admin_Secure 和 %Admin_Manage 上的使用权限。
您也会看到许多其他的权限。这是因为您需要访问许多不同的资源,才能够查看和修改 InterSystems IRIS 设置。既然我们知道只有一种关键资源 %Admin_Secure,在 System Administration(系统管理)的安全相关页面的访问方面,对该资源的访问将是我们两个自定义角色之间的唯一区别。
点击 Cancel(取消) (在 Edit %Manager 下面),返回到主 Roles(角色)页面。
创建 "标准管理者"角色
在 Roles(角色)页面上,点击 Create New Role(创建新角色)。将出现一个角色定义页面。
基于角色的访问控制:探索它
在 Name(名称) 字段中,输入"Standard_Mgr"。
在 Copy from(复制自) 下拉菜单中,选择 %Manager。这将复制所有信息,包括权限,从预定义 %Manager 角色到新角色。
将描述更改为您所选择的描述,例如:"Role for System Administration without security access(不具有安全访问权限的系统管理角色)"。
点击 Save(保存)。将出现一条 Role saved(保存角色) 信息,您将在 General(常规)标签中看到新角色的权限列表。
在 %Admin_Secure 行中,点击 Delete(删除)。这就从角色中删除了权限。
再次点击 Save(保存) 来保存更改。
创建"安全管理员"角色
在 Roles(角色)页面上,点击 Create New Role(创建新角色)。将出现一个角色定义页面。
在 Name(名称) 字段中,输入"Security_Mgr"。
在 Copy from(复制自)下拉菜单中,选择 %Manager。这将复制所有信息,包括权限,从预定义 %Manager 角色到新角色。
将描述更改为您所选择的描述,例如:"Role for System Administration with securityaccess(具有安全访问权限的系统管理角色)"
点击 Save(保存)。将出现一条 Role saved 信息,您将在 General(常规)标签中看到新角色的权限列表。
创建用户并分配新角色
要查看角色的运行情况,需要创建两个用户,每个用户对应一个新角色。
使用 _SYSTEM 帐户登录管理门户(Management Portal)。
导航至 System Administration(系统管理) > Security(安全) > Users(用户),并点击 Go。您将看到安装了 InterSystems IRIS 的用户定义列表。
创建"标准管理员"用户
在主 Users(用户) 页面上,点击 Create New User(创建新用户)。将出现一个用户定义页面。
在 Name(名称) 字段中,输入"Std_Mgr"。(用户的名称不能与角色的名称一致)。
在 Password(密码) 和 Password (confirm)(确认密码) 字段中,输入您选择的密码。
点击 Save(保存)。将出现一条 User saved 信息。
点击 Roles(角色)标签。滚动左侧的 Available 列表,并高亮显示 Standard_Mgr(标准管理员)。
点击右箭头 ,将该角色添加到 Selected(已选)列表中。然后点击"Assign(分配)"。
7. 点击 Cancel(取消) 以返回到主 Users(用户)页面。
创建"安全管理员"用户
在主 Users(用户) 页面上,点击 Create New User(创建新用户)。将出现一个用户定义页面。
在 Name(名称) 字段中,输入"Sec_Mgr"。
在 Password(密码) 和 Password (confirm)(确认密码) 字段中,输入您选择的密码。
基于角色的访问控制:探索它
点击 Save(保存)。将出现一条 User saved 信息。
点击 Roles(角色)标签。滚动左侧的 Available 列表,并高亮显示 Security_Mgr(安全管理员)。
点击右箭头,将该角色添加到 Selected(已选)列表中。然后点击 Assign(分配)。
点击 Cancel(取消) 以返回到主 Users(用户)页面。
尝试管理门户(Management Portal)中的角色
以 Std_Mgr 用户(标准管理员用户)登录管理门户(Management Portal)。您将看到,与安全有关的菜单选项是灰色的,正如预期的那样。Interoperability(互操作性)菜单选项也是灰色的,因为从其中复制两个自定义角色的预定义 %Manager 没有访问这些页面所需的权限。
退出,然后以 Sec_Mgr 用户(安全管理员用户)重新登录。 正如您所看到的,这个用户具有对 System Administration(系统管理) > Security(安全)和 System Administration(系统管理) > Encryption(加密) 子菜单中的页面的完全访问权限。
了解有关基于角色的访问控制的更多信息
要了解有关基于角色的访问控制和 InterSystems IRIS 安全模型的更多信息,请参见:
About InterSystems Security(《有关 InterSystems 安全》)中的 "Authorization:Controlling User Access(授权:控制用户访问)"一节
InterSystems IRIS Programming Orientation Guide(《InterSystems IRIS 编程指南》)中的 "InterSystems IRIS Security(InterSystems IRIS 安全)"和 "Namespaces and Databases(命名空间和数据库)"部分 --- 为应用程序开发人员提供有关基于角色的访问控制的信息。
Security Tutorial(《安全教程 》)中的 "Authorization(授权)"部分 --- 创建用户、角色和权限的逐步说明。
文章
Qiao Peng · 三月 29, 2021
一些熟悉SQL的用户希望用SQL表的方式获取InterSystems IRIS/Caché的变更数据。知道了Global和SQL表的对应关系,就可以知道是哪一张SQL表数据变化了,甚至通过SQL查询获取变更的数据。下面介绍如何实现这种方式,和注意事项。
获取Global和SQL表的对应关系
通常InterSystems IRIS/Caché的持久化的对象模型(类)和SQL表之间有一一对应的关系;而持久化的对象模型和Global之间也有一一对应关系。建立Global和SQL表的对应关系,通常可以使用以下的SQL查询特定SQL schema下所有表对应的Global:
SELECT CC.SqlQualifiedNameQ SQLTable, CS.parent Class, CS.DataLocation
FROM %Dictionary.CompiledStorage CS, %Dictionary.CompiledClass CC
WHERE CS.parent = CC.ID
AND CC.SqlSchemaName= <schemaname>
其中<schemaname>是SQL的Schema名称; 返回字段SQLTable是SQL表名、Class是对象类名、DataLocation是保存数据的Global名称。
多种建模方式Global和SQL表的对应关系的影响
InterSystems IRIS/Caché都是支持多种建模方式的数据平台,常见的建模方式有SQL、面向对象、多维数组。如果之前不了解InterSystems IRIS/Caché的多维数组,可以先简单理解为键值对。无论使用何种建模方式,都可以得到3套模型:SQL模型、对象模型和多维数组存储模型(Global模型)。上面提到通常InterSystems IRIS/Caché的持久化的对象模型(类)和SQL表之间有一一对应的关系。但由于SQL表达模型的局限性, InterSystems IRIS/Caché的对象模型和SQL表之间并不总是一一对应的关系。
下面就逐一分析各种建模方式下,如何分析和获取Global和SQL表的对应关系。
1. 基于SQL建模
如果InterSystems IRIS/Caché模型就是用SQL建模的,查找Global和SQL表的对应关系很简单:对象模型是基于SQL模型自动创建的,因此它们之间是一对一的关系。这是,在Caché里,编译出的Storage 类型为%Library.CacheStorage;在InterSystems IRIS里,编译出的Storage 类型为%Storage.Persistent。
可以执行SQL查询:
SELECT CC.SqlQualifiedNameQ as SQLTable, CS.parent as Class, CS.DataLocation
FROM %Dictionary.CompiledStorage CS, %Dictionary.CompiledClass CC
WHERE CS.parent = CC.ID
AND CC.SqlSchemaName= <schemaname> AND type='%Library.CacheStorage'
其中<schemaname>是SQL的Schema名称,如果Schema里有“_”,应将其去掉。Parent字段是SQL表对应的类名,DataLocation是保存数据的Global名称。而Global的第一个下标就是行号/Id字段。
例如使用DDL创建一个table:
Create table Demo.Mytable(name varchar(20), notes varchar(100))
通过上面的SQL查询,DataLocation为Demo.MytableD。那么Journal中所有对于Global为Demo.MytableD的操作就是对表Demo.Mytable的记录操作。例如^Demo.MytableD(123), 就是对行号/Id字段为123的Demo.Mytable记录到操作,从而可以通过SQL: SELECT name, notes from Demo.Mytable WHERE id = 123 获取这条变更的记录。
2. 基于对象建模
如果InterSystems IRIS/Caché模型是使用对象建模的,查找Global和SQL表的对应关系有时并不那么简单。例如以下描述患者及地址的简单对象模型:
Class Demo.Address Extends %SerialObject
{
Property Type As %String;
Property City As %String;
Property Street As %String;
Property RoomNo As %String;
}
Class Demo.Patient Extends %Persistent
{
Property Name As %String;
Property Gender As %String;
Property DOB As %Date;
Property Addresses As list Of Demo.Address(SQLPROJECTION = "table", STORAGEDEFAULT = "array");
}
因为患者可能有多个地址,因此Demo.Patient类用以列表类型(list)描述地址属性。其中地址Demo.Address对象模型是通过被引用的持久化对象来序列化的,此处引用它的持久化对象类就是Demo.Patient。Demo.Address类并没有独立的Global保存其数据,它的数据是保存在Demo.Patient的Global中的。
这个对象模型很容易理解,以对象方式在InterSystems IRIS/Caché里也很容易操作数据。但SQL的二维表无法表达这样稍微复杂一点的模型,因此需要将患者的地址投射为一张地址表,并用主外键将地址表和患者表的记录关联起来。
上面的患者对象模型中Addresses属性的SQLPROJECTION和STORAGEDEFAULT参数就是将属性Addresses投射为一张SQL表。
编译后,这个患者对象模型,在SQL上会投射出两张表:患者表:Demo.Patient地址表:Demo.Patient_Addresses注意:SQL表Demo.Patient_Addresses并不是由对象类Demo.Address投射而来,它是由对象类Patient的列表类型的属性Addresses投射而来。对象类Demo.Address是序列化类,它并不会投射SQL表。
执行SQL查询
SELECT CC.SqlQualifiedNameQ as SQLTable, CS.parent as Class, CS.DataLocation
FROM %Dictionary.CompiledStorage CS, %Dictionary.CompiledClass CC
WHERE CS.parent = CC.ID
AND CC.SqlSchemaName= 'Demo'
将返回类似如下结果:
SQLTable
Class
DataLocation
Demo.Patient
Demo.Patient
^Demo.PatientD
Demo.Patient_Addresses
Demo.Patient
注意:SQL表Demo.Patient_Addresses并没有对应的Global,因为它的数据是保存在Patient的Global里的。
这时可以使用以下SQL查询获取SQL表Demo.Patient_Addresses对应的Global和下标:
SELECT CC.ID||'_'||CSD.Attribute as SQLTable, CS.parent as Class, CS.DataLocation, CSD.Structure, CSD.Subscript
FROM %Dictionary.CompiledStorage CS, %Dictionary.CompiledClass CC, %Dictionary.CompiledStorageData CSD
WHERE CS.parent = CC.Name
AND CS.ID1 = CSD.parent
AND CC.SqlSchemaName= 'Demo'
AND CC.ID||CSD.Attribute in (select parent from %Dictionary.CompiledStorage where DataLocation is null)
它返回类似如下结果:
SQLTable
Class
DataLocation
Structure
Subscript
Demo.Patient_Addresses
Demo.Patient
^Demo.PatientD
subnode
“Addresses”
这说明SQL表Demo.Patient_Addresses的数据放在Global ^Demo.PatientD的下标为"Addresses"的子节点下。所以对Global节点 ^Demo.PatientD(“Addresses”)的数据变更就是对SQL表Demo.Patient_Addresses的数据变更。
类似的,当创建对象模型的父子关系时,父子关系子方的数据可以保存在父方的Global中。如以下模型:患者模型
Class Demo.Patient Extends %Persistent
{
Property Name As %String;
Property Gender As %String;
Property DOB As %Date;
Property Addresses As list Of Demo.Address(SQLPROJECTION = "table", STORAGEDEFAULT = "array");
Relationship Encounters As Demo.Encounter [ Cardinality = children, Inverse = Patient ];
}
就诊模型,它和患者模型是父子关系
Class Demo.Encounter Extends %Persistent
{
Property EncounterNo As %String;
Property VisitDate As %Date;
Relationship Patient As Demo.Patient [ Cardinality = parent, Inverse = Encounters ];
}
执行SQL查询
SELECT CC.SqlQualifiedNameQ as SQLTable, CS.parent as Class, CS.DataLocation
FROM %Dictionary.CompiledStorage CS, %Dictionary.CompiledClass CC
WHERE CS.parent = CC.ID
AND CC.SqlSchemaName= 'Demo'
将返回类似如下结果:
SQLTable
Class
DataLocation
Demo.Encounter
Demo.Encounter
{%%PARENT}(“Encounters”)
Demo.Patient
Demo.Patient
^Demo.PatientD
Demo.Patient_Addresses
Demo.PatientAddresses
这说明SQL表Demo.Encounter的数据放在Global ^Demo.PatientD的下标为" Encounters"的子节点下。所以对Global ^Demo.PatientD(“Encounters”)的数据变更就是对SQL表Demo.Encounter的数据变更。
3. 基于Global建模
直接基于Global建模并不常见。如果是直接基于Global建模的,可以在Global模型的基础上再建立对象模型,这样数据不仅可以使用多维数组方式操作,也可以通过对象和SQL方式操作。
这种情况下的对象模型,使用的Storage 类型在Caché里为%CacheSQLStorage,在InterSystems IRIS里为%Storage.SQL。
例如如下使用%CacheSQLStorage的Caché对象类Demo.Department:
Class Demo.Department Extends %Persistent [ StorageStrategy = SQLStorage ]
{
Property Id As %Integer;
Property Name As %String;
Property Parent As Demo.Department;
Index MyId On Id [ IdKey ];
Storage SQLStorage
{
<SQLMap name="DataMap">
<Data name="Id">
<Delimiter>"^"</Delimiter>
<Node>"id"</Node>
<Piece>1</Piece>
</Data>
<Data name="Name">
<Delimiter>"^"</Delimiter>
<Node>"Name"</Node>
<Piece>1</Piece>
</Data>
<Data name="Parent">
<Delimiter>"^"</Delimiter>
<Node>"Parent"</Node>
<Piece>1</Piece>
</Data>
<Global>^MyDepartment</Global>
<RowIdSpec name="1">
<Field>Id</Field>
</RowIdSpec>
<Subscript name="1">
<Expression>{Id}</Expression>
</Subscript>
<Subscript name="2">
<Expression>"Dep"</Expression>
</Subscript>
<Type>data</Type>
</SQLMap>
<StreamLocation>^Demo.DepartmentS</StreamLocation>
<Type>%CacheSQLStorage</Type>
}
}
对于这种使用%CacheSQLStorage或%Storage.SQL的对象类所投射出的SQL表,可以使用以下SQL查询获取SQL表对应的Global和下标:
SELECT CC.SqlQualifiedNameQ as sqltable,
CC.id as class, CSM._Global as DataLocation, CSM.Structure, CSMS.Name as subscript,CSMS.Expression
FROM %Dictionary.CompiledStorage CS,
%Dictionary.CompiledClass CC,
%Dictionary.CompiledStorageSQLMap CSM,
%Dictionary.CompiledStorageSQLMapSub CSMS
WHERE CS.parent = CC.ID
AND CS.ID1 = CSM.parent
AND CSM.ID = CSMS.parent
AND CSM.Type='data'
AND CC.SqlSchemaName= <schemaname>
其中<schemaname>是SQL的Schema名称。它返回类似如下结果:
SQLTable
Class
DataLocation
Structure
Subscript
Expression
Demo.Department
Demo.Department
^MyDepartment
1
{Id}
Demo.Department
Demo.Department
^MyDepartment
2
“Dep”
说明SQL表Demo.Department的数据保存在^MyDepartment 中,并且放在2个下标下,第一维下标为Id字段,第二维下标为字符串常量"Dep"。
这时,可以通过^MyDepartment的第一维下标(字段Id)值,执行SQL语句获取变更的整条记录:
SELECT * FROM Demo.Department WHERE id=?
使用%CacheSQLStorage/%Storage.SQL为Storage类型的InterSystems IRIS/Caché对象类,其Global模型可以任意灵活,而且不影响对象操作和SQL操作。但这也提高了将Global变更对应到SQL表的难度。
总结
通过上面的分析,如果要从InterSystems IRIS/Caché中通过SQL方式分析数据变更,需要先了解其建模方式,分析Global对应SQL表的关系。可以建立一张SQL表,存储分析得到的Global及下标和SQL表对应关系。当通过Dejournal filter发现global数据变更时,查询该SQL表,将数据变更表达为对应SQL表和对应记录(RowID),从而使用SQL获取完整的变化记录。
其它注意事项:流类型的属性/字段,通常保存在名为S的Global内,因此这些Global的数据更新也应该捕获并转换为对应SQL表的数据变更记录。
CDC系列
更多的CDC选项实现,请参考:
1. CDC系列之一 :使用Dejournal Filter在InterSystems IRIS/Caché上通过Mirroring实现CDC功能
2. CDC系列之二 :使用Dejournaling filter routine在Caché上通过Shadow实现CDC
3. CDC系列之三 :建立InterSystems IRIS/Caché的Global数据变更与SQL表记录的对应关系
4. CDC系列之四:使用DSTIME特性在InterSystems IRIS/Caché上实现CDC功能
公告
Claire Zheng · 七月 30, 2021
亲爱的社区开发者们,大家好!
我们真诚邀请您参加 Online Meetup:InterSystems 开发者竞赛(人工智能与机器学习)!
时间: 2021年7月30日(周五) 11:00 AM (美东时间)23:00 (北京时间)
在这场在线Meetup,您将了解到:
此次优胜者的个人履历;
获奖Application的简短Demo;
有关应用技术的开放探讨、问答,以及下次竞赛的一些计划。
我们的发言人名单:
@José.Pereira, BI开发者,Shift Consultoria e Sistemas Ltda
@Henrique, 系统管理专员/数据库管理员, Sao Paulo Federal Court
@Oleh.Dontsov, 全栈开发工程,Tax Sketches SRO
@Aleksandr.Kalinin6636, 工程师, LLC "Escape"
@Renato.Banzai, 机器学习工程师,Itaú Unibanco
@Evgeny.Shvarov, InterSystems 开发者生态经理(Developer Ecosystem Manager)
@tomd, InterSystems 产品专家(机器学习)
@Raj.Singh5479, InterSystems 产品经理( 开发者体验)
@Robert.Kuszewski, InterSystems 产品经理( 开发者体验)
欢迎您在这个特别的会议上与我们的开发人员沟通、交流!
➡️ 注册参会!
公告
Claire Zheng · 八月 28, 2023
SUTA培训是InterSystems专为SUTA有效期客户提供的原厂产品技术服务,具体包括产品的基础管理、编程管理、高级管理和开发培训等。2023 SUTA培训报名现已启动,汇聚技术专家,与新老客户一起探讨提升InterSystems数据平台基础管理运维的技能和知识:
新客户:系统学习管理运维工作的整体架构和基础概念
老客户:更加深入和全面地加强对管理运维工作的理解和提升
常见运维问题解析:助力您轻松应对日常工作中的问题和挑战
现场互动答疑:体验InterSystems技术专家的一对一诊断指导
点击此处,了解培训详情,报名参会(扫描下图中的二维码报名)。请关注InterSystems微信公众号,及时获取开播信息。
快来报名吧!
问题
j ay · 三月 22, 2023
1、java如何连接cache2016数据库
2、java如何调用cache的函数
"Backup.General", "ExternalFreeze", Using the JDBC Driver | Using Java with InterSystems Software | InterSystems IRIS for Health 2023.1请参阅这个文档来使用jdbc 链接cache 数据库,
Native SDK for Java | InterSystems IRIS for Health 2023.1 如果要调用任何的 cache 服务器端的代码,可以使用Native SDK for Java 使用方法请参阅上面的文档 public static void main(String[] args) {
EventPersister xep = null;
try {
// 1. 创建XEP持久化实例并连接
xep = PersisterFactory.createPersister();
xep.connect("ip", 1972, "%SYS", "cache", "cache");
Object result = xep.callClassMethod("SYS.Mirror", "RemoveMirroredDatabase", "worker");
// 4. 输出结果
System.out.println("备份操作结果: " + result);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 5. 关闭连接
if (xep != null) {
try {
xep.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
文章
姚 鑫 · 九月 25, 2022
# 第四十三章 使用多个 IRIS 实例(三)
# `Windows` 上的 `iris` 命令
在 `Windows` 上,必须从 `install-dir\bin` 目录运行 `iris` 命令(或在命令中包含完整路径)。
- `iris all` 列出所有已安装实例的摘要信息,每行一个实例,如下所述。
注意:如果需要完整的信息,例如用于解析或报告目的,请使用 `iris list`。
```java
C:\InterSystems\IRISHealth\bin>iris all
Instance Version ID Port Directory
------------- ---------- ---- ---------
up irishealth 2022.1.0.114.0 51773 c:\intersystems\irishealth
```
- `iris allw` 为每个实例列出与 `iris all` 相同的信息,而不包含长字段值。可能会产生超过 `80` 个字符的行。
```java
C:\InterSystems\IRISHealth\bin>iris allw
Instance Name Version ID Port Directory
------------------------------- ---------------------------- ----- --------------------------------
up irishealth 2022.1.0.114.0 51773 c:\intersystems\irishealth
```
- `iris console instname [arguments]` 在操作系统命令窗口而不是终端窗口中打开 `Terminal` 。

- `iris force instname` 强制关闭实例。
- `iris help` 显示有关 `iris` 命令的最新信息。
```java
C:\InterSystems\IRISHealth\bin>iris help
usage:
iris start []
to start instance , optionally using the specified .cpf file.
An optional /EmergencyId=Username,Password can be used to start
InterSystems IRIS in emergency mode. When the EmergencyId argument
is supplied, the system starts up in emergency mode in which only the
baseline databases are mounted and access to InterSystems IRIS is
governed by InterSystems IRIS login using that username and password.
Emergency mode is supplied to give access in the event that privileged
users are not available or their password is forgotten. Emergency
startup is only available from an administrator account.
When InterSystems IRIS is started in emergency mode, the IRIS control
service is not used. This means that if you log out of Windows, all
the InterSystems IRIS processes will immediately exit.
or: iris startnostu
to start instance without running ^STU.
or: iris stop
to shut down instance .
or: iris stopnoshut
to shut down instance without running user shutdown routines.
or: iris stopstart
to shut down and restart instance .
Note: An optional /nofailover argument can be specified for stop,
stopnoshut, or stopstart to not trigger a mirror failover.
or: iris force
to force down instance .
or: iris [ run OR console OR terminal ]
to run InterSystems IRIS in programmer mode with
[ no-device OR console OR terminal ] for $Principal.
or: iris [ run OR console OR terminal ]
to run InterSystems IRIS routine in application mode with
[ no-device OR console OR terminal ] for $Principal.
or: iris [ run OR console OR terminal ]
to run InterSystems IRIS routine in in application
mode with [ no-device OR console OR terminal ] for $Principal.
or: iris runw []
to run InterSystems IRIS routine in application mode with
no input/output device for $Principal using the optional namespace.
When run from a batch script, iris will wait for the InterSystems IRIS
process to terminate before returning. The exit code from the InterSystems
IRIS process will be returned by iris.
Note: An optional /Title="Title string" can specify the console
or terminal title bar text.
or: iris iristraystart
to start IRISTray for instance .
or: iris iristraystop
to stop IRISTray for instance .
or: iris licmanagerstop
to stop licmanager running in instance .
or: iris all [> outputfile]
to list all installed instances.
or: iris allw [> outputfile]
to list (wide format) all installed instances.
or: iris list [] [> outputfile]
to list information about all installed instances or the
specified instance.
or: iris qlist [] [> outputfile]
to display a quick list of information about all installed
instances or the specified instance, in a format suitable
for parsing in command scripts.
The record for an instance contains fields separated by "^" (carats):
Field 1: instance name
Field 2: instance directory
Field 3: version identifier
Field 4: current status for the instance
Field 5: configuration file name last used
Field 6: SuperServer port number
Field 7: WebServer port number
Field 8: JDBC Gateway port number
Field 9: Instance status (e.g., ok, warn, alert)
Field 10: Product name of the instance
Field 11: Mirror Member Type (e.g., Failover, Disaster Recovery)
Field 12: Mirror Status (e.g., Primary, Backup, Connected)
or: iris serverlist [> outputfile]
to list information about all defined servers.
Note: When [> outputfile] is present, output is redirected
to the file instead of being displayed on the terminal.
or: iris telnetstop
to stop the InterSystems IRIS TELNET daemon.
or: iris telnettrace
to toggle the TELNET trace state.
or: iris iristrmdstop
to stop the InterSystems IRIS terminal daemon.
Note: iris often displays error information in a message box.
You can suppress the message box containing error information
by adding "quietly" (without the quotation marks) as the
final argument to the iris command.
or: iris help [display]
to show this help. If display is specified the help
is displayed in a browser window.
```
- `iris list [arguments]` 显示有关已安装 `IRIS` 实例的信息,如下所述。
```java
C:\InterSystems\IRISHealth\bin>iris list irishealth
Instance 'irishealth' (Custom installation)
directory: 'C:\InterSystems\IRISHealth'
versionid: '2022.1.0.114.0'
conf file: 'c:\intersystems\irishealth\iris.cpf' (SuperServer port = 51773, WebServer port = 52773)
status : 'running, since Mon Sep 12 08:08:58 2022'
Product : InterSystems IRISHealth
```
`instname` — 可以选择指定 `IRIS` 实例名称以仅显示有关该实例的信息。例如,`iris list MyIRIS` 仅显示有关 `MyIRIS` 实例的信息。
- `iris qlist [参数]` 与 `iris list` 类似,但有附加信息。每个实例的输出(如下所述)在一行中给出,字段由插入符号 (`^`) 分隔。
`instname` — 可以选择指定 `IRIS` 实例名称以仅显示有关该实例的信息。例如,`iris qlist MyIRIS` 仅显示有关 `MyIRIS` 实例的信息。
```java
C:\InterSystems\IRISHealth\bin>iris qlist irishealth
irishealth^C:\InterSystems\IRISHealth^2022.1.0.114.0^running, since Mon Sep 12 08:08:58 2022^c:\intersystems\irishealth\iris.cpf^51773^52773^^^IRISHealth^^
```
- `iris run instname [arguments]` 在没有 `$Principal` 的输入/输出设备的程序员模式下运行 IRIS。
- `iris runw instname 例程 [参数]` 在应用程序模式下运行命名的 `IRIS` 例程,没有 `$Principal` 的输入/输出设备。从批处理脚本运行时,该命令会等待 `IRIS` 进程终止,然后再从进程返回退出代码。
`namespace` — 在指定的命名空间中运行例程。
注意:如果使用指定了启动命名空间的用户帐户启动 `IRIS`,则命名空间参数无效(请参阅用户帐户属性)。
- `iris start instname [参数]` 启动实例。
注意:系统可能会提示以“紧急模式”启动。
完整的 `CPF` 路径 — 默认情况下, `IRIS` 从位于 `<install-dir>/mgr` 目录中的 `iris.cpf` 文件中读取某些设置。可以提供另一个 `.cpf` 文件的完整路径以供使用。
- `iris startnostu instname` 启动指定的实例而不运行`^STU`。
- `iris stop instname [参数]` 关闭实例。
`/nofailover` — 指定此可选参数以防止触发镜像故障转移。
- `iris stopnoshut instname [参数]` 使用 `INTNOSHUT^SHUTDOWN` 关闭命名实例。
**注意:只有实例所有者和 `irisusr` 可以在不登录终端的情况下运行 `INTNOSHUT^SHUTDOWN`。**
`/nofailover` — 指定此可选参数以防止触发镜像故障转移。
- `iris stopstart instname [参数]` 关闭实例后启动它。
`/nofailover` — 指定此可选参数以防止触发镜像故障转移。
- `iris terminal instname [参数]` 打开实例的 `Terminal` 。
`routine` — 在终端中以应用程序模式为 `$Principal` 运行命名的 `IRIS` 例程。 `"[label[+offset]]^routine"` — 指定要在用户模式下运行的 `ObjectScript` 程序的名称。除了指定的格式之外,还可以传递由字符串和`/`或数字文字组成的参数列表,以及省略的 (`void`) 参数,如下所示:
- `"routine[([parameter-list])]"`
- `"[label]^routine[([parameter-list])]"`
- `"##CLASS(package.class).method[([parameter-list])]"`
其中,例如,参数列表以“`string literal`”的形式指定,`-+-000123.45600E+07`,省略的参数作为 `$Data(parameter)=0` 传递给目标。
注意:空格和 `shell` 元字符必须以依赖于操作系统的形式引用。
命名空间 — 与例程一起使用,在指定的命名空间中运行例程。
注意:如果您用指定了启动命名空间的用户帐户启动 `IRIS`,则命名空间无效(请参阅用户帐户属性)。
## iris list, qlist, and all
#### `iris all`
列出有关一个或多个 `IRIS` 实例的以下信息:
- 实例状态,如下
- ``(状态不可用,登录已禁用)
- `dn`(关闭或已崩溃)
- `up` (running)
- `st` (starting or stopping)
- 实例名称
- `IRIS` 版本
- 超级服务器端口号
- 安装目录
#### `iris list`
列出有关一个或多个 `IRIS` 实例的以下信息:
- 实例名称(和安装类型)
- 安装目录
- `IRIS` 版本
- `IRIS` 参数 (`.cpf`) 文件的路径名
- 超级服务器和网络服务器端口号
- 实例状态,如下
- `running`
- `down`
- `starting or stopping`
- 不完整的启动或停止,登录被禁用
- 实例的系统健康状态,如果正在运行(不包括在 `Windows` 中)
- 镜像成员类型和状态(如果是镜像成员)
#### iris qlist
为一个或多个 `IRIS` 实例在单行上输出以下信息,以插入符号 (`^`) 分隔:
1. 实例名称(和安装类型)
2. 安装目录
3. `IRIS`版本
4. 实例状态
5. 当前配置参数文件的路径名,相对于安装目录。 `Windows` 系统改为显示完整路径。
6. 超级服务器端口号
7. 网络服务器端口号
8. `JDBC` 网关端口号
9. 实例的系统健康状态,如果正在运行(在 `Windows` 上总是空白)
10. 产品名称
11. 镜像成员类型(如果是镜像成员)
12. 镜像状态(如果是镜像成员)
13. 数据目录(如果适用)
文章
姚 鑫 · 十一月 28, 2024
# 第三十五章 终端输入 输出 - 特殊变量显示 I O 条件
# WRITE * and $X and $Y
`WRITE *`不会更改`$X`和`$Y `。因此,可以将控制序列发送到终端, `$X`和`$Y`仍将反映真实的光标位置。某些控制序列确实会移动光标,因此可以在需要时直接设置`$X`或`$Y` 。
# `$X` 和 `$Y` 示例
在以下示例中,控制序列将 `VT100` 终端中的光标移动到第 `10` 行、第 `20` 列,并相应地设置`$X`和`$Y` 。
```java
; set DY and DX to desired
; values for $Y and $X
SET DY=10
SET DX=20
; ...
; escape sequence moves
; cursor to desired position
WRITE *27, *91, DY+1, *59, DX+1, *72
; ...
; updates $X and $Y
SET $Y=DY
SET $X=DX
```
# 转义序列对 `$X` 和 `$Y`的影响各不相同
转义序列可以改变`$X`和`$Y`值上的回显效果。三个因素控制着这种影响:
- 操作系统,设置默认行为。
- 是否在`OPEN`或`USE`命令中指定了 `/NOXY`(禁用`$X`和`$Y`处理)。
- 可以使用`%SYSTEM.Process`类的 `DX()` 方法来设置`$X`如何处理当前进程的转义序列。可以通过类中设置 `Config.Miscellaneous`的 `DX` 属性来建立系统范围的默认行为。
# 转义序列影响 `Windows` 和 `UNIX®` 系统上的 `$X` 和 `$Y`
默认情况下,在 `UNIX®` 和 `Windows` 上,当写入或回显任何包含 `ASCII` 转义字符(十进制值 `27`)的字符串时, `IRIS` 会更新`$X`和`$Y`,就像更新任何其他字符序列一样。因此,终端执行但不显示的 `ANSI` 标准控制序列可能会打乱$X和$Y与光标位置的关系。
避免此问题的最简单方法是使用`DX()`方法来更改行为(请参阅下一节)。或者,可以在`WRITE *`语句中使用字符串中每个字符的 `ASCII` 值。
# 控制序列示例
而不是使用代码:
```java
%SYS>WRITE $CHAR(27)_"[lm"
```
可以使用以下不更新`$X`和`$Y` 的等效语句:
```java
%SYS>WRITE *27,*91,*49,*109
```
文章
Claire Zheng · 七月 22, 2022
这是一个帖子合集,方便你快速了解关于开发者社区的各种积分福利和玩儿法!
刚刚接触开发者社区er
1. 欢迎欢迎✿✿ヽ(°▽°)ノ✿!InterSystems 开发者社区欢迎您!
2. 遵守社区行为准则很重要 InterSystems开发者社区行为准则
社区福利区-Global Master
1. 认识Global Masters 倡导中心,从这里开始!
2. 如何在 InterSystems Global Masters倡导中心获得积分
3. Global Masters: 在中文社区贡献可以获得超高积分
4. Global Masters的成员们,即日起在社区发布帖子和译文贴可获得两倍积分!
5. 社区福利持续更新中!来Global Masters,赢取Apple AirPods,Amazon Echo Dot,解锁更多奖品
6. Global Masters_ Open Exchange 应用市场上每个 ZPM 应用程序的奖励积分
7. Global Masters 奖励计划:1.5 小时的 InterSystems 专家咨询
8. 探索之夏——来开发者社区提问,获取双倍积分!
社区基本技能-搜索&关注
1. 如何更好地搜索开发者社区?
2. 如何在InterSystems开发者社区学习?第一部分:玩转“关注”
3. 如何在InterSystems开发者社区学习?第二部分:标签(Tags)
社区基本技能-发帖
1. 技能帖:更好地利用开发者社区的发帖功能!
2. 如何发帖以及其他常见问题解答
3. 如何在开发者社区上发布包含代码的帖子?
4. 如何从 Word 或 Google Docs 发布文章
5. 如何在帖子中突出显示 ObjectScript?
6. (给自己赚更多积分、换iPods)如何在其他开发者社区翻译并发布帖子
7. 如何在发帖时嵌入视频
社区基本技能-提问
1. 如何在开发者社区上发布同类最佳的问题?
社区高级技能-参赛
开发者社区会定期举办技术大赛,欢迎积极参赛!
参赛者需要在Open Exchange上发布程序以提交参赛作品,那么这两篇是必读:
1. 如何把参赛APP提交给大赛
2. 如何在 InterSystems Open Exchange 应用市场上发布应用程序?
提交作品后,社区投票是非常重要的获奖依据,那么这篇是必读:
1. 投票必读:如何成为社区活跃用户(Active user)
2. 如何更好地成为社区贡献者/活跃用户?
开发者社区服务
1. 如何在开发者生态系统的各类资源中修改您的主邮箱(Primary Email Address)?
2. InterSystems开发者社区新增“工作”版块
3. 畅聊吧!来Discord加入InterSystems开发者社区!
4. 如何查看自己的发帖表现
5. 如何将 InterSystems 认证添加到您的社区资料(Profile)中?
如果有疑问,欢迎跟帖提问!
文章
Claire Zheng · 八月 17, 2021
回过头来,业务场景都是千人千面的, FHIR怎么能够用一个标准涵盖尽可能多的用例?HL7吸收了V3的教训,在V3里面不成功的、或者说采纳度比较低的一个原因就V3试图穷举所有用例,由HL7组织自己来规范这些用例。这个是蛮沉重的教训,这也是V3的方法论虽然好,但是这套实施的路线在国际上有很大障碍的原因。
HL7已经不试图再自己穷举所有用例开发标准。它在FHIR的标准开发上,使用的是80/20原则。80/20的原则就是它自己专注在80%的业务都需要的那些数据部分上,其它20%交给使用者自己去进行相应的扩展,也就说它有很好的扩展性。
FHIR到底怎么来进行扩展?FHIR可以对模型、值集、API进行扩展,并且进一步的进行约束。而这些扩展本身也是资源,因此扩展可以像其它资源一样被创建、被访问、被交换。
怎么把你的扩展告诉别人?
在HL7 V2年代扩展很容易做,用z字段就可以来做扩展。但是你自己做的扩展约束需要通过文档和人工沟通的方式跟对方来进行人工沟通,告诉人家你是怎么扩展的,你是怎么约束的,你是怎么计划使用HL7消息。
而FHIR是通过Profile(规范)来进行约束和扩展表达的。将你做的扩展和约束与被扩展和约束的资源通过Profile(规范)来进行关联,然后注册这些Profile(规范),让别人能够找到。对方的技术系统只要通过你发给他的这些约束和扩展过的资源里面所标记的Profile的URL,就可以来得到获取并够解析Profile(规范),这样就能够理解你所做的约束和扩展,实现机器可读。这是FHIR跟之前标准在扩展模式上非常大的区别。
另外因为涉及到了用例,通常Profile(规范)是级联的。先按国家和地区的通用用例来建立一个区域级的、一个大的、有共性的Profile(规范),然后区域内的医疗机构可以以此为基础来创建自己下一级的Profile(规范),自己可能有一些扩展——例如说梅奥诊所,它可以基于美国的核心的Profile(规范)、扩展过的患者的资源上,来进行自己的一些患者信息扩展——这种级联扩展方式能够保证最大程度的互操作能力,即在同一个区域里面的所有机构,都共享一个通用的资源,可以保证互操作能力的最大化实现。
另外一个概念就是实施指南(Implementation Guides)。FHIR本身是一个平台规范,它本身关注在能力建设和生态建设上,这意味着广大的用户可以基于FHIR来开发出不同的解决方案。而实施指南就是说明如何使用FHIR的资源和能力来构建解决方案的。
注意区别Profile(规范)与FHIR的实施指南(Implementation Guide)。FHIR实施指南(Implementation Guide)相当于是什么?相当于经线,描述的是针对业务场景所需要的使用的方法;而Profile(规范)相当于是纬线,描述的是应用场景所需要的标准本身。HL7组织提供了一个实施指南注册的一个网站,大家都可以将自己的用例的实施指南注册在上面,所有人都可以看到、获取、利用、学习它。
上图是我把网站上列出来的所有注册的实施指南做的一个汇总。从这张汇总出来的实施指南的统计图来看,它涉及的业务场景是非常广泛的,包括了电子病历访问、管理、公卫、财务等等,这也说明了FHIR资源的覆盖面其实非常广,它可以覆盖从临床、管理、财务、设备、组学等方方面面。
FHIR还有生态。HL7设计FHIR初衷就是让它成为一个生态的标准,围绕着FHIR其实已经有一个不断扩大的生态圈。这里面列出来一些包括刚才我们提到的SMART on FHIR。
注:本文根据InterSystems中国技术总监乔鹏演讲整理而成。
公告
Michael Lei · 一月 21
InterSystems 已更正导致在使用特定 $LIST 语法时引入无效数据库和日志记录的缺陷。 遇到此缺陷的可能性非常低,但它对操作的影响可能会很大。
受影响的产品
InterSystems IRIS® 数据平台:2023.3、2024.1.0、2024.1.1、2024.1.2、2024.2、2024.3 版
InterSystems IRIS® for Health:2023.3、2024.1.0、2024.1.1、2024.1.2、2024.2、2024.3 版
HealthShare® Health Connect:2023.3.0、2024.1、2024.1.1、2024.1.2、2024.2、2024.3 版
HealthShare® Unified Care Record and Suite:2024.2 版
基于上述产品的所有产品组合
该问题仅影响 Unicode 安装。
使用以下语法在 global 中向列表附加新元素时,会出现此问题:
SET $LIST(<global reference>, *+1) = value.
当此调用的结果列表超出最大字符串长度时,正确的行为是返回 <MAXSTRING> 错误。此错误会出现在 InterSystems IRIS、InterSystems IRIS for Health 和 Health Connect 2023.3 之前的版本中。 在 2023.3 及后续版本中,无效值会保存到数据库而不是生成 <MAXSTRING> 错误.
任何后续引用 global 节点的尝试都会导致出现 <MAXSTRING> 错误。
global 更新也会产生日志记录(假设对此 global 的更新通常都会记录)。任何尝试应用生成的日志记录(包括启动时恢复、日志恢复和镜像操作)都会失败并出现 <MAXSTRING> 错误,同时停止对日志文件的进一步处理。
如果此缺陷给您带来了影响,请联系全球响应中心 (WRC) 寻求帮助。
此缺陷的更正标识为 DP-437169 。在从 InterSystems IRIS、InterSystems IRIS for Health 和 Health Connect 2024.1.3 与 2025.1.0 开始的未来所有版本中,都将包含此更正。 您也可以通过临时分发获取。 HealthShare Unified Care Record 2025.1 版与产品套件会在发布时包含该更正,但在先前版本的维护版中将不包含该更正。 如果您对此提醒有任何疑问,请联系全球响应中心。