搜索​​​​

清除过滤器
文章
姚 鑫 · 四月 3, 2021

第十五章 使用管理门户SQL接口(二)

# 第十五章 使用管理门户SQL接口(二) # 过滤模式内容 Management Portal SQL界面的左侧允许查看模式(或匹配筛选器模式的多个模式)的内容 1. 通过单击SQL interface页面顶部的Switch选项,指定希望使用的名称空间。 这将显示可用名称空间的列表,可以从中进行选择。 2. 应用筛选器或从模式下拉列表中选择模式。 可以使用Filter字段通过输入搜索模式来筛选列表。 可以在一个模式或多个模式中筛选模式,或筛选表/视图/过程名(项)。 搜索模式由模式名、点(`.`)和项目名组成——每个名称由文字和通配符的某种组合组成。字面值不区分大小写。 通配符是: - 星号(`*`)表示0个或多个任意类型的字符。 - 下划线(`_`)表示任意类型的单个字符。 - 撇号(`'`)倒装前缀,意为“不”(除了)。 - 反斜杠(`\`)转义字符:`\_`表示字面上的下划线字符。 例如,`S*`返回所有以`S S*`开头的模式。 `Person`返回所有以`S. *`开头的模式中的所有Person项。 `Person*`返回所有模式中以`Person开头`的所有项。 可以使用逗号分隔的搜索模式列表来选择满足所列模式(或逻辑)中的任何一种的所有项。 例如,`* .Person * *`。 `Employee*`选择所有模式中的所有Person和Employee项。 若要应用筛选器搜索模式,请单击refresh按钮或按Tab键。 过滤器搜索模式将一直有效,直到显式地更改它。 过滤器字段右侧的`“x”`按钮清除搜索模式。 3. 从schema下拉列表中选择一个模式将覆盖并重置之前的任何筛选器搜索模式,选择单个模式。 指定筛选器搜索模式将覆盖之前的任何模式。 4. 可选地,使用下拉“应用到”列表来指定要列出的项目类别:表、视图、过程、缓存查询,或以上所有。 默认为`All`。 在“应用到”下拉列表中指定的任何类别都受到筛选器或模式的限制。 在“应用到”中没有指定的类别继续在名称空间中列出该类别类型的所有项。 5. 可选地,单击System复选框以包含系统项目(名称以`%`开头的项目)。 默认情况下不包含系统项。 6. 展开类别的列表,列出指定架构或指定筛选器搜索模式的项。 展开列表时,不包含项的任何类别都不会展开。 7. 单击展开列表中的项,在SQL界面的右侧显示其目录详细信息。 如果所选项目是表或过程,则Catalog Details类名信息提供到相应类参考文档的链接。 请注意,筛选器设置是用户自定义的,并保留以供该用户将来使用。 ## Browse选项卡 Browse选项卡提供了一种方便的方式,可以快速查看名称空间中的所有模式,或者名称空间中经过过滤的模式子集。 可以选择Show All Schemas或Show Schemas with Filter,这将应用在管理门户SQL界面左侧指定的过滤器。 通过单击模式名称标题,可以按字母升序或降序列出模式。 每个列出的模式都提供指向其关联表、视图、过程和查询(缓存的查询)列表的链接。 如果模式没有该类型的项,则在该模式列表列中显示一个连字符(而不是命名链接)。 这使能够快速获得关于模式内容的信息。 单击“表”、“视图”、“过程”或“查询”链接将显示有关这些项的基本信息的表。 通过单击表标题,可以按该列的值升序或降序对列表进行排序。 过程表总是包括区段过程,而不管管理门户SQL界面左侧的过程设置如何。 可以使用Catalog Details选项卡获得关于单个表、视图、过程和缓存查询的更多信息。 从Browse选项卡中选择表或视图不会激活该表的`Open Table`链接。 # 目录详情 管理门户提供每个表,视图,过程和缓存查询的目录详细信息。管理门户SQL界面的过滤架构内容(左侧)组件允许您选择单个项目以显示其目录详细信息。 ## 目录表的详细信息 每个表提供以下目录详细信息选项: - 表信息:表类型:表类型:无论是表,全局临时或系统表(仅在选择系统复选框时显示系统表),所有者名称,最后编译的时间戳,外部和读取的布尔值,类名称,范围大小,子表的名称和/或父表(如果相关)和一个或多个引用字段到其他表(如果相关),无论是使用`%storage.persistent`默认存储类,无论是支持位图指标, `ROWID`字段名称,`ROWID`基于(如果相关)的字段列表,以及表是否被分析。如果有一个显式分片键,它会显示分片键字段。 类名是在Intersystems类参考文档中的相应条目的链接。类名是通过删除标点字符,如标识符和类实体名称中所述从表名派生的唯一包。 只有当当前表中的某个字段对另一个表有一个或多个引用时,引用才会出现在表信息中。 这些对其他表的引用作为指向所引用表的表信息的链接列出。 Sharded:如果表是一个分片主表,那么表信息将显示分片本地类和表的名称,并链接到InterSystems类参考文档中相应的条目。 如果该表是一个碎片本地表,表信息将显示碎片主类和表的名称,并链接到InterSystems类参考文档中相应的条目。 只有选中“System”复选框时,才会显示“Shard-local”表。 该选项还为打开表时要加载的行数提供了一个可修改的值。 这将设置打开表中显示的最大行数。 可用范围从1到10,000; 默认值为100。 管理门户将一个超出可用范围的值修正为一个有效值:0修正为100; 一个小数四舍五入到下一个更大的整数; 大于10,000的数字更正为10,000。 - 字段:表中字段的列表,显示字段名,数据类型,列#,必需的,惟一的,排序,隐藏,MaxLen, MaxVal, MinVal,流,容器,xDBC类型,引用,版本列,选择性,离群值选择性,离群值和平均字段大小。 - 映射/索引:为表定义的索引列表,显示:索引名、SQL映射名、列、类型、块计数、映射继承和全局。 索引名称是索引属性名称,然后遵循属性命名约定;从SQL索引名称生成时,将删除SQL索引名称中的标点符号(例如下划线)。 SQL映射名称是索引的SQL名称。生成的SQL映射名称与约束名称相同,并遵循相同的命名约定(下面描述)。列指定为索引指定的字段或逗号分隔的字段列表;它可以指定index collation类型和full schinea.table.field参考,如下例所示:`$$sqlupper({sample.people.name})`。类型可以是以下之一:位图范围,数据/主,索引(标准索引),位图或`bitslice`索引以及唯一的约束。块计数包含计数和该计数的确定:由Class Author(定义)明确地设置,由可调组织(测量)计算,或由类编译器(估计)估计。如果映射继承?是的,map是从超类继承的。全局是包含索引数据的下标全局的名称。索引全局的命名约定在索引全局名称中描述。您可以向ZWRITE提供此全局名称以显示索引数据。 此选项还为每个索引提供重建索引的链接。 - 触发:为表显示的触发器列表显示:触发名称,时间事件,订单,代码。 - 约束:表格的字段列表,显示:约束名称,约束类型和约束数据(括号中列出的字段名称)。约束包括主键,外键和唯一约束。主键是定义,唯一;它仅列出一次。此选项列出约束名称的约束;使用显示组件字段的逗号分隔列表的约束数据列出了一次涉及多个字段的约束。约束类型可以是唯一的主键,隐式主键,外键或隐式外键。 还可以通过调用`Information_schema.constraint_column_usage`来列出约束。此列表按字段名称约束。以下示例返回字段的名称和所有唯一,主键,外键和`Check Constraints`的约束的名称: ```sql SELECT Column_Name,Constraint_Name FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE WHERE TABLE_SCHEMA='Sample' AND TABLE_NAME='Person' ``` ![image](/sites/default/files/inline/images/1_28.png) 如果该表定义为`%PublicraWID`,并且没有定义显式主键,则`RowID`字段列出了具有约束名称`RowidField_As_PKey`的`Contriced`主键的约束类型。 对于显式约束,约束名称是如下生成的: - 字段定义中指定的约束:例如,`fullname varchar(48)`唯一或`fullname varchar(48)`主键。字段的约束名称值是具有语法`tableName_ctype#`的生成值,其中ctype是唯一的,`pkey`或`fkey`,`#`是在表定义中指定的顺序分配给未命名约束的顺序整数。例如,如果`FullName`具有`MyTest`表中的第二个未命名的唯一约束(不包括ID字段),则`FullName`的生成约束名称将是`mytest_unique2`;如果`fullname`是`MyTest`表中指定的主键和第3个未命名约束(不包括ID字段),则`FullName`的生成约束名称将是`MyTest_pKey3`。 - 约束关键字命名约束子句:例如,约束`UFULLNAME`唯一(名字,`LastName`)或约束`Pkname`主键(`FullName`)),约束名称是指定的唯一约束名称。例如,`MyTest`表中的名字和`LastName`每个都将每个约束名称`UfullName`; `fullname`将具有约束名称`pkname`。 - 未命名约束子句:例如,唯一(名字,姓氏)或主键(`FullName`)。约束名称值是具有语法`tableNamectype#`的生成值,其中`ctype`是唯一的,`pkey`或`fkey`,`##`是在表定义中指定的顺序分配给未命名约束的顺序整数。例如,如果`FirstName`和`LastName`具有`MyTest`表中的第2个未命名的唯一约束(不包括ID字段),则`FirstName`和`LastName`的生成约束名称将是`MyTestunique2`;如果`FullName`是`MyTest`表中指定的主要键和第3个未命名的约束(不包括ID字段),则`FullName`的生成约束名称将是`MyTestPKEY3`。 (注意混合大写/小写,没有下划线。) 如果一个字段涉及多个唯一约束,则为每个约束名称单独列出。 - 缓存查询:表的缓存查询列表显示:例程名称,查询文本,创建时间,源,查询类型。 - 表的SQL语句:为此表生成的SQL语句列表。与命名空间的SQL语句相同的信息。 ## 目录的视图详细信息 Management Portal SQL接口还提供视图,过程和缓存查询的目录详细信息: 为每个视图提供以下目录详细信息选项: - 查看信息:所有者名称,最后编译的时间戳。使用“编辑视图”链接并保存更改时,此时间戳更新。 定义为只读,视图是可更新的布尔值:如果仅读取的视图定义,则它们分别设置为1和0。否则,如果查看视图是从单个表定义的,它们被设置为0和1;如果视图由已加入的表定义,则它们设置为0和0。可以使用编辑视图链接更改此选项。 类名是唯一的包。通过删除标点字符,如标识符和类实体名称中所述,从视图名称派生的名称。 如果查看定义包含“使用”选项“子句,则仅列出选项。它可以是本地的或级联。您可以使用编辑视图链接更改此选项。 类类型是视图。它提供了编辑视图链接以编辑视图定义。 查看文本是用于定义视图的`SELECT`语句。可以使用编辑视图链接更改视图定义。 字段列表包括字段名称,数据类型,maxlen参数,maxval参数,minval参数,blob(`%stream.globalcharacter`或`%stream.globalbinary`字段),长度,精度和比例。 - 查看的SQL语句:为此视图生成的SQL语句列表。与命名空间的SQL语句相同的信息。 ## 存储过程的目录详细信息 为每个过程提供以下目录详细信息: - 存储过程信息: 类名是一个唯一的包。通过将类型标识符( `‘func’, ‘meth’, ‘proc’, or ‘query’`)预定到类名(例如,SQL函数`MyProc`变为`FuncMyProc`)并删除标点符号字符,如标识符和类实体名称中所述。类文档是Intersystems类参考中相应条目的链接。过程类型(例如,函数)。方法或查询名称生成的类方法或类查询的名称;此名称在标识符和类实体名称中描述。运行过程链接提供交互方式的选项。 - 存储过程SQL语句:为此存储过程生成的SQL语句列表。与命名空间的SQL语句相同的信息。 ## 缓存查询的目录详细信息 缓存查询提供查询的全文,一个选项来显示查询执行计划,以及交互式执行缓存查询的选项。 # 向导 - 数据导入向导 - 运行向导将数据从文本文件导入Intersystems Iris类。 - 数据导出向导 - 运行向导将数据从Intersystems Iris类导出到文本文件中。 - 数据迁移向导 - 运行向导以从外部源迁移数据,并创建一个Intersystems Iris类定义来存储它。 - 链接表向导 - 运行向导,以链接到外部源中的表或视图,就像它是本机Intersystems Iris数据一样。 - 链接过程向导 - 运行向导,以链接到外部源中的过程。 # 操作 - 创建视图 - 显示一个页面以创建视图。使用此选项的说明提供了本书的“定义和使用视图”章节。 - 打印目录 - 允许打印有关表定义的完整信息。单击打印目录显示打印预览。通过单击此打印预览上的指数,触发器和/或约束,可以从目录打印输出中包含或排除此信息。 - Purege缓存查询 - 提供三种用于清除缓存查询的选项:清除当前命名空间的所有缓存查询,清除指定表的所有缓存查询,或者仅清除所选缓存的查询。 - 调谐表信息 - 对选定的表运行调谐表工具。这计算了每个表列对当前数据的选择性。选择性值1表示定义为唯一(因此具有所有唯一数据值)的列。选择性值为`1.0000%`表示未定义所有当前数据值是唯一值的唯一列。 `1.0000%`的百分比值更大,指示当前数据中该列的重复值的相对数量。通过使用这些选择性值,可以确定要定义的索引以及如何使用这些索引来优化性能。 - 调整架构中的所有表 - 运行调谐表工具,针对所属于当前命名空间中指定架构的所有表。 - 重建表索引 - 重建指定表的所有索引。 - 删除此项目 - 删除(删除)指定的表定义,查看定义,过程或缓存查询。必须具有适当的权限来执行此操作。除非表类定义包括[`DDLOWALLED`],否则否则不能在通过定义持久性类创建的表上使用删除。否则,操作失败了,使用`SQLCode -300`错误,其中包含类`“Schema.TableName”`的`%MSG DDL`。如果相应的持久性类具有子类(派生类),则不能在表格上使用删除;使用`%msg`类`'schema.tableName'`具有派生类`SQLCode -300`错误失败,因此无法通过DDL删除。 如果一个类被定义为链接表,则下降操作也会将链接表放在本地系统上,即使链接的表类未被定义为ddlowed。下降不会删除实际表此链接引用服务器上的引用。 - 导出所有语句 - 将所有SQL语句导出在当前命名空间中。 SQL语句以XML格式导出。可以选择导出到文件,或导出到浏览器显示页面。 - 导入语句 - 将SQL语句从XML文件导入当前命名空间。 # 打开表 如果在管理门户SQL接口的左侧选择表或视图,则会显示该表或视图的目录详细信息。页面顶部的打开表链接也变为活动状态。打开表显示表中的实际数据(或通过视图访问)。数据以显示格式显示。 默认情况下,将显示前100行数据;通过在“目录详细信息”选项卡信息中将表打开时,通过设置要加载的行数来修改此默认值。如果表格中的行数多于此行到加载值,则在数据显示的底部显示越多的数据...指示器。如果表格中的行较少,则要加载值的行数,则在数据显示的底部显示完整的指示符。 一列数据类型`%Stream.globalcharacter`将实际数据(最多100个字符)显示为字符串。超出前100个字符的附加数据由省略号(`...`)表示。 一列数据类型`%Stream.Globalbinary`显示为。 # 工具 System Explorer,SQL,Tools下拉列表提供对以下工具的访问。这些是系统资源管理器,工具,SQL性能工具的相同工具: - SQL运行时统计信息:用户界面生成指定查询的SQL运行时统计信息。 - 索引分析仪:用于收集指定架构的各种类型索引分析的用户界面。 - 替代表演计划:用户界面生成指定查询的备用显示计划。 - 生成报告以将SQL查询性能报告提交给Intersystems WRC(全球响应中心客户支持)。要使用此报告工具,必须先从WRC获取WRC跟踪号码。 - 导入报告以通过文件名导入现有WRC报告。仅用于Intersystems使用。 ![image](/sites/default/files/inline/images/2_17.png)
文章
Frank Ma · 三月 2, 2022

如何以自动化方式/编程方式创建一个镜像环境

各位好, 你曾建立过一个镜像环境吗?它是否有一个私有网络、虚拟IP地址和SSL配置? 在做了几次之后,我意识到这是一个漫长的过程,而且需要很多手动操作来生成证书和配置每个IRIS实例。 对于经常要做这件事的人来说,这是一个痛苦的过程。 例如,质量保证团队可能需要为每个新的应用程序版本创建一个新的镜像环境来测试。支持团队可能需要创建一个镜像环境来重现一个复杂的问题。 我们肯定需要工具来快速创建这些镜像环境。 在这篇文章中,我们将用如下环境创建一个镜像样例: - 仲裁机 - 主服务器 - 故障切换备份成员 - 读写报告异步成员 - 节点间日志转移的SSL配置 - 镜像环境中的私有网络 - 虚拟IP地址 - 镜像数据库 ![network-schema](https://raw.githubusercontent.com/lscalese/iris-mirroring-samples/master/img/net-schema.png) 乍一看,它似乎有点复杂,看起来需要大量的代码,但不要担心。 在OpenExchange上有一些库,可以轻松地执行大多数操作。 本文的目的是提供一个例子,说明如何根据你的需要调整这个过程,但在安全问题上,它不是一个最佳实践指南。 现在,让我们来创建我们的样本。 ### 工具和库 - [PKI-script](https://openexchange.intersystems.com/package/PKI-Script): 公钥基础设施(PKI)是一个与IRIS集成的功能,它允许你生成一个自签名的证书并拥有你的授权服务器。在伟大的[Pete Greskoff的文章](https://community.intersystems.com/post/creating-ssl-enabled-mirror-intersystems-iris-using-public-key-infrastructure-pki)之后,PKI-script的目标是以编程方式执行所有操作,避免在管理门户中进行任何手动操作。 该库包括用于镜像的实用方法。 然而,如果你已经有了证书,你可以用它们来代替PKI-Script。 - [config-api](https://openexchange.intersystems.com/package/Config-API): 这个库将被用来配置IRIS。它从1.1.0版本开始支持镜像配置。我们将不对如何使用这个库进行详细描述。 [这里](https://community.intersystems.com/post/environment-setup-config-api) 已经有一组文章。简而言之,config-api将被用来创建IRIS模板配置文件(JSON格式)并轻松加载。 - [ZPM](https://openexchange.intersystems.com/package/ObjectScript-Package-Manager). - Docker. ### Github 页 你可以在[iris-mirroring-samples repository](https://github.com/lscalese/iris-mirroring-samples/)上找到所有必要的资源文件。 ### 准备你的系统 克隆现有的资源库: ```bash git clone https://github.com/lscalese/iris-mirroring-samples cd iris-mirroring-samples ``` 如果你喜欢从头开始创建一个样本,而不是克隆资源库,只需创建一个带有子目录的新目录: `backup` 和 `config-files`. 下载 [irissession.sh](https://raw.githubusercontent.com/lscalese/iris-mirroring-samples/master/session.sh) : ``` mkdir -p iris-mirroring-samples/backup iris-mirroring-samples/config-files cd iris-mirroring-samples wget -O session.sh https://raw.githubusercontent.com/lscalese/iris-mirroring-samples/master/session.sh ``` 为了避免以后出现 "权限拒绝 "的问题,我们需要创建`irisowner`组,`irisowner`用户,并将备份目录的组改为`irisowner`。 ```bash sudo useradd --uid 51773 --user-group irisowner sudo groupmod --gid 51773 irisowner sudo chgrp irisowner ./backup ``` 这个目录将被用作卷,在与其他节点建立第一个镜像成员后共享数据库备份。 ### 获得IRIS许可证 镜像在IRIS社区版中不可用。 如果你还没有有效的IRIS容器许可证,请用你的账户连接到 [全球响应中心(WRC)](https://wrc.intersystems.com)。 点击 "Actions" --> "SW distribtion", 然后点击 "Evaluations" 按钮并选择"Evaluation License"; 填写表单。 把你的许可证文件`iris.key`复制到这个目录。 ###登录Intersystems 容器注册中心(Containers Registry) 为了方便起见,我们使用Intersystems Containers Registry(ICR)来提取docker镜像。如果你不知道你的docker登录名/密码,只要用你的WRC账户连接到[SSO.UI.User.ApplicationTokens.cls](https://login.intersystems.com/login/SSO.UI.User.ApplicationTokens.cls) 就可以检索到你的ICR Token。 ```bash docker login -u="YourWRCLogin" -p="YourICRToken" containers.intersystems.com ``` ### 创建`myappdata`数据库和global 我们现在并没有真正创建`myappdata`数据库,而是准备一个配置,在docker构建时创建它。 为此,我们只是用JSON格式创建一个简单的文件。 config-api库将被用来在IRIS实例中加载它。 为此,我们只是用JSON格式创建一个简单的文件。 config-api库将被用来在IRIS实例中加载它。 创建文件[config-files/simple-config.json](https://github.com/lscalese/iris-mirroring-samples/blob/master/config-files/simple-config.json) ```json { "Defaults":{ "DBDATADIR" : "${MGRDIR}myappdata/", "DBDATANAME" : "MYAPPDATA" }, "SYS.Databases":{ "${DBDATADIR}" : {} }, "Databases":{ "${DBDATANAME}" : { "Directory" : "${DBDATADIR}" } }, "MapGlobals":{ "USER": [{ "Name" : "demo.*", "Database" : "${DBDATANAME}" }] }, "Security.Services" : { "%Service_Mirror" : { /* Enable the mirror service on this instance */ "Enabled" : true } } } ``` 这个配置文件允许你用默认设置创建一个新的数据库,并在USER命名空间做global映射`demo.*`。 关于[config-api](https://openexchange.intersystems.com/package/config-api) 配置文件功能的更多信息请参考相关的[文章](https://community.intersystems.com/post/environment-setup-config-api) 或[github页](https://community.intersystems.com/post/environment-setup-config-api) ### Docker 文件 Docker文件是基于现有的 [docker模板](https://github.com/intersystems-community/objectscript-docker-template)的,但我们需要做一些修改,以创建一个工作目录,安装使用虚拟IP的工具,安装ZPM等等。 我们的IRIS image对每个镜像成员都是一样的。镜像将根据其角色The mirroring will be set up on the container starting with the correct configuration depending on its role (第一成员,故障转移备份成员,或读写报告成员) 在容器上以正确的配置开始设置。 请看下面Dockerfile上的注释: ```Dockerfile ARG IMAGE=containers.intersystems.com/intersystems/iris:2021.1.0.215.0 # 不需要从WRC下载image。它将在构建时从ICR中提取。 FROM $IMAGE USER root # COPY session.sh / COPY iris.key /usr/irissys/mgr/iris.key # /opt/demo 将是我们的工作目录,用于存储我们的配置文件和其他安装文件。 # 安装iputils-arping 以得到一个arping 命令。这在配置虚拟IP时会用到。 # 下载最新ZPM 版本 (ZPM 仅包含在社区版中)。 RUN mkdir /opt/demo && \ chown ${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} /opt/demo && \ chmod 666 /usr/irissys/mgr/iris.key && \ apt-get update && apt-get install iputils-arping && \ wget -O /opt/demo/zpm.xml https://pm.community.intersystems.com/packages/zpm/latest/installer USER ${ISC_PACKAGE_MGRUSER} WORKDIR /opt/demo # 设置默认镜像(Default Mirror)角色为主控(master) # 它将在运行时被重写在docker-compose文件上(第一个实例的主文件、备份和报告)。 ARG IRIS_MIRROR_ROLE=master # 将config-files目录的内容复制到/opt/demo。 # 目前我们只创建了一个simple-config来设置我们的数据库和global映射。 # 在本文的后面,我们将添加其他配置文件来设置镜像。 ADD config-files . SHELL [ "/session.sh" ] # 安装 ZPM # 用 ZPM 安装config-api 和 pki-script # 用config-api加载simple-config.json文件,用以: # - 创建"myappdata" 数据库, # - 为 "myappdata "数据库中global "demo.*"在命名空间 "USER "中添加一个global映射。 # 基本上,安装ObjectScript应用程序的入口在这里。 # 对于这个例子,我们将加载simple-config.json来创建一个简单的数据库和一个global映射。 RUN \ Do $SYSTEM.OBJ.Load("/opt/demo/zpm.xml", "ck") \ zpm "install config-api" \ zpm "install pki-script" \ Set sc = ##class(Api.Config.Services.Loader).Load("/opt/demo/simple-config.json") # 复制镜像初始化脚本。 COPY init_mirror.sh / # 执行一个启动后的脚本,配置镜像。 # init_mirror.sh的内容将在本文后面描述。 CMD ["-a", "/init_mirror.sh"] ``` ### 制作 IRIS image Docker文件已经准备好了;我们可以制作image了。: ``` docker build --no-cache --tag mirror-demo:latest . ``` 这个image将会运行 将被用于运行主节点、备份节点和报告节点。 ### 准备第一个镜像成员的配置文件 config-api库允许配置一个镜像,所以我们必须为第一个镜像成员创建一个专门的配置文件`config-files/mirror-master.json` 为方便起见,注释直接位于JSON中。你可以下载 [没有注释的mirror-master.json](https://raw.githubusercontent.com/lscalese/iris-mirroring-samples/master/config-files/mirror-master.json). 所有的IP地址将通过`Docker-compose`文件分配给每个节点。 ```json { "Defaults":{ /* Section contains all variables */ "MirrorName" : "Demo", /* The name of our mirror */ "ArbiterNode" : "172.16.238.10|2188", /* IP Address and port of the arbiter node */ "VirtualAddress" : "172.16.238.100/24", /* Virtual IP Address */ "VirtualAddressInterface" : "eth0", /* Network interface used for the Virtual IP Address. */ "MirrorAddress" : "172.16.220.20", /* IP Address of this node in the private mirror network */ "AgentAddress" : "172.16.238.20", /* IP Address of this node (Agent is installed on the same machine) */ "SystemName" : "master", /* This instance name in the mirror */ "DBDir" : "${MGRDIR}myappdata/", /* Database directory to add to the Demo mirror */ "DBName" : "MYAPPDATA" /* Database name in the mirror */ }, "SYS.MirrorMaster" : { "${MirrorName}" : { "Config" : { "Name" : "${MirrorName}", "SystemName" : "${SystemName}", "UseSSL" : true, "ArbiterNode" : "${ArbiterNode}", "VirtualAddress" : "${VirtualAddress}", "VirtualAddressInterface" : "${VirtualAddressInterface}", "MirrorAddress": "${MirrorAddress}", "AgentAddress": "${AgentAddress}" }, "Databases" : [{ /* List of databases to add to the mirror */ "Directory" : "${DBDir}", "MirrorDBName" : "${DBName}" }], "SSLInfo" : { /* SSL Configuration, certificates are generated by PKI */ "CAFile" : "/usr/irissys/mgr/CAServer/CA_Server.cer", "CertificateFile" : "/usr/irissys/mgr/master_client.cer", "PrivateKeyFile" : "/usr/irissys/mgr/master_client.key", "PrivateKeyPassword" : "", "PrivateKeyType" : "2" } } } } ``` ### 准备故障转移备份成员的配置文件 创建一个配置文件,故障转移备份成员`config-files/mirror-backup.json`. 它看起来像第一个成员。 ```json { "Defaults":{ /* Section contains all variables */ "MirrorName" : "Demo", /* Mirror to join */ "AgentAddress" : "172.16.238.20", /* Agent IP Address of the first mirror member */ "SystemName" : "backup", /* This instance name in the mirror */ "PrimaryInstanceName" : "IRIS", /* IRIS Instance name of the first mirror member */ "VirtualAddressInterface" : "eth0", /* Network interface used for the Virtual IP Address. */ "DBDir" : "${MGRDIR}myappdata/", /* DB in mirror */ "MirrorAddress" : "172.16.220.30" /* IP Address of this node in the private mirror network */ }, "SYS.MirrorFailOver" : { "${MirrorName}" : { "Config": { "Name" : "${MirrorName}", "SystemName" : "${SystemName}", "InstanceName" : "${PrimaryInstanceName}", "AgentAddress" : "${AgentAddress}", "AgentPort" : "2188", "AsyncMember" : false, "AsyncMemberType" : "" }, "Databases" : [{ "Directory" : "${DBDir}" }], "LocalInfo" : { "VirtualAddressInterface" : "${VirtualAddressInterface}", "MirrorAddress": "${MirrorAddress}" }, "SSLInfo" : { "CAFile" : "/usr/irissys/mgr/CA_Server.cer", "CertificateFile" : "/usr/irissys/mgr/backup_client.cer", "PrivateKeyFile" : "/usr/irissys/mgr/backup_client.key", "PrivateKeyPassword" : "", "PrivateKeyType" : "2" } } } } ``` ### 准备读写报告异步成员的配置文件 它与故障转移配置文件非常相似。 不同之处在于`AsyncMember`、`AsyncMemberType`和`MirrorAddress`的值。 创建文件`./config-files/mirror-report.json`: ```json { "Defaults":{ "MirrorName" : "Demo", "AgentAddress" : "172.16.238.20", "SystemName" : "report", "PrimaryInstanceName" : "IRIS", "VirtualAddressInterface" : "eth0", "DBDir" : "${MGRDIR}myappdata/", "MirrorAddress" : "172.16.220.40" }, "SYS.MirrorFailOver" : { "${MirrorName}" : { "Config": { "Name" : "${MirrorName}", "SystemName" : "${SystemName}", "InstanceName" : "${PrimaryInstanceName}", "AgentAddress" : "${AgentAddress}", "AgentPort" : "2188", "AsyncMember" : true, "AsyncMemberType" : "rw" }, "Databases" : [{ "Directory" : "${DBDir}" }], "LocalInfo" : { "VirtualAddressInterface" : "${VirtualAddressInterface}", "MirrorAddress": "${MirrorAddress}" }, "SSLInfo" : { "CAFile" : "/usr/irissys/mgr/CA_Server.cer", "CertificateFile" : "/usr/irissys/mgr/report_client.cer", "PrivateKeyFile" : "/usr/irissys/mgr/report_client.key", "PrivateKeyPassword" : "", "PrivateKeyType" : "2" } } } } ``` ### 配置IRIS节点并生成证书 所有的配置文件都准备好了! 我们的[Dockerfile](https://github.com/lscalese/iris-mirroring-samples/blob/master/Dockerfile)的最后一行是`CMD ["-a", "/init_mirror.sh"]`。 现在我们要写这个脚本来生成证书,并用相关的配置文件来设置每个IRIS节点。 正如你在这个脚本中看到的那样,生成证书的代码非常简单: * `Do ##class(lscalese.pki.Utils).MirrorMaster(,"",,,,"backup,report")` -主控节点。 它配置了PKI服务器,PKI客户端,请求证书;等待验证,获得证书,自动接受验证节点的进一步请求,持续5分钟。自动接受的请求只限于`故障转移备份主机` 和 `报告异步成员主机`。 * `Do ##class(lscalese.pki.Utils).MirrorBackup("${PKISERVER}","")` -备份节点和报告节点。 配置 PKI 客户端,请求证书,等待验证,获得证书。 ```bash #!/bin/bash # 用来测试镜像的数据库 DATABASE=/usr/irissys/mgr/myappdata # 目录包含由主控节点备份的myappdata,以便在其他节点上恢复。 BACKUP_FOLDER=/opt/backup # 主控节点的json config-api格式的镜像配置文件。 MASTER_CONFIG=/opt/demo/mirror-master.json # json config-api格式的镜像配置文件,用于故障转移备份节点。 BACKUP_CONFIG=/opt/demo/mirror-backup.json # 报告异步节点的json config-api格式的镜像配置文件。 REPORT_CONFIG=/opt/demo/mirror-report.json # 镜像名字... MIRROR_NAME=DEMO # 镜像成员清单 MIRROR_MEMBERS=BACKUP,REPORT # PKI服务器主机:端口(PKI服务器安装在主实例上)。 PKISERVER=master:52773 # 在主控节点上操作。 # 在这个实例上配置公钥基础设施服务器,并生成证书以配置使用SSL的镜像。 # 请参见文章https://community.intersystems.com/post/creating-ssl-enabled-mirror-intersystems-iris-using-public-key-infrastructure-pki。 # 和相关的工具https://openexchange.intersystems.com/package/PKI-Script。 # 使用config-api加载镜像配置与/opt/demo/simple-config.json文件。 # 启动一个作业,自动接受其他名为 "备份 (backup)"和 "报告 (report)"的成员加入镜像(避免在门户管理中进行手动验证,最大延迟为600秒)。 master() { rm -rf $BACKUP_FOLDER/IRIS.DAT iris session $ISC_PACKAGE_INSTANCENAME -U %SYS
文章
jieliang liu · 一月 8, 2021

ObjectScript类浏览器 - 以UML类图方式浏览ObjectScript类

你好! 本文简单介绍一款工具,帮您理解InterSystems产品(从IRIS到Caché、Ensemble以及HealthShare)中的类及其结构。 简言之,它将类或整个包可视化,显示类之间的关系,并向开发人员和团队领导提供各种信息,而无需到 Studio 中检查代码。 如果您正在学习InterSystems产品,经常查看项目,或只对InterSystems技术解决方案中的新内容感兴趣,欢迎阅读ObjectScript类浏览器概述! InterSystems 产品简介 IRIS(之前称为Caché) 是一个多模型DBMS。您可以使用SQL查询来访问它,也可以通过各种编程语言可用的接口与存储的对象和过程进行交互。但最多的还是使用DBMS原生内置语言--ObjectScript (COS) 开发应用程序。 Caché支持DBMS级别的类。有两种主要的类类型:Persistent(可以存储在数据库中)和 Registered(不存储在数据库中,扮演程序和处理程序的角色)。还有几种特殊的类类型:Serial(可集成到持久类中用于创建复杂数据类型(如:地址)的类),DataType(用于创建用户定义的数据类型)、Index、View 和 Stream。 进入类浏览器 Caché类浏览器是一个工具,它将Caché类的结构可视化为图表,显示类之间的依赖关系和所有相关信息,包括各种类元素的方法代码、查询、xData块、注释、文档和关键字。 功能 类浏览器使用扩展版UML类图进行可视化,因为Caché有一组很重要但不被标准UML支持的附加实体:查询、xData块、方法和属性的大量关键字(如System、ZenMethod、Hidden、ProcedureBlock等)、父子关系和一多关系、类类型等。 Caché 类浏览器(1.14.3版)允许您执行以下操作: 显示包、类图或整个包的层次结构; 编辑图表显示后的外观; 保存类图的当前图像; 保存一个图表的当前外观,并在将来恢复; 按图表或类树中显示的任何关键字搜索; 使用工具提示获得关于类、其属性、方法、参数、查询和xData块的完整信息; 查看方法、查询或xData块的代码; 启用或禁用任何图表元素的显示,包括图形图标。 为了更好理解下文内容,先看下类浏览器的如何对类进行可视化的。举个例子,让我们显示来自“samples”命名空间的“cinema”包: 详细信息和功能概述 左侧边栏包含一个包树。将鼠标指针放在包名称上,然后单击出现在其右侧的按钮以显示整个包。在包树中选择类,将其与其链接的类一起呈现。 类浏览器可以显示类之间的几种依赖关系类型: 1. 继承。以白色实心箭头显示,箭头指向继承的类; 2. 类之间的“关联”或关系。如果其中一个类的字段包含另一个类的类型,图表构建器将把它显示为关联关系; 3. 父子关系和一多关系:维护数据完整性的规则。 如果将鼠标指针指向该关系,则创建该关系的属性将高亮显示: 注意,类浏览器不会更深入,也不会为当前包之外的类绘制依赖关系。它将只显示当前包中的类,如果需要限制类浏览器查找类的深度,请使用“依赖级别”设置: 类本身显示为一个矩形,分为六个部分: 1. 类名:将鼠标指针指向类名,可以了解它是何时创建和修改的,查看注释以及所有分配给这个类的关键字。双击类头将打开其文档; 2. 类参数:所有带类型、关键字和注释的赋值参数。斜体的参数以及任何属性都有工具提示并且可以悬停; 3. 类属性与参数类似; 4. 方法:点击任何方法都可以查看其源代码。COS 语法将被高亮显示; 5. 查询:与方法类似--点击可以查看源代码; 6. xData块:主要包含XML数据的块。点击将显示块中格式化的源代码。 默认每个类都显示有许多图形图标。点击屏幕右上角的“帮助”按钮,了解每个图标的含义。如果您需要默认显示更严格或更包容的 UML 类图,以及任何类的任何部分,可以在设置部分禁用。 如果关系图太大,而且您也不太熟悉,可以使用快速图表搜索功能。包含您输入的关键字的任何部分的类将被高亮显示。要跳转到下一个匹配项,只需按 Enter 键或再次单击搜索按钮: 最后,在完成了图表编辑,去掉所有不必要关系,并将元素安放好,实现期望的外观之后,可以点击左下角的“下载”按钮来保存: 激活固定按钮 时,元素在当前类(或包)组的图表上的位置将被固定。例如,如果您选择A类和B类,然后用固定按钮保存视图,则再次选择A类和B类时将看到完全相同的视图,即使在重新启动浏览器或机器之后也不会变化。但是如果您只选择A类,布局将是默认的。 安装 要安装Caché类浏览器,只需将最新版本xml包导入到任何命名空间中。导入后就能看到名为hostname/ClassExplorer/(末尾的斜杠不能丢)的新web应用程序。 详细安装说明 1. 下载最新版Caché类浏览器压缩包; 2. 提取名为Cache/CacheClassExplorer-vX.X.X.xml的XML文件; 3. 使用以下方法之一将包导入任何命名空间: 1. 只需将XML文件拖到Studio上; 2. 使用系统管理门户:系统资源管理器 -> 类 -> 导入,并指定本地文件路径; 3. 使用terminal命令: do ##class(%Installer.Installer).InstallFromCommandLine(“Path/Installer.cls.xml”); 4. 读取导入日志--如果顺利安装,就可以通过 http://hostname/ClassExplorer/ 打开 web 应用程序。如果出了问题,请检查以下内容: 1. 是否有足够权限将类导入该命名空间; 2. web应用程序用户是否有足够权限访问不同的命名空间; 3. 如果出现错误404,只需检查是否在 URL 末尾添加了斜杠。 附加截图 [截图 1] DSVRDemo 包,鼠标指针悬停在一个类名上。 [截图 2] DataMining 包,在图表中搜索“TreeInput”关键字。 [截图 3] JavaDemo.JavaListSample 类中的方法代码视图。 [截图 4] 查看 ClassExplorer.Router 类中的 Xdata 块内容。 您可以尝试在标准SAMPLES命名空间中使用类浏览器:演示。这个项目的评测视频。 欢迎任何反馈、建议和意见--提交到这里或GitHub仓库。希望对您有用!
文章
Jingwei Wang · 十二月 29, 2021

ObjectScript数据类型 - 日期

$HOROLOG($H) 表示当前的本地日期和时间,是由两个整数值组成的字符串,这些整数是计数器,是InterSystems IRIS存储格式,不是用户可读的日期和时间。 ddddd,sssss 代码示例: w $H,! 北京时间2021年12月29日15:15:30时,输出结果为: 66107,54930 第一个整数,ddddd,是当前日期,表示为自1840年12月31日以来的天数,其中第1天是1841年1月1日。这个日期到达的最大年年限是9999年12月31日,所以这个整数的最大值是2980013。$HOROLOG不能直接用于表示1840年到9999年范围之外的日期 第二个整数,sssss,是当前的时间,表示为从当天午夜开始的秒数计数。系统将时间字段从0递增到86399秒。当午夜时分达到86399时,系统将时间字段重置为0,并将日期字段增加1。 你可以通过调用Horolog()方法获得相同的当前日期和时间信息,如下所示。 WRITE $SYSTEM.SYS.Horolog() $NOW() $NOW()返回当前进程的本地日期和时间,是InterSystems IRIS存储格式,不是用户可读的日期和时间。 ddddd,sssss.ffffff 代码示例: w $NOW(),! 北京时间2021年12月29日15:15:30时,输出结果为: 66107,54930.383622 $ZTIMESTAMP $ZTIMESTAMP返回UTC日期和时间,是InterSystems IRIS存储格式,不是用户可读的日期和时间。带有小数秒,小数秒以三位数的精度表示(Windows系统),或以六位数的精度表示(UNIX®系统) 代码示例: w $ZTIMESTAMP,! 北京时间2021年12月29日15:15:30时,输出结果为: 66107,26130.383 $NOW() vs $HOROLOG vs $ZTIMESTAMP $HOROLOG包含了InterSystems IRIS存储格式的、经过变体调整的本地日期和时间。本地时区是由$ZTIMEZONE特殊变量的当前值决定的,然后根据本地时间变体进行调整,如夏令时。它只返回整数秒,小数秒会被截断。 $NOW()根据$ZTIMEZONE特殊变量的值确定本地时区。本地时间不会因本地时间变体(如夏令时)而调整。因此,它可能与本地时钟时间不一致。$NOW(tzmins)返回与指定的tzmins时区参数对应的时间和日期。$ZTIMEZONE的值被忽略。 $ZTIMESTAMP返回UTC日期和时间。 日期和时间的转换 $ZDATE 将$HOROLOG的日期部分,即ddddd,转换为用户可读的形式。 ​ WRITE $ZDATE($PIECE($HOROLOG,",",1)) 输出结果为: 12/29/2021 $ZTIME 将$HOROLOG的时间部分,即sssss,转换为用户可读的形式。 $ZDATETIME 将$HOROLOG的日期和时间,同时转换为用户可读的形式。 当使用$HOROLOG时,在这些函数中设置时间值的精度总是返回零作为小数秒。 $ZDATETIME(hdatetime,dformat,tformat,precision,monthlist,yearopt,startwin,endwin,mindate,maxdate,erropt,localeopt) $ZDT(hdatetime,dformat,tformat,precision,monthlist,yearopt,startwin,endwin,mindate,maxdate,erropt,localeopt) 参数描述请参考参数解析 参数 描述 hdatetime 内部格式的日期和时间值:$HOROLOG]或者 $ZTIMESTAMP dformat 一个整数,指定返回日期值的格式 tformat 一个整数,指定返回时间值的格式 precision 一个整数,指定返回时间值的小数位数(小数秒):只有当hdatetime格式可以包括小数时间值($ZTIMESTAMP格式),并且选择的tformat选项包括秒时,精度才适用。 monthlist 可选的 - 一个字符串或一个变量的名称,用于指定一组月名。 这个字符串必须以一个分界符开始,它的12个条目必须以这个分界符分开。 例如: January February March April May June July August September October November December Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec monthlist仅在dformat为2、5、6、7、9、18或20时有效。 yearopt 一个整数代码,指定以两位数或四位数的数值表示年份。 startwin 滑动窗口的开始,在这个窗口中,日期用两位数的年份表示。 当你使用yearopt为3或5时,你必须提供startwin,startwin对任何其他yearopt值都是无效的。 当yearopt=3时,startwin是一个$HOROLOG日期格式的绝对日期,表示滑动窗口的开始日期。 当yearopt=5时,startwin是一个数值,表示滑动窗口的起始年份,以当前年份之前的年数表示。 endwin 滑动窗口的末端,在这个窗口中,日期用两位数的年份表示。 当yearopt为3或5时,你可以选择提供endwin。endwin在任何其他yearopt值下无效。 当yearopt=3时,endwin是一个$HOROLOG日期格式的绝对日期,表示滑动窗口的结束日期。 当yearopt=5时,endwin是一个数值,表示滑动窗口的结束年限,以当前年限后的年数表示。 当yearopt=5时,滑动窗口总是从startwin中指定的年份的1月1日开始,到endwin中指定的年份的12月31日结束,或者是隐含的结束年份(如果你省略endwin)。 如果省略endwin(或指定为-1),有效的滑动窗口将是100年的长度。 如果你同时提供startwin和endwin,它们指定的滑动窗口的持续时间不能超过100年。 mindate 有效日期范围的下限。指定为$HOROLOG的整数日期计数,例如 0代表1840年12月31日,2/22/2018表示为64701。 支持的mindate值:正的整数,0 或-1 maxdate 有效日期范围的上限,指定为整数$HOROLOG日期计数. 例如,1/1/2100表示为94599 指定一个大于maxdate的hdatetime日期会产生一个VALUE OUT OF RANGE错误。 指定一个大于2980013的maxdate会产生一个VALUE OF RANGE错误。 你可以指定maxdate,也可以不指定mindate。指定一个小于mindate的maxdate会产生一个ILLEGAL VALUE错误。 erropt 当hdatetime无效时要返回的表达式。为这个参数指定一个值可以抑制与无效或超出范围的hdatetime值有关的错误代码。$ZDATETIME不发出错误信息,而是返回erropt。 localeopt 一个布尔标志,指定对dformat、tformat、monthlist、yearopt、mindate和maxdate默认值以及其他日期和时间特征使用哪种语言: localeopt=0:当前语言属性设置决定这些参数默认值。 localeopt=1:ODBC标准语言决定这些参数默认值。 localeopt没有指定:dformat值决定这些参数默认值。 $ZDATETIMEH 将用户可读的日期和时间,转换为$HOROLOG(ddddd,sssss)格式 $ZDATETIMEH(datetime,dformat,tformat,monthlist,yearopt,startwin,endwin,mindate,maxdate,erropt,localeopt) $ZDTH(datetime,dformat,tformat,monthlist,yearopt,startwin,endwin,mindate,maxdate,erropt,localeopt) 参数描述请参考参数解析 可以使用 "T "或 "t "字母代码来指定当前日期。但是,dformat必须是5、6、7、8、9或15。 WRITE $ZDATETIMEH("T",5) 输出: 66107,0 当前日期前三天: WRITE $ZDATETIMEH("T-3",5) 输出: 66104,0 $ZTIMEZONE : 时区 $ZTIMEZONE是一个从格林威治子午线开始的固定时区偏移量,它不对当地的季节性时间变体进行调整,如夏令时。 代码示例: w $ZTIMEZONE,! 输出结果为: -480
文章
姚 鑫 · 三月 10, 2021

第七章 SQL表之间的关系

# 第七章 SQL表之间的关系 要在表之间强制执行引用完整性,可以定义外键。修改包含外键约束的表时,将检查外键约束。 # 定义外键 有几种方法可以在InterSystems SQL中定义外键: - 可以定义两个类之间的关系。定义关系会自动将外键约束投影到SQL。 - 可以在类定义中添加显式外键定义(对于关系未涵盖的情况)。 - 可以使用`CREATE TABLE`或`ALTER TABLE`命令添加外键。可以使用`ALTER TABLE`命令删除外键。 用作外键引用的`RowID`字段必须是公共的。引用隐藏的`RowID`?有关如何使用公用(或专用)`RowID`字段定义表的信息。 **一个表(类)的外键最大数目为400。** ## 外键引用完整性检查 外键约束可以指定更新或删除时的引用操作。 在`CREATE TABLE reference action`子句中描述了使用DDL定义这个引用操作。 在类定义引用的`OnDelete`和`OnUpdate`外键关键字中定义了一个持久化类来定义这个引用操作,该类投射到一个表。 在创建分片表时,这些引用操作必须设置为无操作。 默认情况下,InterSystemsIRIS®数据平台对`INSERT`,`UPDATE`和`DELETE`操作执行外键引用完整性检查。如果该操作将违反参照完整性,则不会执行;该操作将发出`SQLCODE -121,-122,-123或-124`错误。参照完整性检查失败会生成如下错误: ```java 错误#5540:SQLCODE:-124消息:表'HealthLanguage.FKey2'中至少存在1行,该行引用键NewIndex1-外键约束'NewForeignKey1'(字段'Pointer1')的NO ACTION引用操作失败[Execute + 5 ^ IRISSql16:USER] ``` 可以使用`$SYSTEM.SQL.SetFilerRefIntegrity()`方法在系统范围内禁止此检查。若要确定当前设置,请调用`$SYSTEM.SQL.CurrentSettings()`。 默认情况下,当删除带有外键的行时,InterSystems IRIS将在相应的被引用表的行上获取长期(直到事务结束)共享锁。这样可以防止在引用行上的`DELETE`事务完成之前对引用行进行更新或删除。这样可以防止删除引用行,然后回退删除引用行的情况。如果发生这种情况,外键将引用不存在的行。如果使用`NoCheck`定义外键,或者使用`%NOCHECK`或`%NOLOCK`指定引用行的`DELETE`,则不会获取此锁定。 使用持久性类定义定义表时,可以使用`NoCheck`关键字定义外键,以禁止将来对该外键进行检查。` CREATE TABLE`不提供此关键字选项。 可以使用`%NOCHECK`关键字选项禁止检查特定操作。 默认情况下,InterSystems IRIS还对以下操作执行外键引用完整性检查。如果指定的操作违反了引用完整性,则不执行该命令: - `ALTER TABLE DROP COLUMN`。 - `ALTER TABLE DROP CONSTRAINT`删除约束 问题`-317 SQLCODE`。 可以使用`SET`选项`COMPILEMODE=NOCHECK`来抑制外键完整性检查。 - 删除表。问题`-320 SQLCODE`。可以使用`SET`选项`COMPILEMODE = NOCHECK`来抑制外键插入检查。 - 触发器事件,包括事件之前。 例如,如果删除操作因违反外键引用完整性而不能执行,则不会执行`BEFORE DELETE`触发器。 在父/子关系中,没有定义子元素的顺序。 应用程序代码不能依赖于任何特定的顺序。 # 父表和子表 ## 定义父表和子表 在定义投射到表的持久类时,可以使用`relationship`属性指定两个表之间的父/子关系。 下面的例子定义了父表: ```java Class Sample.Invoice Extends %Persistent { Property Buyer As %String(MAXLEN=50) [Required]; Property InvoiceDate As %TimeStamp; Relationship Pchildren AS Sample.LineItem [ Cardinality = children, Inverse = Cparent ]; } ``` 下面的例子定义了一个子表: ```java Class Sample.LineItem Extends %Persistent { Property ProductSKU As %String; Property UnitPrice As %Numeric; Relationship Cparent AS Sample.Invoice [ Cardinality = parent, Inverse = Pchildren ]; } ``` 注意这两句话: - `Relationship Pchildren AS Sample.LineItem [ Cardinality = children, Inverse = Cparent ];` - `Relationship Cparent AS Sample.Invoice [ Cardinality = parent, Inverse = Pchildren ];` 在Management Portal SQL interface Catalog Details选项卡中,表信息提供了子表和/或父表的名称。 如果是子表,则提供对父表的引用,如:`parent->Sample.Invoice`。 子表本身可以是子表的父表。 (子表的子表被称为“孙”表。) 在本例中,表`Info`提供了父表和子表的名称。 ## 向父表和子表插入数据 在将相应的记录插入子表之前,必须将每个记录插入父表。 例如: ```java INSERT INTO Sample.Invoice (Buyer,InvoiceDate) VALUES ('yaoxin',CURRENT_TIMESTAMP) ``` ```java INSERT INTO Sample.LineItem (Cparent,ProductSKU,UnitPrice) VALUES (1,'45-A7',99.95) INSERT INTO Sample.LineItem (Cparent,ProductSKU,UnitPrice) VALUES (1,'22-A1',0.75) ``` ![image](/sites/default/files/inline/images/1_24.png) 尝试插入没有对应父记录ID的子记录时,会使用`%msg`子表`'Sample生成SQLCODE -104错误。 LineItem'`引用父表中不存在的行。 在子表上的插入操作期间,在父表的相应行上获得共享锁。 在插入子表行时,该行被锁定。 然后,锁被释放(直到事务结束时才被持有)。 这确保了在插入操作期间引用的父行不会被更改。 ## 标识父表和子表 在嵌入式SQL中,可以使用主机变量数组来标识父表和子表。 在子表中,主机变量数组的下标0被设置为父引用(`Cparent`),格式为parentref,下标1被设置为子记录ID,格式为`parentref|| childf`。 在父表中,没有定义下标0。 如下面的例子所示: ```java /// d ##class(PHA.TEST.SQL).FatherChildTable() ClassMethod FatherChildTable() { KILL tflds,SQLCODE,C1 &sql(DECLARE C1 CURSOR FOR SELECT *,%TABLENAME INTO :tflds(),:tname FROM Sample.Invoice) &sql(OPEN C1) IF SQLCODE
文章
姚 鑫 · 四月 9, 2021

第二十一章 导入和导出SQL数据

# 第二十一章 导入和导出SQL数据 在InterSystems IRIS®Data Platform Management Portal中,有用于导入和导出数据的工具: - 从文本文件导入数据 - 将数据导出到文本文件 这些工具使用动态SQL,这意味着查询是在运行时准备和执行的。可以导入或导出的行的最大大小为3,641,144个字符。 还可以使用%SQL.Import.Mgr类导入数据,使用%SQL.Export.Mgr类导出数据。 # 从文本文件导入数据 可以将数据从文本文件导入到合适的InterSystems IRIS类中。执行此操作时,系统将在表中为该类创建并保存新行。该类必须已经存在并且必须编译。要将数据导入到此类中,请执行以下操作: 1. 从管理门户中选择系统资源管理器,然后选择SQL。使用页面顶部的切换选项选择一个命名空间;这将显示可用命名空间的列表。 2. 在页面顶部,单击向导下拉列表,然后选择数据导入。 3. 在向导的第一页上,从指定外部文件的位置开始。对于导入文件所在的位置,请单击要使用的服务器的名称。 4. 然后输入文件的完整路径和文件名。 5. 对于选择架构名称,单击要向其中导入数据的InterSystems IRIS包。 6. 对于选择表名,单击将包含新创建的对象的类。 7. 然后单击下一步。 8. 在向导的第二页上,单击将包含导入数据的列。 9. 然后单击下一步。 10. 在向导的第三页上,描述外部文件的格式。 - 有关用什么分隔符分隔您的列?,请单击与此文件中的分隔符对应的选项。 - 单击第一行是否包含列标题?如果文件的第一行不包含数据,则选中此复选框。 - 对于字符串引号,单击指示此文件用于开始和结束字符串数据的引号分隔符字符的选项。 - 对于日期格式,请单击指示此文件中日期格式的选项。 - 对于时间格式,请单击指示此文件中的时间格式的选项。 - 对于时间戳格式,请单击指示此文件中的时间戳格式的选项。 - 单击禁用验证?如果不希望向导在导入时验证数据,请选中此复选框。 - 使用%SortBegin/%SortEnd?如果不希望向导在导入期间重新生成索引,请选中此复选框。如果选中延迟索引生成,向导将在将导入的数据插入到表中之前为该类调用%SortBegin方法。导入完成后,向导将调用%SortEnd方法。不执行任何验证(与使用%NOCHECK的INSERT相同)。这是因为当使用%SortBegin/%SortEnd时,在SQL INSERT期间不能检查索引的唯一性。如果选中延迟索引构建,则假定导入的数据有效,不会检查其有效性。 - 或者,单击“预览数据”以查看向导将如何分析此文件中的数据。 11. 单击“下一步”。 12. 检查条目,然后单击Finish。向导将显示“数据导入结果”对话框。 13. 单击关闭。或者单击给定的链接以查看后台任务页面。 在任何一种情况下,向导都会启动一个后台任务来完成工作。 # 将数据导出到文本文件 可以将给定类的数据导出到文本文件。为此: 1. 从管理门户中选择系统资源管理器,然后选择SQL。使用页面顶部的切换选项选择一个命名空间;这将显示可用命名空间的列表。 2. 在页面顶部,单击向导下拉列表,然后选择数据导出。 3. 在向导的第一页上: - 输入要创建以保存导出数据的文件的完整路径和文件名。 - 从下拉列表中,选择要从中导出数据的命名空间、方案名和表名。 - 或者,从Charset下拉列表中选择一个字符集;默认值为Device Default。 - 然后单击下一步。 4. 在向导的第二页上,选择要导出的列。然后单击下一步。 5. 在向导的第三页上,描述外部文件的格式。 - 有关用什么分隔符分隔的列?,请单击与此文件中的分隔符对应的选项。 - 单击导出列标题?如果要将列标题导出为文件的第一行,请选中此复选框。 - 对于字符串引号,单击一个选项以指示如何开始和结束此文件中的字符串数据。 - 对于日期格式,单击一个选项以指示要在此文件中使用的日期格式。 - (可选)单击“预览数据”以查看结果的外观。然后单击下一步。 6. 检查条目,然后单击Finish。该向导将显示“数据输出结果”对话框。 7. 单击关闭。或单击给定的链接以查看后台任务页面。 在任何一种情况下,向导都启动后台任务来完成工作。
文章
姚 鑫 · 五月 23, 2021

第三章 发送HTTP请求

# 第三章 发送HTTP请求 # 发送HTTP请求 创建HTTP请求后,使用以下方法之一发送该请求: ### Delete() ```java method Delete(location As %String = "", test As %Integer = 0, reset As %Boolean = 1) as %Status ``` 发出HTTP DELETE请求。 ### Get() ```java method Get(location As %String = "", test As %Integer = 0, reset As %Boolean = 1) as %Status ``` 发出HTTP GET请求。此方法使Web服务器返回请求的页面。 ### Head() ```java method Head(location As %String, test As %Integer = 0, reset As %Boolean = 1) as %Status ``` 发出HTTP Head请求。此方法使Web服务器仅返回响应头,而不返回正文。 ### Patch() ```java method Patch(location As %String = "", test As %Integer = 0, reset As %Boolean = 1) as %Status ``` 发出HTTP修补程序请求。使用此方法可以对现有资源进行部分更改。 ### Post() ```java method Post(location As %String = "", test As %Integer = 0, reset As %Boolean = 1) as %Status ``` 发出HTTP POST请求。使用此方法可将数据(如表单结果)发送到Web服务器,或上载文件。有关示例,请参阅“发送表单数据”。 ### Put() ```java method Put(location As %String = "", test As %Integer = 0, reset As %Boolean = 1) as %Status ``` 发出HTTP PUT请求。使用此方法将数据上载到Web服务器。PUT请求并不常见。 ### Send() ```java method Send(type As %String, location As %String, test As %Integer = 0, reset As %Boolean = 1) as %Status ``` 将指定类型的HTTP请求发送到服务器。此方法通常由其他方法调用,但如果要使用不同的HTTP谓词,则提供此方法以供使用。此处`type`是指定HTTP谓词(如`“POST”`)的字符串。 在所有情况下: - 每个方法都返回一个状态,应该检查该状态。 - 如果该方法正确完成,则对此请求的响应将位于`HttpResponse`属性中。 - `Location`参数是要请求的URL,例如:`"/test.html"`。 - `Location`参数可以包含参数,假定这些参数已经URL转义,例如:`"/test.html?PARAM=%25VALUE"`将`PARAM`设置为等于`%VALUE`。 - 使用test参数检查正在发送的是您预期要发送的内容: - 如果test为1,则该方法不会连接到远程计算机,而是将其本应发送到Web服务器的内容输出到当前设备。 - 如果`test`为`2`,则在发出`HTTP`请求后将响应输出到当前设备。 - 在从服务器读取响应后,每个方法都会自动调用`Reset()`方法,除非`test=1`或`Reset=0`。 `Reset()`方法重置`%Net.HttpRequest`实例,以便它可以发出另一个请求。这比关闭此对象并创建新实例要快得多。这还会将`Location`标头的值移动到`Referer`标头。 ```java Set httprequest=##class(%Net.HttpRequest).%New() Set httprequest.Server="www.intersystems.com" Do httprequest.Get("/") ``` # 创建和发送多部分POST请求 要创建和发送多部分`POST`请求,请使用`%Net.MIMEPart`类,本书后面将详细讨论这些类。下面的示例发送包含两个部分的`POST`请求。第一部分包括文件二进制数据,第二部分包括文件名。 ```java ClassMethod CorrectWriteMIMEMessage3(header As %String) { // Create root MIMEPart Set RootMIMEPart=##class(%Net.MIMEPart).%New() //Create binary subpart and insert file data Set BinaryMIMEPart=##class(%Net.MIMEPart).%New() Set contentdisp="form-data; name="_$CHAR(34)_"file"_$CHAR(34)_"; filename=" _$CHAR(34)_"task4059.txt"_$CHAR(34) Do BinaryMIMEPart.SetHeader("Content-Disposition",contentdisp) Set stream=##class(%FileBinaryStream).%New() Set stream.Filename="/home/tabaiba/prueba.txt" Do stream.LinkToFile("/home/tabaiba/prueba.txt") Set BinaryMIMEPart.Body=stream Do BinaryMIMEPart.SetHeader("Content-Type","text/plain") // Create text subpart Set TextMIMEPart=##class(%Net.MIMEPart).%New() Set TextMIMEPart.Body=##class(%GlobalCharacterStream).%New() Do TextMIMEPart.Body.Write("/home/tabaiba/prueba.txt") // specify some headers Set TextMIMEPart.ContentType="text/plain" Set TextMIMEPart.ContentCharset="us-ascii" Do TextMIMEPart.SetHeader("Custom-header",header) // Insert both subparts into the root part Do RootMIMEPart.Parts.Insert(BinaryMIMEPart) // create MIME writer; write root MIME message Set writer=##class(%Net.MIMEWriter).%New() // Prepare outputting to the HttpRequestStream Set SentHttpRequest=##class(%Net.HttpRequest).%New() Set status=writer.OutputToStream(SentHttpRequest.EntityBody) if $$$ISERR(status) {do $SYSTEM.Status.DisplayError(status) Quit} // Now write down the content Set status=writer.WriteMIMEBody(RootMIMEPart) if $$$ISERR(status) {do $SYSTEM.Status.DisplayError(status) Quit} Set SentHttpRequest.Server="congrio" Set SentHttpRequest.Port = 8080 Set ContentType= "multipart/form-data; boundary="_RootMIMEPart.Boundary Set SentHttpRequest.ContentType=ContentType set url="alfresco/service/sample/upload.json?" _"alf_ticket=TICKET_caee62bf36f0ea5bd51194fce161f99092b75f62" set status=SentHttpRequest.Post(url,0) if $$$ISERR(status) {do $SYSTEM.Status.DisplayError(status) Quit} } ``` # 访问HTTP响应 发送`HTTP`请求后,请求的`HttpResponse`属性将更新。此属性是`%Net.HttpResponse`的实例。本节介绍如何使用`Response`对象。它包括以下主题: ## 访问响应的数据 HTTP响应的正文包含在响应的Data属性中。此属性包含流对象(特别是`%GlobalBinaryStream`)。要使用此流,请使用标准流方法:`Write()`、`WriteLine()`、`Read()`、`ReadLine()`、`Rewind()`、`MoveToEnd()`和`Clear()`。还可以使用流的`Size`属性。 请求的`ReadRawMode`属性控制如何读取响应正文。 - 默认情况下,此属性为False,并且InterSystems IRIS假定正文在响应的`HTTP`标头中指定的字符集内(并相应地转换该字符集)。 - 如果此属性为true,InterSystems IRIS将以原始模式读取正文(不执行字符集转换)。 还可以使用`OutputToDevice()`方法,该方法将完整响应写入当前设备。标头的顺序与Web服务器生成的顺序不同。 下面是一个简单的示例,在该示例中,我们将响应流复制到文件并保存: ```java /// w ##class(PHA.TEST.HTTP).Stream() ClassMethod Stream() { set request=##class(%Net.HttpRequest).%New() set request.Server="tools.ietf.org" set request.Https=1 set request.SSLConfiguration="yx" set status=request.Get("/html/rfc7158") if $$$ISERR(status) { do $system.OBJ.DisplayError() } else { set response=request.HttpResponse } Set file=##class(%FileCharacterStream).%New() set file.Filename="e:/temp/rfc7158.txt" set status=file.CopyFrom(response.Data) if $$$ISERR(status) { do $system.OBJ.DisplayError() } do file.%Close() q "" } ``` ## 按名称获取HTTP标头 `%Net.HttpResponse`类将其`HTTP`标头存储在InterSystems IRIS多维数组中。要访问标头,请使用以下方法: ### GetHeader() 返回给定头的值。 ### GetNextHeader() 返回给定标头之后的下一个标头的名称。 这些方法中的每一个都只有一个参数,即HTTP标头的名称字符串。 还可以使用`OutputHeaders()`方法,该方法将HTTP标头写入当前设备(尽管它们的生成顺序不同)。 ## 访问有关响应的其他信息 `%Net.HttpResponse` 类提供了存储HTTP响应其他特定部分的属性: - `StatusLine`存储HTTP状态行,这是响应的第一行。 - `StatusCode`存储HTTP状态码。 - `ReasonPhrase`存储与`StatusCode`对应的人类可读的原因。 - `ContentInfo`存储关于响应体的附加信息。 - `ContentType`存储了`Content-Type:`标头的值。 - `HttpVersion`表示发送响应的web服务器所支持的HTTP版本。
文章
姚 鑫 · 七月 7, 2021

第三十章 从类生成XML架构

# 第三十章 从类生成XML架构 本章介绍如何使用`%XML.Schema`从启用了XML的类生成XML架构。 # 概述 要生成为同一XML命名空间中的多个类定义类型的完整架构,请使用`%XML.Schema`构建架构,然后使用`%XML.Writer`为其生成输出。 # 从多个类构建架构 要构建XML架构,请执行以下操作: 1. 创建`%XML.Schema`实例。 2. 可以选择设置实例的属性: - 若要为任何其他未分配的类型指定命名空间,请指定`DefaultNamespace`属性。默认值为`NULL`。 - 默认情况下,类及其属性的类文档包含在模式的``元素中。 要禁用此功能,请将`IncludeDocumentation`属性指定为0。 注意:必须在调用`AddSchemaType()`方法之前设置这些属性。 3. 调用实例的`AddSchemaType()`方法。 ```java method AddSchemaType(class As %String, top As %String = "", format As %String, summary As %Boolean = 0, input As %Boolean = 0, refOnly As %Boolean = 0) as %Status ``` - class是支持xml的类的完整包名和类名。 - top 是可选的; 如果指定,它将覆盖该类的类型名。 - format指定此类型的格式。 它必须是`"literal"`(文字格式,默认),`"encoded"`(用于SOAP编码),`"encoded12"`(用于SOAP 1.2编码),或`"element"`。 值`“element”`与元素位于顶层的文字格式相同。 - summary,如果为true,将导致InterSystems IRIS启用xml的类的`XMLSUMMARY`参数。 如果指定了此参数,则模式将只包含该参数列出的属性。 - input,如果为true,将导致InterSystems IRIS获取输入模式,而不是输出模式。 在大多数情况下,输入模式和输出模式是相同的; 如果为类的属性指定`XMLIO`属性参数,则它们是不同的。 - refOnly如果为true,将导致InterSystems IRIS仅为引用的类型生成模式,而不是为给定的类和所有引用的类型生成模式。 这个方法返回一个应该被检查的状态。 4. 根据需要重复前面的步骤。 5. 如果要定义导入模式的位置,可以调用`DefineLocation()`方法。 ```java method DefineLocation(namespace As %String, location As %String) ``` namespace 是一个或多个引用类使用的名称空间,位置是对应模式(XSD文件)的URL或路径和文件名。 可以重复调用此方法来为多个导入的模式添加位置。 如果不使用这个方法,模式会包含一个``指令,但是不会给出模式的位置。 6. 要定义额外的``指令,可以调用`DefineExtraImports()`方法。 ```java method DefineExtraImports(namespace As %String, ByRef imports) ``` namespace是``指令应该添加到的命名空间,imports是一个多维数组,形式如下: Node| Value ---|--- `arrayname("namespace URI")` |字符串,给出此名称空间的模式(XSD文件)的位置。 # 为架构生成输出 按照上一节所述创建`%XML.Schema`的实例后,请执行以下操作以生成输出: 1. 调用实例的`GetSchema()`方法将架构作为文档对象模型(DOM)的节点返回。 此方法只有一个参数:模式的目标命名空间的URI。该方法返回`%XML.Node`的一个实例,该实例在“将XML文档表示为DOM”一章中介绍。 如果模式没有命名空间,请使用`“”`作为`GetSchema()`的参数。 2. 可以选择修改此DOM。 3. 要生成架构,请执行以下操作: a. 创建`%XML.Write`的实例,并可选择设置属性(如缩进)。 b. 可以选择调用编写器的`AddNamespace()`方法和其他方法,将名称空间声明添加到`` 元素。 因为架构可能引用简单的XSD类型,所以调用`AddSchemaNamespace()`来添加XML模式命名空间很有用。 c. 使用架构作为参数,调用编写器的`DocumentNode()`或`Tree()`方法。 # 示例 ## 简单的示例 第一个示例显示了基本步骤: ```java Set schemawriter=##class(%XML.Schema).%New() //添加类和包(例如) Set status=schemawriter.AddSchemaType("Facets.Test") //通过其URI(在本例中为NULL)检索架构 Set schema=schemawriter.GetSchema("") //create writer Set writer=##class(%XML.Writer).%New() Set writer.Indent=1 //use writer Do writer.DocumentNode(schema) ``` ## 更复杂的架构示例 ```java Class SchemaWriter.Person Extends (%Persistent, %XML.Adaptor) { Parameter NAMESPACE = "http://www.myapp.com"; Property Name As %Name; Property DOB As %Date(FORMAT = 5); Property PatientID as %String; Property HomeAddress as Address; Property OtherAddress as AddressOtherNS ; } ``` `Address`类定义在相同的XML名称空间(`“http://www.myapp.com”`)中,而`OtherAddress`类定义在不同的XML名称空间(`“http://www.other.com”`)中。 `Company`类也被定义在XML名称空间`“http://www.myapp.com”`中。 其定义如下: ```java Class SchemaWriter.Company Extends (%Persistent, %XML.Adaptor) { Parameter NAMESPACE = "http://www.myapp.com"; Property Name As %String; Property CompanyID As %String; Property HomeOffice As Address; } ``` 注意,不存在连接`Person`和`Company`类的属性关系。 要为命名空间`"http://www.myapp.com"`生成模式,我们可以使用以下方法: ```java ClassMethod Demo() { Set schema=##class(%XML.Schema).%New() Set schema.DefaultNamespace="http://www.myapp.com" Set status=schema.AddSchemaType("SchemaWriter.Person") Set status=schema.AddSchemaType("SchemaWriter.Company") Do schema.DefineLocation("http://www.other.com","c:/other-schema.xsd") Set schema=schema.GetSchema("http://www.myapp.com") //create writer Set writer=##class(%XML.Writer).%New() Set writer.Indent=1 Do writer.AddSchemaNamespace() Do writer.AddNamespace("http://www.myapp.com") Do writer.AddNamespace("http://www.other.com") Set status=writer.DocumentNode(schema) If $$$ISERR(status) {Do $system.OBJ.DisplayError() Quit } } ``` 输出如下: ```xml ``` 请注意以下几点: - 模式包括`Person`及其所有引用的类的类型,以及`Company`及其所有引用的类的类型。 - ``指令导入了`OtherAddress`类使用的命名空间; 因为我们使用了`DefineLocation()`,所以这个指令还指示了相应模式的位置。 - 因为我们在调用`DocumentNode()`之前使用了`AddSchemaNamespace()`和`AddNamespace()`,所以``元素包含了名称空间声明,它为这些名称空间定义了前缀。 - 如果我们没有使用`AddSchemaNamespace()`和`AddNamespace()`, ``将不会包含这些名称空间声明,模式将会如下所示: ```xml ... ```
文章
姚 鑫 · 七月 10, 2021

Caché XML

# Caché XML # [第一章 InterSystems XML工具简介☆☆☆☆](https://cn.community.intersystems.com/post/第一章-intersystems-xml工具简介) # [第二章 从对象写入XML输出☆☆☆☆☆](https://cn.community.intersystems.com/post/第二章-从对象写入xml输出) # [第三章 指定输出的字符集☆☆☆☆☆](https://cn.community.intersystems.com/post/第三章-指定输出的字符集) # [第四章 添加命名空间声明☆☆☆☆☆](https://cn.community.intersystems.com/post/第四章-添加命名空间声明) # [第五章 生成XML元素☆☆☆☆☆](https://cn.community.intersystems.com/post/第五章-生成xml元素) # [第六章 控制名称空间的使用☆☆☆☆☆](https://cn.community.intersystems.com/post/第六章-控制名称空间的使用) # [第七章 控制命名空间分配的外观☆☆☆☆☆](https://cn.community.intersystems.com/post/第七章-控制命名空间分配的外观) # [第八章 Other Options of the Writer☆☆☆☆☆](https://cn.community.intersystems.com/post/第八章-other-options-writer) # [第九章 将XML导入到对象中☆☆☆☆☆](https://cn.community.intersystems.com/post/第九章-将xml导入到对象中) # [第十章 XML元素和属性☆☆☆☆☆](https://cn.community.intersystems.com/post/第十章-xml元素和属性) # [第十一章 重新定义读取器处理相关对象的方式☆☆☆☆☆](https://cn.community.intersystems.com/post/第十一章-重新定义读取器处理相关对象的方式) # [第十二章 XML其他示例☆☆☆☆☆](https://cn.community.intersystems.com/post/第十二章-xml其他示例) # [第十三章 将XML文档表示为DOM☆☆☆☆☆](https://cn.community.intersystems.com/post/第十三章-将xml文档表示为dom) # [第十四章 XML获取当前节点信息☆☆☆☆☆](https://cn.community.intersystems.com/post/第十四章-xml获取当前节点信息) # [第十五章 XML检查属性☆☆☆☆☆](https://cn.community.intersystems.com/post/第十五章-xml检查属性) # [第十六章 创建或编辑DOM☆☆☆☆☆](https://cn.community.intersystems.com/post/第十六章-创建或编辑dom) # [第十七章 加密XML文档☆☆☆](https://cn.community.intersystems.com/post/第十七章-加密xml文档) # [第十八章 签署XML文档☆☆☆](https://cn.community.intersystems.com/post/第十八章-签署xml文档) # [第十九章 使用%XML.TextReader☆☆☆☆☆](https://cn.community.intersystems.com/post/第十九章-使用xmltextreader) # [第二十一章 使用%XML.TextReader 导航文档☆☆☆☆☆](https://cn.community.intersystems.com/post/第二十一章-使用xmltextreader-导航文档) # [第二十二章 计算XPath表达式☆☆☆☆☆](https://cn.community.intersystems.com/post/第二十二章-计算xpath表达式) # [第二十三章 执行XSLT转换☆☆☆](https://cn.community.intersystems.com/post/第二十三章-执行xslt转换) # [第二十四章 执行XSLT转换☆☆☆](https://cn.community.intersystems.com/post/第二十四章-执行xslt转换) # [第二十五章 添加和使用XSLT扩展函数☆☆☆](https://cn.community.intersystems.com/post/第二十五章-添加和使用xslt扩展函数) # [第二十六章 定制SAX解析器的使用方式☆☆☆☆](https://cn.community.intersystems.com/post/第二十六章-定制sax解析器的使用方式) # [第二十七章 定制SAX解析器的执行自定义实体解析☆☆☆☆](https://cn.community.intersystems.com/post/第二十七章-定制sax解析器的执行自定义实体解析) # [第二十八章 定制SAX解析器创建自定义内容处理程序☆☆☆☆](https://cn.community.intersystems.com/post/第二十八章-定制sax解析器创建自定义内容处理程序) # [第二十九章 从XML架构生成类☆☆☆☆](https://cn.community.intersystems.com/post/第二十九章-从xml架构生成类) # [第三十章 从类生成XML架构☆☆☆☆](https://cn.community.intersystems.com/post/第三十章-从类生成xml架构) # [第三十一章 检查命名空间和类☆☆☆☆](https://cn.community.intersystems.com/post/第三十一章-检查命名空间和类) # [第三十二章 XML基础知识概念☆☆☆☆☆](https://cn.community.intersystems.com/post/第三十二章-xml基础知识概念) # Caché XML 在CSDN 上 # [第一章 InterSystems XML工具简介☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/117734468) # [第二章 从对象写入XML输出☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/117765426) # [第三章 指定输出的字符集☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/117804741) # [第四章 添加命名空间声明☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/117837881) # [第五章 生成XML元素☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/117867002) # [第六章 控制名称空间的使用☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/117898116) # [第七章 控制命名空间分配的外观☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/117928000) # [第八章 Other Options of the Writer☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/117946239) # [第九章 将XML导入到对象中☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/117980776) # [第十章 XML元素和属性☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118015143) # [第十一章 重新定义读取器处理相关对象的方式☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118046952) # [第十二章 XML其他示例☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118066297) # [第十三章 将XML文档表示为DOM☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118079066) # [第十四章 XML获取当前节点信息☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118099092) # [第十五章 XML检查属性☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118141298) # [第十六章 创建或编辑DOM☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118173945) # [第十七章 加密XML文档☆☆☆](https://yaoxin.blog.csdn.net/article/details/118205925) # [第十八章 签署XML文档☆☆☆](https://yaoxin.blog.csdn.net/article/details/118240046) # [第十九章 使用%XML.TextReader☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118265395) # [第二十章 使用%XML.TextReader 节点属性☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118291334) # [第二十一章 使用%XML.TextReader 导航文档☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118324134) # [第二十二章 计算XPath表达式☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118353276) # [第二十三章 执行XSLT转换☆☆☆](https://yaoxin.blog.csdn.net/article/details/118378341) # [第二十四章 执行XSLT转换☆☆☆](https://yaoxin.blog.csdn.net/article/details/118404243) # [第二十五章 添加和使用XSLT扩展函数☆☆☆](https://yaoxin.blog.csdn.net/article/details/118433664) # [第二十六章 定制SAX解析器的使用方式☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118456474) # [第二十七章 定制SAX解析器的执行自定义实体解析☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118478683) # [第二十八章 定制SAX解析器创建自定义内容处理程序☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118510180) # [第二十九章 从XML架构生成类☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118538567) # [第三十章 从类生成XML架构☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118565357) # [第三十一章 检查命名空间和类☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118594282) # [第三十二章 XML基础知识概念☆☆☆☆☆](https://yaoxin.blog.csdn.net/article/details/118629407) # 预告 下一期系列将用一个月的时间连载,**《Caché File》**,**《Caché 关键字大全》**,敬请期待。 # 交流群 - QQ群号:410039091 - 笔者QQ:454115408 - 公众号:技术理科直男 - [intersys版主:姚鑫](https://cn.community.intersystems.com/user/236891/posts) ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f9VqwzNP-1608850948003)(3E1D939266954ED48BDAEA9B8086B11E)\]](https://img-blog.csdnimg.cn/20201225070433434.png) # 大型免费课程,进群410039091获取课程目录 - 适合所有阶段程序员,总有一款你遗漏的知识点! ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210607145017460.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3lhb3hpbjUyMTEyMw==,size_16,color_FFFFFF,t_70#pic_center)
文章
Louis Lu · 四月 9, 2022

使用SQL查询返回结果集数量有偏差的问题解答 --- 检查索引是否有效

此文章也是对问题 在不重建的情况下插入索引Inserting an index without reconstruction 的一种解释 在使用SQL语言对 InterSystems IRIS 中的表进行查询时,有时候会发现返回的结果与实际有出入,特别是使用count() 函数,或者select 查询时,返回的结果少于实际应返回的值。这种情况往往是由于数据表格的索引值出了问题。 索引出问题的主要原因可能是: 表中先有数据,后创建的索引定义,并且定义之后没有重新生成索引。 对保存数据的global直接操作。如果是使用对象或者sql的方式操作数据,相应的索引都会自动更新,但是如果直接对global操作,则不会自动更新索引。 对保存索引的global直接操作。 要解决或者要检查是不是索引引发的问题,可以使用%ValidateIndices()函数,它有两种方式使用 $SYSTEM.OBJ.ValidateIndices(classname,idxList,autoCorrect,lockOption,multiProcess) 或者 ##class(classname).%ValidateIndices(idxList,autoCorrect,lockOption,multiProcess) 两种使用方法最大的差别是:$SYSTEM.OBJ.ValidateIndices()方法会同时检查继承于该表的子表的索引,而##class(classname).%ValidateIndices()不检查子表的索引。 函数参数: idxList, ""代表检查所有索引,或者设定检查的索引项。默认为检查所有索引。 autoCorrect, 是否自动纠正错误。默认为0,不自动纠正。 lockOption, 执行过程中执行的锁的操作,0 - 完全不进行锁定 1 - 在检查每一行时进行共享锁定 2 - 对整个表进行独占锁定。默认=1 multiProcess, 在允许的情况下使用多进程执行。$SYSTEM.OBJ.ValidateIndices() 默认为 0,##class(classname).%ValidateIndices() 默认为 1. 例子: Do $SYSTEM.OBJ.ValidateIndices("Sample.Company",$lb("NameIdx"),1,1) Do ##class(Sample.Company).%ValidateIndices()
文章
姚 鑫 · 七月 28, 2021

类关键字SoapBodyUse,SqlCategory,SqlRowIdName,SqlRowIdPrivate

# 第三十三章 类关键字 - SoapBodyUse 指定此类中定义的任何`web method`的编码。此关键字仅适用于`web服务`和`web客户端`类。 # 用法 要指定此类的`web method`的输入和输出所使用的编码,请使用以下语法: ```java Class MyApp.MyClass [ SoapBodyUse = soapbodyuse ] { //class members } ``` 其中`soapbodyuse`是下列之一: - `literal` 文字(默认)—默认情况下,此类中的`web method`使用文字数据。也就是说,`SOAP`消息的``中的`XML`与`WSDL`中给出的模式完全匹配。 - `encoded` 编码—默认情况下,此类中的`web method`使用`SOAP`编码的数据。也就是说,`SOAP`消息的``中的`XML`使用了适合所使用的`SOAP`版本的`SOAP`编码,如以下规范所要求的: - `SOAP 1.1` (https://www.w3.org/TR/2000/NOTE-SOAP-20000508/Opens in a new window) - `SOAP 1.2` (https://www.w3.org/TR/soap12-part2/Opens in a new window) 重要提示:对于手动创建的`web服务`,该关键字的默认值通常是合适的。当使用`SOAP`向导从WSDL生成`web`客户端或服务时,InterSystems IRIS会将此关键字设置为适合该`WSDL`;如果修改该值,web客户端或服务可能不再工作。 # 详解 此关键字指定此类中定义的任何`web method`使用的默认编码。它还控制这个类的`ELEMENTQUALIFIED`和`XMLELEMENT`参数的默认值,这将在本主题的一个小节中讨论。 可以通过使用`SoapBodyUse`方法关键字或`SoapBodyUse`查询关键字,为单个方法重写此关键字。 # 对子类的影响 此关键字不是继承的。 # 默认 默认值为文字。(`SOAP`标准V1.1指定`web method`应该使用`SOAP`编码。但是,大多数`SOAP`客户端(包括`.NET`)都使用文字样式。) # WSDL的关系 `SoapBodyUse`关键字指定了`WSDL`的``部分中``元素的`Use`属性的值。例如,如果`SoapBodyUse`是字面意思,则`WSDL`可能如下所示: ```xml ...
文章
Chang Liu · 九月 22, 2022

在国产系统上安装Healthconnect2021

1,准备 本次安装环境:Kylin-Server-10-SP2-Release-Build09-20210524-x86_64.iso 安装系统适配的对应版本:HealthConnect-2021.1.2.338.0-lnxubuntux64.tar.gz;ISCAgent-2021.1.2.338.0-lnxubuntux64.tar.gz 系统语言选择:English(必要) 2,安装HealthConnect+webgateway 2.1 新建所需用户组 groupadd iscagent 2.2 解压文件 2.3 安装 本次安装,使用root用户及root用户组安装,超级端口改为51773 3,安装ISCAgent 3.1安装说明 ISCAgent是healthconnect的镜像服务,若是单机使用,则不需要安装。 3.2 解压文件 3.3 安装 3.3 加入服务 3.3.1 新建文件 在/etc/systemd/system 下创建文件,ISCAgent.service,内容如下: [Unit] Description=InterSystems Agent After=syslog.target network-online.target [Service] Environment=LD_LIBRARY_PATH=/usr/local/etc/irissys Environment=COMLIB=/usr/local/etc/irissys ExecStart=/usr/local/etc/irissys/ISCAgent Type=forking PIDFile=/var/run/ISCAgent.pid KillMode=process [Install] WantedBy=multi-user.target 其中,/usr/local/etc/irissys为ISCAgent服务安装默认目录。 3.3.2 修改文件属性 chmod 755 ISCAgent.service3.3.3 重新启动systemctl systemctl daemon-reload 3.3.4 启动服务 systemctl start ISCAgent.service 3.3.5 查看服务状态 systemctl status ISCAgent.service 如下: 4, 防火墙配置 firewall-cmd --zone=public --add-port=51773/tcp --permanent firewall-cmd --zone=public --add-port=52773/tcp --permanent firewall-cmd --zone=public --add-port=2188/tcp --permanent (--permanent永久生效,没有此参数重启后失效) 重载生效: firewall-cmd --reload 5,镜像配置 5.1 主机配置 创建镜像 5.2 备机配置 加入故障转移 hc为HealthConnect的安装实例名称 6 安装过程中出现的问题 6.1 描述 添加虚拟ip失败: 6.2 问题解决 发现virtualIP.sh中部分代码在中文系统中执行时有问题,则将系统换成英文系统则可以解决这个问题。 The End 可以,很实用 找了好久,国产系统适配先行者 很棒的分享! 友友写的真好 优秀 非常不错,总结到位 真的很不错 加精了!
公告
Claire Zheng · 八月 26, 2022

开发者社区2022年7月发布

欢迎了解2022年7月社区的最新动态! 最近我们进行了很多有趣的提升,以优化你在InterSystems开发者社区的体验: 📌 社交网络通知功能 📌 改进了订阅设置 📌 全新的“关于我们”页面 📌 更友好的“会员”页面 我们来详细看看这些改进! 通知 从现在开始,你会在你页面右上角(靠近头像照片)看到新的通知,点击小铃铛,你就可以看到所有最新的通知,点击即可获得更详细的信息: 点击“查看全部”即可抵达“通知”页面,在那里你可以看到所有通知信息。 在此页面中,您可以“将所有内容标记为已读(Mark all as read)”或通过链接进入生成通知的页面。并管理订阅设置。 订阅 我们改进了订阅页面,希望你们会觉得这个页面变得更加友好 您可以选择从开发者社区接收哪些通知,无论您是通过电子邮件还是通过网站接收。你可以在你账户的“订阅”部分找到它。 关于我们 我们 已经提到 过,我们创建了一些全新的“关于我们”页面。但是这些按钮太可爱了,值得我再提一次🥰 你可以在顶部菜单的About部分找到它——> 关于我们: 会员 另一个我们已经调整的是“会员”页,希望可以让你感到更便利。我们添加了一个新的“最新活动”列。您可以通过单击任何列的名称对其进行排序。 暂时就这些吧!希望您赞成我们所有的改进! 下次见!
文章
Michael Lei · 六月 8, 2023

2023全球峰会,完美收官!期待来年!

嗨社区! 我们已经到了#GlobalSummit23 的尾声——最后一天!这是我们的一天——程序员的一天。今天的主题演讲都致力于开发人员、他们的成长、抱负和创新。 更有趣的是,在主题演讲中,@Dean.Andrews2971谈到了开发者社区等话题。你现在可以在Youtube上观看这部分,或者晚些有更新的版本: 午餐后,出席全球峰会的所有主持人齐聚一堂,参加名为“如何充分利用 InterSystems 开发人员生态系统”的会议。今年参加的人比去年多了很多! @Dean.Andrews2971 谈到了社区、全球大师、开放交流、创意门户的新闻和功能,以及人们如何从中受益。 然后是任何想说几句话的人的开放季节😊 @Dmitry.Maslennikov 英文社区 @José.Pereira 葡语社区 @Muhammad.Waseem 英文社区 西语社区的@Francisco.López1549 法文社区的@Lorenzo Scalese DC 英文社区的@Scott Roth 这是所有在场主持人的照片(从左到右):@José.Pereira、@Muhammad.Waseem、@Djeniffer.Greffin7753、@Scott.Roth、@Dean.Andrews2971、@John.Murray、@Irène.Mykhailova ,@Lorenzo.Scalese,@Francisco.López1549。 多么好的一群人! 我希望在场的每个人都喜欢这 45 分钟。 会议结束后,几乎是最后的冰淇淋和咖啡时间了!但在我看见@Guillaume.Rongier7183完成他关于他最喜欢的主题 Python 的演讲之前。 我们联系了@Dmitry.Maslennikov、@Murray.Oldfield 以及在上述会议期间加入的我们的新社区成员 - @Vladimir.Babarykin。 在最后的告别之后,我真的从 Caelestinus 抓住了@Vita.Tsareva 以上就是全部内容,希望您喜欢我的全球峰会进展情况的故事。 在评论中分享您对全球峰会的看法。您认为 2024 年全球峰会的举办地点是什么?这是一个有趣的话题😀到时候见!
文章
Jingwei Wang · 七月 7, 2023

FAQ常见问题系列 - 互联互通套件基础问题

本篇文章主要介绍互联互通套件的一些基础问题: 基于互联互通套件通过互联互通成熟的测评的实施工作量 电子病历共享文档部分:需要客户将业务系统数据灌入CCH套件SQL模型中 服务部分:在平台做消息改造,或者直接做业务系统接口改造 基于互联互通套件通过电子病例五级+互联互通成熟度测评四级需要的最低人员配备和项目总耗时 需要了医院现有业务系统和人员配备,做进一步评估及分析 目标只是通过互联互通成熟度测评需不需要FHIR 不需要,如果只是过测评,只需要互联互通套件基础版就够了 BI相关功能如何实现 可以使用DeepSee,基于Cubes做数据分析及钻取 如何使用Java进行快速开发 可以使用PEX,支持Java开发,但是如果使用Production,推荐使用内置开发语言ObjectScript,学习成本更低,未来开发新特性能力更强大 有没有自带的ETL工具 InterSystems 互联互通套件中没有ETL工具,但是支持所有ETL工具的连接 发送失败消息是否有记录 所有错误消息都能够在平台监控到,且可以进行转发或者重发 有没有按照单个服务流程进行整个业务流程的修改和查看 平台内所有服务都可以按照类别区分,也可以按照服务查看业务流程,但是没有按照单个服务修改整个业务流程的界面