搜索​​​​

清除过滤器
文章
姚 鑫 · 七月 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)
文章
Hao Ma · 十一月 22, 2022

ObjectScript的命名规范

命名规范,英文叫"name convention", 是对写代码取名字的一些”共识“。也就是说, 你可以不遵守,但大家都选择了遵守,照者一个规范来。为什么呢?因为有社区,大家要共享代码, 你不照着规矩来, 别人会鄙视你, 懒的用你的代码。 ObjectScript以前没什么社区,大家各写各的, 使用ObjectScript的大公司也没谁把自己的代码拿出来共享。因此,个人开发者基本就是参考官方InterSystems的命名规范。举个例子, 比如以下的代码: ```java Class Ens.Util.ResponseBodyMethods { property NoFailWhileDisconnected as %Boolean; property FirstName as %String; parameter SETTINGS = "ReplyCodeActions"; method OnKeepalive(pAdapterStatus As %Status) as %String { return "okay" } } ``` 我来简单总结一下: - **包名和类名**:Pascal格式,也就是首字母大写。其中%开头的是官方独占, - **Property名字**:首字母大写 - **method Name**:同上。但出入参用的是驼峰格式,也就是第一个单词小写,后面单词大写开头。 - **Parameter Name**:常量。 官方的代码都是这个规范吗? 大体上是,但也有例外, 比如%xsd包,包名类名全小写, 像这样: %xsd.string。这个从Caché年代就这样,我是不明白为什么这个包这么特殊。 到了IRIS上,更多瞎写了, 比如这个: [%SYSTEM.external.SQL](https://docs.intersystems.com/iris20222/csp/documatic/%25CSP.Documatic.cls?LIBRARY=%25SYS&CLASSNAME=%25SYSTEM.external.SQL)。不光是它,我发现很多和“external“相关的包名,都开始用小写了,写在代码里是这样的: %system.external.help(), %system.dotnet.SQL.addPath()。后面一个为什么SQL大小,dotnet小写,我也是没想明白。 然后,重要的来了。 InterSystems Developer Community贴出了这样的[community代码命名规范](https://community.intersystems.com/post/objectscript-package-manager-naming-convention)。它是怎么被推广的呢? 通过zpm,也就是社区里的代码ObjectScript的包管理工具。曾经一度你要参加社区的代码比赛,就必须使用zpm打包,而zpm对使用这个代码规范有硬要求,所以这个convention得到了一定程度的接受,能看到越来越多的开发者这么写代码了。 原文上面有链接,这里说最重要的: **package名字全小写,class名字用首字母大写**。比如class会定义成: ```java class company.project.subpackage.TheClass{ ... } ``` 这基本上是借鉴Java。作者也说了:*The approach borrowed from the naming convention for java classes.* 作者还做了个解释:全小写的Package名字避免了和class或者interface的名字冲突。这句话我不是很明白。 我觉得网友只所以接受它,纯粹就是java和python用惯了,烦大写的类名。 如果都是c++, c#的程序员,估计这个命名规范还得有得吵。 我这里只说了包名类名, 其他的method, property, 变量的命名什么的,还包括github上repo起名字的规范, 有兴趣去原文看看吧。 我是挺喜欢这个规范的。 唯一有点不满意的是:Java中定义Package name 和class name不是连着写在一起的,比如下面: ```java package org.springframework.asm; public abstract class AnnotationVisitor { ... } ``` 所以你很少能看到包名和类名连写在一起的情况,所以小写的小写, 大写的大写,都不挨着。而ObjectScript的类定义一定要写全了, 上面的定义如果在ObjectScript里就是: ```java public class org.springframework.asm.AnnotationVisitor { ... } ``` 因此这样的写法会有个视觉上的大小写的落差。 我属于没事找事的。 结论: 社区有了命名规范,矮骡子们纷纷表示支持。 按这个convention,Tony老师如果去写一个示例代码贡献给社区的话,可能是这样的 ```java class com.dhc.tony.demo.xml.TestUtils { property noFailWhileDisconnected as %Boolean; property firstname as %String; parameter SETTINGS = "ReplyCodeActions"; method onKeepalive(pAdapterStatus As %Status) as %String { return "okay" } } ``` 我们目前还都是首字母大写的驼峰 之后是要统一改用zpm的命名规范吗。。。
文章
Michael Lei · 七月 4, 2021

Gartner DBMS 魔力象限中的主要领先数据库产品功能对比

大家好, 在本文中,我比较了 Gartner 最新DBMS 魔力象限中的主要领先数据库产品的功能。 请见按现有功能数量排序的列表。 1. InterSystems IRIS 2020.3 - 60 个功能 (https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls) 2. Oracle Database 21c - 54 个功能 (https://docs.oracle.com/en/database/oracle/oracle-database/index.html) 3. Microsoft SQL Server - 45 个功能 (https://docs.microsoft.com/en-us/sql/sql-server/?view=sql-server-ver15) 4. AWS Aurora - PostgreSQL - 34 个功能 (https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/CHAP_AuroraOverview.html) 我只比较了功能,未进行任何性能比较(关于此内容,请参见性能测试:https://cn.community.intersystems.com/post/intersystems-iris%E6%95%B0%E6%8D%AE%E5%B9%B3%E5%8F%B0%EF%BC%9A%E6%95%B0%E6%8D%AE%E6%8E%A5%E6%94%B6%E9%80%9F%E5%BA%A6%E6%B5%8B%E8%AF%95)。 我使用了上面的产品官方文档链接。 请见比较表格: <colgroup><col style="width:245pt" width="327"><col style="width:88pt" width="118"><col style="width:122pt" width="162"><col style="width:150pt" width="200"><col style="width:146pt" width="195"></colgroup> 功能 InterSystemsIRIS 2020.3 OracleDatabase 21c MicrosoftSQL Server 2020 AWS Aurora -PostgreSQL 故障转移集群 有 有 有 有 镜像/数据复制 有 有 有 有 分布式缓存/内存中支持 有 有 有 有 备份/恢复 - 增量和完整 有 有 有 有 纵向缩放 有 有 有 有 针对 Insert、Update 和 Delete 进行横向缩放 有 有 无 无 针对 Select 进行横向缩放 有 有 有 有 分片集群 有 有 无 有 云支持和云管理器 有 有 有 有 Kubernetes 支持和 Kubernetes 管理器 有 有 有 有 Docker 支持 有 有 有 无 AWS 托管 有 有 有 有 Azure 托管 有 有 有 无 Google Cloud 托管 有 有 有 无 托管云 有 有 有 有 内部部署支持 有 有 有 无 多模型 - OO 有 无 无 无 多模型 - 文档 - JSON 有 有 有 有 多模型 - XML 有 有 有 有 多模型 - 键/值 有 无 无 无 多模型 - SQL 有 有 有 有 多模型 - 空间 无 有 有 有 多模型 - 图表 无 有 有 无 多模型 - OLAP 多维数据集 有 有 有 无 GIS 平台 无 有 无 无 本机 OO 编程语言 有 有 无 无 Java、.Net、Python、C/C++ 和 PHP 支持 有 有 有 有 Node.js 支持 有 有 有 有 ODBC/JDBC 支持 有 有 有 有 后端应用程序开发 有 有 无 无 前端应用程序开发 有 有 无 无 低代码 Web 应用程序开发 无 有 有 无 数据库应用程序开发 有 有 有 有 OData 支持 无 有 有 无 REST 服务 有 有 有 有 SOAP 服务 有 无 无 无 终端工具 有 有 有 有 IDE 支持 有 有 有 有 Web 管理/IDE 支持 有 有 有 有 嵌入 NLP 有 无 无 无 嵌入 AutoML 有 无 无 无 R/机器学习支持 有 有 有 有 PMML 有 无 无 无 业务报表服务器/开发 有 有 有 无 自主 AI 操作 无 有 无 无 非结构化文本注释/类似 Apache UIMA 有 有 无 无 Spark 支持 有 有 有 有 BI 工具 有 无 有 无 MDX 支持 有 有 有 无 互操作性连接器 有 无 无 无 BPEL/集成编排/工作流 有 无 无 无 ETL - 提取、转换和加载数据 有 无 无 无 IoT/MQTT 支持 有 无 无 无 EDI 支持 有 无 无 无 ESB 有 无 无 无 CDC - 变更数据捕获 有 有 有 有 RBAC 模型 有 有 有 有 LDAP 支持 有 有 有 有 双因素授权/身份验证支持 有 有 有 有 加密 有 有 有 有 标记 有 有 有 无 审计和跟踪 有 有 有 有 SAM 有 有 有 有 多操作系统支持 有 有 有 有 SAML/Oauth/OpenID 支持 有 有 有 有 性能调整 IDE/包 无 有 无 无 特权用户访问管理 无 有 无 无 API 管理 有 无 无 无 功能总数 61 54 45 34
文章
Michael Lei · 九月 15, 2022

示例:使用 Java + SpringBoot + Hibernate 和 IRIS 数据库创建 REST API

Spring Boot 是最常用来创建 REST API 和微服务的 Java 框架。 它可用于部署 Web 应用程序、可执行 Web 应用程序或桌面自包含应用程序,其中应用程序和其他依赖项打包在一起。 Spring Boot 允许执行许多功能,请参见: 注:要了解有关 SpringBoot 的信息,请参见官方网站 - https://spring.io/quickstart 要创建具有一个或多个微服务的 Web api 应用程序,可以使用 Spring IDE for Eclipse/VSCode,并使用向导配置上述将在应用程序中使用的技术,请参见: ![](/sites/default/files/inline/images/images/image(1388).png) 您可以选择技术并创建项目。 所有技术都将通过 maven 导入。 它就像一个可视化的 zpm。 所创建的项目有一个类用于为应用程序提供支持,其中包含所有所需内容(Web 和应用程序服务器,以及所有依赖项、微服务概念)。 此项目的完整源代码在以下 open exchange 项目中: https://openexchange.intersystems.com/package/springboot-iris-crud。 首先要配置 IRIS JDBC 驱动程序和 IRIS Hibernate 支持,为此,请将 jar 文件复制到 resources 文件夹,请参见: ![](/sites/default/files/inline/images/images/image(1390).png) 打开 pom.xml 以配置这些 jar 文件的依赖项,请参见: <dependency> <groupId>com.intersystems</groupId> <artifactId>intersystems-jdbc</artifactId> <version>3.2.0</version> <scope>system</scope> <systemPath>${project.basedir}/src/main/resources/intersystems-jdbc-3.2.0.jar</systemPath> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-iris</artifactId> <version>1.0.0</version> <scope>system</scope> <systemPath>${project.basedir}/src/main/resources/hibernate-iris-1.0.0.jar</systemPath> </dependency>   现在可以在 application.properties 中配置与 IRIS 数据库的连接,请参见: spring.datasource.username=_SYSTEM spring.datasource.url=jdbc:IRIS://iris:1972/USER spring.datasource.password=SYS spring.jpa.properties.hibernate.default_schema=dc_Sample #spring.jpa.hibernate.ddl-auto=update spring.datasource.driver-class-name=com.intersystems.jdbc.IRISDriver spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false spring.jpa.database-platform=org.hibernate.dialect.InterSystemsIRISDialect spring.datasource.sql-script-encoding=utf-8 server.tomcat.relaxed-query-chars=|,{,},[,] spring.jpa.show-sql=false spring.jpa.properties.hibernate.format_sql=true 下一步是创建一个映射到 IRIS 表的持久化 Java 类,请参见: package community.intersystems.springboot.app.model; import java.io.Serializable; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import com.fasterxml.jackson.annotation.JsonFormat; @Entity @Table(name = "Product") public class Product implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue (strategy = GenerationType.IDENTITY) private Long id; private String name; private String description; private Double height; private Double width; private Double weight; @Column(name="releasedate") @Temporal(TemporalType.DATE) @JsonFormat(pattern = "dd/MM/yyyy") private Date releaseDate; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Double getHeight() { return height; } public void setHeight(Double height) { this.height = height; } public Double getWidth() { return width; } public void setWidth(Double width) { this.width = width; } public Double getWeight() { return weight; } public void setWeight(Double weight) { this.weight = weight; } public Date getReleaseDate() { return releaseDate; } public void setReleaseDate(Date releaseDate) { this.releaseDate = releaseDate; } } 最后一步是创建一个仓库接口,以将您的持久化类作为 REST 服务公开(以 HATEOAS 模式),您无需执​​行 crud 操作,只需编写以下代码: package community.intersystems.springboot.app.repository; import org.springframework.data.jpa.repository.JpaRepository; import community.intersystems.springboot.app.model.Product; public interface ProductRepository extends JpaRepository<Product, Long> { } 现在,将您的应用程序作为 Spring Boot 应用程序运行: ![](/sites/default/files/inline/images/images/image(1389).png) 等待内部服务器启动,然后打开 localhost:8080。 Spring boot 将打开一个 API REST HAL 浏览器。 请参见以下图像记录: ![IRIS 与 Hibernate 配合运行](https://github.com/yurimarx/springboot-iris-crud/raw/master/iris-hibernate.gif) 更多详细信息,请参见我的应用程序示例。 我将所有内容一起打包成一个 Docker 项目,其中包含 2 个服务:IRIS 和 SpringBoot。 HATEOAS 模式非常适合 api url、路径和导航,更多详细信息,请自行百度。 祝使用愉快!
文章
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 可以,很实用 找了好久,国产系统适配先行者 很棒的分享! 友友写的真好 优秀 非常不错,总结到位 真的很不错 加精了!
文章
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 年全球峰会的举办地点是什么?这是一个有趣的话题😀到时候见!
公告
Claire Zheng · 八月 26, 2022

开发者社区2022年7月发布

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

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

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

SAM - 设置和添加非 IRIS 目标指标的技巧和提示

# SAM - 设置和添加非 IRIS 目标指标的技巧和提示 SAM(系统警报和监视)以“功能齐全”的 docker-compose 容器集的形式提供,只要启动就可以开始以默认的仪表板监视 IRIS 实例。 使用初始配置就可以很好地了解 SAM 功能并开始对 IRIS 系统进行基本监视。 但是,当开始监视多个系统并收集大量指标数据时,需要更改一些默认设置。 为了从 SAM 获取更多价值,您还会想要添加来自其他数据源(目标)的指标。 以下技巧将帮助您在生产环境中部署 SAM,从多个目标收集指标并将这些指标组合到您自己的仪表板和图表中。 此外,您还将看到一些可能有助于探索 SAM 容器和应用程序的命令。 > *注意:*我应该指出,其中一些技巧和提示可能不是最佳做法;这更像是一个日志,记录了我第一次如何配置 SAM 来监视相同系统上的多个服务器和非 IRIS 目标的基准。 如果您有建议,请在评论中指教 ;) 所以,记住本帖可能会随着时间的推移而有所变化,让我们开始吧; --- 在下面的技巧中,有重启 docker 以及启动和停止 SAM 的操作。 请通读这些技巧,确定哪些适合您,然后按照下面的相同顺序执行。 ## 1. 确保有足够的空间用于 SAM 数据库 默认情况下,docker 容器将文件存储在根 (/) 文件系统。 SAM 不需要很多 CPU 或内存资源;但是,指标收集将占用空间。 > 指标需要的存储容量“视情况而定”。 虽然在开始监视之前可能无法明确数据库大小,但大致上,在抓取周期为 15 秒的情况下,监视 10 个 IRIS 虚拟机以及操作系统指标大约消耗 50GB 存储。 策略包括:增加监视实例的根存储,或更改数据库的卷位置。 我使用了以下命令来更改运行 docker 的虚拟机上的 docker 目录。 也许是杀鸡用了牛刀,但很管用。 - 停止 docker 并将 docker 文件复制到空间充足的文件系统(本例中为 /data/docker/data)。 见下面的示例: ```other [root@mysamserver lib]# sudo systemctl stop docker [root@mysamserver lib]# pwd /var/lib [root@mysamserver lib]# cp -rp docker /data/docker/data [root@mysamserver lib]# [root@mysamserver lib]# rm -rf docker ``` - 在 docker 配置文件中更新卷路径。 注意此文件还有一个网络设置“bip”(请参见注释:...) ```swift cat /etc/docker/daemon.json { "data-root": "/data/docker/data", "bip": "192.168.0.1/24" } ``` - 重启 docker ```swift sudo systemctl daemon-reload sudo systemctl restart docker systemctl status docker.service ``` ## 2. 设置 SAM 我假定您已在测试系统上设置 SAM,并熟悉它的基本操作:添加集群和实例,以及查看系统指标。 建议您花 20 分钟时间查看我在虚拟全球峰会 2020 上的展示,以了解安装步骤的概述,以及添加多个目标的运行指标时 SAM 的外观。 要观看此会议,请使用以下链接(您需要使用您的电子邮件注册): [DEV007 系统警报和监视](https://intersystems.6connex.com/event/virtual-summit/en-us/contents/434680/share?rid=Lobby&nid=804450) 登录到 SAM 门户并配置一些 IRIS 实例。 这会填充配置文件并提供向导。 `http://mysamserver:8080/api/sam/app/index.csp#/` > 注意:如果要添加多个实例,或者希望用脚本执行此步骤,可以通过 API 添加实例。 请参见文档。 ## 3. 升级到生产许可证 SAM 随附了一个 IRIS 社区版许可证。 有几个限制,包括 IRIS.DAT 限制为 10GB。 10GB 不足以长时间从多个目标收集数据。 请联系您的 InterSystems 联系人以获取生产许可证。 在没有编辑器的情况下,在精简的容器中更新许可证可能很棘手,我只是在 IRIS 容器上登录一个交互式会话,然后使用以下命令更新许可证密钥: - 打开 shell,切换目录至 mgr 文件夹(iris.key 文件的默认位置) ```swift docker exec -it sam_iris_1 bash cd /dur/iconfig/mgr ``` - 使用 unix“here 文档”更新密钥。 在“>”后面粘贴密钥文本。 在密钥文本后面,输入“>EOF”以提交命令。 然后输入“exit”退出 shell。 ```other cat [ConfigFile] FileType=InterSystems License Rev-A.1 LicenseID=999999 [License] LicenseCapacity=InterSystems IRIS 2020.2 Server for SAM:etc etc, the key you were sent by your InterSystems contact. >EOF exit ``` - 然后使用提供的 docker-compose shell 脚本停止再启动 SAM: ```swift ./stop.sh ./start.sh ``` - 可以通过访问系统管理门户或登录到 iris 实例并检查 messages.log 来检查许可证是否一切正常。 ```shell docker exec -it sam_iris_1 bash cd /dur/iconfig/mgr cat messages.log ``` ## 4. 在目标上安装其他 prometheus 导出程序 例如,prometheus 节点导出程序可显示各种硬件和内核相关的指标。 [节点导出程序文档](https://prometheus.io/docs/guides/node-exporter/) 通过请求(抓取)实例端点的指标,测试节点导出程序是否正常工作: ```swift curl my_target_server_name:9100/metrics ``` 您应该看到类似下面的信息: ```swift mylaptop:~ mo$ my_target_server_name:9100/metrics | more HELP go_gc_duration_seconds A summary of the GC invocation durations. # TYPE go_gc_duration_seconds summary go_gc_duration_seconds{quantile="0"} 4.8862e-05 go_gc_duration_seconds{quantile="0.25"} 7.5898e-05 go_gc_duration_seconds{quantile="0.5"} 9.2974e-05 go_gc_duration_seconds{quantile="0.75"} 0.000130664 go_gc_duration_seconds{quantile="1"} 0.000358762 go_gc_duration_seconds_sum 303.291715258 go_gc_duration_seconds_count 2.572586e+06 # HELP go_goroutines Number of goroutines that currently exist. # TYPE go_goroutines gauge go_goroutines 9 : : many many metrics will be displayed ``` 注意您可以对您的 IRIS 实例执行同样操作: ```swift mylaptop:~ mo$ curl my_target_server_name:52776/api/monitor/metrics | more iris_cpu_pct{id="AUXWD"} 0 iris_cpu_pct{id="CSPDMN"} 0 iris_cpu_pct{id="CSPSRV"} 0 iris_cpu_pct{id="ECPCliR"} 0 iris_cpu_pct{id="ECPCliW"} 0 iris_cpu_pct{id="ECPSrvR"} 0 iris_cpu_pct{id="ECPSrvW"} 0 : : many many metrics will be displayed ``` ## 5. 编辑配置文件以添加对新目标的抓取 例如,前一个技巧中的 node-exporter 实例。 配置文件将位于 SAM 的安装位置。 如下所示,可以看到 grafana 和 prometheus `yml` 配置文件。 ```plaintext [root@mysamserver sam-1.0.0.115-unix]# ls config docker-compose.yml readme.txt start.sh stop.sh [root@mysamserver sam-1.0.0.115-unix]# tree -x config config ├── alertmanager │   └── isc_alertmanager.yml ├── grafana │   ├── dashboard.json │   ├── dashboard-provider.yml │   ├── datasource.yml │   └── grafana.ini ├── nginx │   └── nginx.conf └── prometheus ├── isc_alert_rules.yml └── isc_prometheus.yml 4 directories, 8 files ``` ## 5.1 添加目标到 prometheus 以下示例是使用 SAM 中的配置 GUI 屏幕创建的 `isc_prometheus.yml` 文件。 该文件包含两个集群。 一个集群监视 sam 实例本身,另一个集群监视五个 IRIS 实例。 ```yaml alerting: alertmanagers: - static_configs: - targets: - alertmanager:9093 global: evaluation_interval: 15s scrape_interval: 15s remote_read: - url: http://iris:52773/api/sam/private/db/read remote_write: - url: http://iris:52773/api/sam/private/db/write rule_files: - ./isc_alert_rules.yml scrape_configs: - job_name: SAM metrics_path: /api/monitor/metrics scheme: http static_configs: - labels: cluster: "1" targets: - mysaminstance.mycompany.com:8080 - labels: cluster: "2" targets: - myiristarget1:52776 - myiristarget2:52776 - myiristarget3:52776 - myiristarget4:52776 - myiristarget5:52776 ``` - 要添加对其他运行 node-exporter 的目标的抓取,请将以下内容添加到 `isc_prometheus.yml` 文件的底部。 注意 API `metrics_path` 与 IRIS 不同。 ```yaml alerting: alertmanagers: - static_configs: - targets: - alertmanager:9093 global: evaluation_interval: 15s scrape_interval: 15s remote_read: - url: http://iris:52773/api/sam/private/db/read remote_write: - url: http://iris:52773/api/sam/private/db/write rule_files: - ./isc_alert_rules.yml scrape_configs: - job_name: SAM metrics_path: /api/monitor/metrics scheme: http static_configs: - labels: cluster: "1" targets: - iscsydsam.iscinternal.com:8080 - labels: cluster: "2" targets: - myiristarget1:52776 - myiristarget2:52776 - myiristarget3:52776 - myiristarget4:52776 - myiristarget5:52776 - job_name: node_shard1 metrics_path: /metrics scheme: http static_configs: - labels: cluster: "2" group: node targets: - myiristarget1:9100 - job_name: node_shard2 metrics_path: /metrics scheme: http static_configs: - labels: cluster: "2" group: node targets: - myiristarget2:9100 - job_name: node_shard3 metrics_path: /metrics scheme: http static_configs: - labels: cluster: "2" group: node targets: - myiristarget3:9100 - job_name: node_shard4 metrics_path: /metrics scheme: http static_configs: - labels: cluster: "2" group: node targets: - myiristarget4:9100 - job_name: node_shard5 metrics_path: /metrics scheme: http static_configs: - labels: cluster: "2" group: node targets: - myiristarget5:9100 ``` - 然后使用提供的 docker-compose shell 脚本停止再启动 SAM: ```swift ./stop.sh ./start.sh ``` SAM 现在从您通过 GUI 添加的 IRIS 实例以及相同实例上的 node-exporter 中收集指标。 # 6. 增加 Prometheus 收集指标的天数 在 SAM 的第一版中,您可以在 GUI 中更改收集指标的天数。 但是,我在显示所有指标时遇到一个问题。 在我弄清楚发生了什么之前,我更改了 Prometheus 中的保留天数,否则 SAM 将收集数据,但是您在 Grafana 的 Prometheus 查询中看不到指标。 在文件 `docker-compose.yml` 中用来安装 SAM 的层,更改 Prometheus 启动时设置的保留天数,例如在 `prometheus` 部分中,更新 `storage.tsdb.retention.time` 参数以匹配所需的保留天数: ```swift prometheus: command: - --web.enable-lifecycle - --config.file=/config/isc_prometheus.yml - --storage.tsdb.retention.time=30d ``` > 注意:在 SAM 的第一版中,最长保留天数为 30 天。 然后使用提供的 docker-compose shell 脚本停止再启动 SAM: ```swift ./stop.sh ./start.sh ``` ## 7. 创建您自己的仪表板 您可以向现有仪表板添加面板,也可以创建新的仪表板以满足您的监视需求。 这是一个很大的主题,所以留到下一个帖子再说。 不过,这里先帮助您上手。 在 SAM 屏幕上使用 `View in Grafana`(在 Grafana 中查看)按钮切换到 Grafana。 ![DraggedImage.png](https://res.craft.do/user/full/635e53bd-527a-1620-0e31-f8c3bdff1139/doc/CB3E6427-4D46-40C7-93DF-9E1FE801E814/C1AAEA2C-B8AF-4CF6-AB18-DD562971A9BC_2) 打开 Grafana 后,可以创建或编辑仪表板; ![DraggedImage-1.png](https://res.craft.do/user/full/635e53bd-527a-1620-0e31-f8c3bdff1139/doc/CB3E6427-4D46-40C7-93DF-9E1FE801E814/BC370FDF-308A-4917-9262-42AE286BDE8B_2) 网上有许多查询导出程序(如 node-exporter)的示例。 > 当可以显示 IRIS 系统指标(SAM 中的默认设置)、IRIS 应用程序指标(您需要将这些指标构建到应用程序中)以及其他指标(如 node-exporter 或由供应商创建的任何数量的指标)时,真正强大的功能才体现出来。 例如,[使用 SAM 和 cAdvisor 监视 Docker 容器](https://community.intersystems.com/post/monitor-docker-containers-using-sam-and-cadvisor)
文章
姚 鑫 · 六月 30, 2021

第二十三章 执行XSLT转换

# 第二十三章 执行XSLT转换概述 XSLT(Extensible StyleSheet Language Transformations,可扩展样式表语言转换)是一种基于XML的语言,用于描述如何将给定的XML文档转换为另一个XML或其他“人类可读”的文档。可以使用`%XML.XSLT`和`%XML.XSLT2`包中的类来执行`XSLT 1.0`和`2.0`转换。 注意:使用的任何XML文档的XML声明都应该指明该文档的字符编码,并且文档应该按照声明的方式进行编码。如果未声明字符编码, IRIS将使用本书前面的“输入和输出的字符编码”中描述的默认值。如果这些默认值不正确,请修改XML声明,使其指定实际使用的字符集。 # 在IRIS中执行XSLT转换概述 IRIS提供两个XSLT处理器,每个处理器都有自己的API: - `Xalan`处理器支持`XSLT 1.0`。`XML.XSLT`包为该处理器提供API。 - `Saxon`处理器支持`XSLT 2.0`。`%XML.XSLT2`程序包为该处理器提供API。 `XML.XSLT2` API通过到`XSLT 2.0`网关的连接向`Saxon`发送请求。网关允许多个连接。这意味着,例如,可以将两个独立的 IRIS进程连接到网关,每个进程都有自己的一组编译样式表,同时发送转换请求。 使用Saxon处理器,编译的样式表和`isc:Evaluate`缓存是特定于连接的;必须管理自己的连接才能利用这两个特性。如果打开连接并创建编译样式表或计算填充`isc:Evaluate`缓存的转换,则在该连接上计算的所有其他转换都将访问编译样式表和`isc:Evaluate`缓存条目。如果打开新连接,其他连接(及其编译的样式表和缓存)将被忽略。 这两个处理器的API相似,不同之处在于`%XML.XSLT2`中的方法使用另一个参数来指定要使用的网关连接。 要执行`XSLT`转换,请执行以下操作: 1. 如果使用的是`Saxon`处理器,请按照下一节所述配置`XSLT`网关服务器。或使用默认配置。 如果使用的是`Xalan`处理器,则不需要网关。 系统会在需要时自动启动网关。或者也可以手动启动它。 2. 如果使用的是`Saxon`处理器,则可以选择创建`%Net.Remote.Gateway`的实例,表示到`XSLT`网关的单个连接。 请注意,当使用`Saxon`处理器时,要利用已编译的样式表和`isc:Evaluate`缓存,这一步是必需的。 3. 可以选择创建已编译的样式表并将其加载到内存中。请参阅本章后面的“创建编译样式表”。如果使用的是`Saxon`处理器,请确保在创建编译后的样式表时指定网关参数。 如果打算重复使用同一样式表,则此步骤非常有用。然而,此步骤也会消耗内存。当不再需要编译的样式表时,请务必将其删除。 4. 调用适用API的转换方法之一。如果使用的是`Saxon`处理器,则在调用`Transform`方法时可以选择指定网关参数。 5. 可以选择调用其他转换方法。如果使用的是`Saxon`处理器,则在调用`Transform`方法时可以选择指定网关参数;这使能够使用相同的连接计算另一个转换。此转换将访问与此连接相关联的所有编译样式表和`isc:Evaluate`缓存条目。如果打开新连接,其他连接(及其编译的样式表和缓存)将被忽略。 Studio还提供了一个向导,可以使用该向导测试XSLT转换;本章稍后将对此进行介绍。 # 配置、启动和停止XSLT 2.0网关 当使用`Saxon`处理器(执行`XSLT 2.0`转换)时, IRIS使用`XSLT 2.0`网关(后者使用Java)。要配置此网关,请执行以下操作: 1. 在管理门户中,选择 System Administration > Configuration > Connectivity > XSLT 2.0 Gateway Server. 2. 选择Go。 ![image](/sites/default/files/inline/images/1_49.png) 系统将显示XSLT网关服务器页面。 左侧区域显示配置详细信息,右侧区域显示最近的活动。 ![image](/sites/default/files/inline/images/2_29.png) 3. 在左侧区域中,可以选择指定以下设置: - Port Number -`XSLT 2.0`网关独占使用的TCP端口号。此端口号不得与服务器上的任何其他本地TCP端口冲突。 默认值为 IRIS SuperServer端口号加`3000`。如果此数字大于`65535`,则系统使用`54773`。 - Java Version - 使用的Java版本。 - Log File - 日志文件的路径名。如果忽略此设置,则不执行日志记录。如果指定了文件名但忽略了目录,则将日志文件写入系统管理器的目录。 - Java Home Directory -包含Java bin目录的目录路径。如果服务器上没有默认Java,或者如果想使用不同的Java,请指定此选项。 要查看默认Java,请在服务器上的Shell中执行以下命令: ``` java -version ``` - JVM Arguments - Java虚拟机要使用的任何其他参数。 此区域还显示`JAVA_HOME`环境变量的当前值。 请注意,在网关运行时,不能编辑这些值中的任何一个。 4. 如果已进行更改,请选择保存以保存更改。或选择重置以。 5. (可选)选择测试以测试更改。 在此页面上,还可以执行以下操作: - 启动网关。要执行此操作,请选择右侧区域中的Start。 请注意, IRIS会在需要时自动启动网关。不需要手动启动网关。 - 关闭网关。要执行此操作,请选择右侧区域中的Stop(停止)。 # 重用XSLT网关服务器连接(XSLT 2.0) 如果使用的是`Saxon`处理器,InterSystems IRIS将使用之前配置的`XSLT 2.0`网关。为了与此网关通信,InterSystems IRIS在内部创建一个`XSLT`网关连接(`%Net.Remote.Gateway`的实例)。默认情况下,系统创建一个连接,将其用于转换,然后丢弃该连接。打开新连接会产生开销,因此为多个转换维护一个连接可提供最佳性能。此外,必须维护自己的连接,以便利用已编译的样式表和`isc:Evaluate`缓存。 要重用XSLT网关连接,请执行以下操作: 1. 调用`%XML.XSLT2.Transformer`的`StartGateway()`方法: ``` set status=##class(%XML.XSLT2.Transformer).StartGateway(.gateway) ``` 此方法启动XSLT 2.0网关(如果它尚未运行),并返回`%Net.Remote.Gateway`的实例作为输出。请注意,该方法还返回状态。 在`%Net.Remote.Gateway`实例表示与网关的连接。 `StartGateway()`有一个可选的第二个参数`useSharedMemory`。如果此参数为真(缺省值),则与`localhost`或`127.0.0.1`的连接将使用共享内存(如果可能)。要强制连接仅使用`TCP/IP`,请将此参数设置为False。 2. 检查上一步返回的状态: ```java if $$$ISERR(status) { quit } ``` 3. 创建任何已编译的样式表。执行此操作时,请将网关参数指定为`%Net.Remote.GatewayInstance`的实例在步骤1中创建。 4. 根据需要调用`%XML.XSLT2.Transformer`的`Transform`方法(`TransformFile()`、`TransformFileWithCompiledXSL()`、`TransformStream()`和`TransformStreamWithCompiledXSL()`)。执行此操作时,请将网关参数指定为在步骤1中创建的`%Net.Remote.Gateway`的实例。 5. 如果不再需要给定的编译样式表,请在调用`%XML.XSLT2.CompiledStyleSheet`的`ReleaseFromServer()`方法: ```java Set status=##class(%XML.XSLT2.CompiledStyleSheet).ReleaseFromServer(compiledStyleSheet,,gateway) ``` 重要提示:当不再需要已编译的样式表时,请务必使用此方法。 6. 当不再需要XSLT网关连接时,调用`%XML.XSLT2.Transformer`的`StopGateway()`方法,并将网关连接作为参数传递: ```java set status=##class(%XML.XSLT2.Transformer).StopGateway(gateway) ``` 此方法丢弃连接并重置当前设备。它不会停止`XSLT 2.0`网关。 重要提示:当不再需要连接时,请务必使用此方法。 有关示例,请参见XSLT2中的`Example10()`方法。`Samples`命名空间中的`Examples`。 # 排除XSLT 2.0网关服务器连接故障 当XSLT 2.0网关打开时,InterSystems IRIS和网关服务器之间的连接可能会变得无效。例如,如果出现网络错误或在InterSystems IRIS连接到网关服务器后重新启动网关服务器,则连接可能无法正常关闭。因此,可能会遇到错误。 可以通过连续调用XSLT网关连接对象的`%LostConnectionCleanup()`方法和`%reconnect`方法,尝试将InterSystems IRIS重新连接到网关服务器。 如果希望在断开连接时自动重新连接到网关服务器,请将网关连接对象的`AttemptReconnect`属性设置为true。 # 创建编译的样式表 如果打算重复使用同一样式表,则可能需要编译该样式表以提高速度。请注意,此步骤会消耗内存。当不再需要编译的样式表时,请务必将其删除。 要创建编译的样式表,请执行以下操作: - 如果使用的是`Xalan`处理器(对于`XSLT 1.0`),请使用`%XML.XSLT.CompiledStyleSheet`的以下类方法之一: - `CreateFromFile()` - `CreateFromStream()` - 如果使用的是`Saxon`处理器(用于`XSLT 2.0`),请在使用`%XML.XSLT2.CompiledStyleSheet`的以下类方法之一: - `CreateFromFile()` - `CreateFromStream()` 另请注意,将需要创建一个XSLT网关连接;请参阅“重用XSLT网关服务器连接(`XSLT 2.0`)”。 对于所有这些方法,完整的参数列表按顺序如下: 1. source - 样式表。 对于`CreateFromFile()`,此参数是文件名。对于`CreateFromStream()`,此参数是一个流。 2. compiledStyleSheet - 编译后的样式表,作为输出参数返回。 这是样式表类(`%XML.XSLT.CompiledStyleSheet`或`%XL.XSLT2.CompiledStyleSheet`,视情况而定)的实例。 3. errorHandler - 编译样式表时使用的可选自定义错误处理程序。 对于这两个类中的方法,这是`%XML.XSLT.ErrorHandler`实例。 4. (仅适用于`%XML.XSLT2.CompiledStyleSheet`)网关-`%Net.Remote.Gateway`的实例 ``` //将tXSL设置为等于适当流的OREF Set tSC=##class(%XML.XSLT.CompiledStyleSheet).CreateFromStream(tXSL,.tCompiledStyleSheet) If $$$ISERR(tSC) Quit ```
文章
姚 鑫 · 三月 9, 2021

第六章 SQL定义和使用视图

# 第六章 SQL定义和使用视图 视图是一种虚拟表,由执行时通过`SELECT`语句或几个`SELECT`语句的`UNION`从一个或多个物理表中检索到的数据组成。 `SELECT`可以通过指定表或其他视图的任意组合来访问数据。因此,存储了视图的视图提供了物理表的所有灵活性和安全性特权。 InterSystemsIRIS®数据平台上的InterSystems SQL支持在视图上定义和执行查询的功能。 注意:不能对以只读方式安装的数据库中存储的数据创建视图。 无法在通过ODBC或JDBC网关连接链接的`Informix`表中存储的数据上创建视图。这是因为InterSystems IRIS查询转换对这种类型的查询使用FROM子句中的子查询。 `Informix`不支持`FROM`子句子查询。 # 创建一个视图 可以通过几种方式定义视图: - 使用SQL `CREATE VIEW`命令(在DDL脚本中或通过JDBC或ODBC)。 - 使用管理门户的“创建视图”界面。 视图名称:不合格的视图名称是一个简单的标识符:`MyView`。合格的视图名称由两个简单的标识符组成,即模式名称和视图名称,以句点分隔:`MySchema.MyView`。视图名称和表名称遵循相同的命名约定,并对不合格的名称执行相同的架构名称解析。同一模式中的视图和表不能具有相同的名称。 可以使用`$SYSTEM.SQL.ViewExists()`方法确定视图名称是否已存在。此方法还返回投影视图的类名称。可以使用`$SYSTEM.SQL.TableExists()`方法确定表名是否已存在。 视图可用于创建表的受限子集。以下嵌入式SQL示例创建一个视图,该视图限制了可以通过该视图访问的原始表的行(通过`WHERE`子句)和列(假设`Sample.Person`包含两个以上的列): ```java /// d ##class(PHA.TEST.SQL).View() ClassMethod View() { &sql(CREATE VIEW Sample.VSrStaff AS SELECT Name AS Vname,Age AS Vage FROM Sample.Person WHERE Age>75) IF SQLCODE=0 { WRITE "创建一个视图",! } ELSEIF SQLCODE=-201 { WRITE "视图已经存在",! } ELSE { WRITE "SQL报错: ",SQLCODE," ",%msg,! } } ``` ```java DHC-APP>d ##class(PHA.TEST.SQL).View() 创建一个视图 ``` 以下嵌入式SQL示例基于`SalesPeople`表创建一个视图,并创建一个新的计算值列`TotalPay`: ```java /// d ##class(PHA.TEST.SQL).View1() ClassMethod View1() { &sql(CREATE VIEW Sample.VSalesPay AS SELECT Name,(Salary + Commission) AS TotalPay FROM Sample.SalesPeople) IF SQLCODE=0 { WRITE "创建一个视图",! } ELSEIF SQLCODE=-201 { WRITE "视图已经存在",! } ELSE { WRITE "SQL报错: ",SQLCODE," ",%msg,! } } ``` ## 管理门户创建视图界面 可以从管理门户创建视图。转到InterSystems IRIS管理门户。在系统资源管理器中,选择SQL。使用页面顶部的Switch选项选择一个名称空间;这将显示可用名称空间的列表。选择名称空间后,单击“操作”下拉列表,然后选择“创建视图”。 这将显示“创建视图”窗口,其中包含以下字段: - 模式:可以决定将视图包含在现有模式中,也可以创建一个新模式。如果选择选择现有模式,则会提供一个现有模式的下拉列表。如果选择创建新架构,请输入架构名称。在这两种情况下,如果省略模式,则InterSystems IRIS都会使用系统范围内的默认模式名称。 - 视图名称:有效的视图名称。不能对同一模式中的表和视图使用相同的名称。 - 使用`Check Option`:选项为`READONLY`,`LOCAL`,`CASCADED`。 - 将视图的所有特权授予`_PUBLIC`:如果选中,则此选项为该视图授予所有用户执行特权。默认设置是不授予所有用户访问该视图的权限。 - 查看文字:可以通过以下三种方式中的任意一种来指定查看文字: - 在“查看文本”区域中键入SELECT语句。 - 使用查询生成器创建`SELECT`语句,然后按OK将此查询提供给“查看文本”区域。 - 如果在Management Portal SQL界面的左侧选择了一个缓存查询名称(例如`%sqlcq.USER.cls4`),然后调用`Create View`,则该缓存查询将提供给“视图文本”区域。请注意,在保存视图文本之前,必须在“视图文本”区域中用实际值替换主机变量引用。 ## 视图和相应的类 定义视图时,InterSystems IRIS会生成一个相应的类。按照名称转换规则,SQL视图名称用于生成相应的唯一类名称。 Management Portal SQL界面显示现有视图的“目录详细信息”,包括此类名称。 # 修改视图 在Management Portal SQL界面中,可以选择一个现有视图以显示该视图的“目录详细信息”。 “目录详细信息视图信息”选项显示“编辑视图”链接,该链接提供了用于编辑视图文本(视图的`SELECT`语句)的界面。它还提供了一个下拉列表,以将“带检查选项”选择为无,`READONLY`,`LOCAL`或`CASCADED`。 # 可更新的视图 可更新的视图是可以在其上执行`INSERT`,`UPDATE`和`DELETE`操作的视图。仅当满足以下条件时,才认为视图是可更新的: - 视图查询的`FROM`子句仅包含一个表引用。该表引用必须标识可更新的基表或可更新的视图。 - 视图查询的`SELECT`列表中的值表达式必须全部是列引用。 - 视图的查询中不得指定`GROUP BY`,`HAVING`或`SELECT DISTINCT`。 - 该视图不是投影为视图的类查询。 - 视图的类不包含类参数`READONLY = 1`(如果视图定义包含`WITH READ ONLY`子句,则为`true`)。 ## WITH CHECK选项 为了防止在视图上执行`INSERT`或`UPDATE`操作,而该操作会导致基础基表中的行不属于派生视图表的一部分,InterSystems SQL在视图定义中支持`WITH CHECK OPTION`子句。此子句只能与可更新视图一起使用。 `WITH CHECK OPTION`子句指定可更新视图上的任何`INSERT`或`UPDATE`操作必须对照视图定义的WHERE子句验证结果行,以确保插入或修改的行将成为派生视图表的一部分。 例如,以下DDL语句定义了一个可更新的`GoodStudent`视图,其中包含所有具有高`GPA`(平均绩点)的学生: ```java CREATE VIEW GoodStudent AS SELECT Name, GPA FROM Student WHERE GPA > 3.0 WITH CHECK OPTION ``` 由于视图包含`WITH CHECK OPTION`,因此任何尝试在`GPA`值小于或等于3.0的`GoodStudent`视图中插入或更新行都将失败(此类行将不表示“好学生”)。 有两种类型的`WITH CHECK`选项: - `WITH LOCAL CHECK`选项意味着只检查`INSERT`或`UPDATE`语句中指定的视图的`WHERE`子句。 - 与级联检查选项(和级联检查选项)意味着视图的`WHERE`子句中指定的`INSERT`或`UPDATE`语句以及所有视图检查基于这一观点,无论外表或与当地检查没有其他选项在这些视图定义条款。 如果指定了`just WITH CHECK`选项,默认值是级联的。 在更新或插入期间,在为基础表的字段计算了所有默认值和触发的计算字段之后,并在常规表验证(必需字段、数据类型验证、约束等)之前,检查`WITH CHECK`选项条件。 在`WITH CHECK`选项验证通过后,插入或更新操作继续进行,就像在基表本身上执行插入或更新一样。 检查所有约束,拉出触发器,等等。 如果在`INSERT`或`UPDATE`语句中指定了`%NOCHECK`选项,则不检查`WITH CHECK`选项的有效性。 有两个与`WITH CHECK`选项验证相关的`SQLCODE`值(插入/更新会导致派生视图表中不存在一行): - `SQLCODE -136`-`INSERT`中视图的`WITH CHECK OPTION`验证失败。 - `SQLCODE -137`-视图的`WITH CHECK OPTION`验证在`UPDATE`中失败。 # 只读视图 只读视图是不能在其上执行`INSERT`,`UPDATE`和`DELETE`操作的视图。任何不符合可更新视图标准的视图都是只读视图。 视图定义可以指定`WITH READ ONLY`子句,以强制其成为只读视图。 如果尝试针对只读视图编译/准备`INSERT`,`UPDATE`或`DELETE`语句,则会生成`SQLCODE -35`错误。 # 查看ID:%VID InterSystems IRIS为视图或`FROM`子句子查询返回的每一行分配一个整数视图`ID`(`%VID`)。与表行`ID`号一样,这些视图行`ID`号是系统分配的,唯一的,非空的,非零的和不可修改的。该`%VID`通常对用户不可见,并且仅在明确指定时返回。它以数据类型`INTEGER`返回。因为`%VID`值是顺序整数,所以如果视图返回有序数据,它们将更有意义。视图与TOP子句配对时,只能使用`ORDER BY`子句。以下嵌入式SQL示例创建一个名为`VSrStaff`的视图: ```java /// d ##class(PHA.TEST.SQL).View() ClassMethod View() { &sql(CREATE VIEW Sample.VSrStaff AS SELECT Name AS Vname,Age AS Vage FROM Sample.Person WHERE Age>75) IF SQLCODE=0 { WRITE "创建一个视图",! } ELSEIF SQLCODE=-201 { WRITE "视图已经存在",! } ELSE { WRITE "SQL报错: ",SQLCODE," ",%msg,! } } ``` 下面的示例返回`VSrStaff`视图定义的所有数据(使用`SELECT *`),并且还指定应返回每一行的视图`ID`。与表行`ID`不同,使用星号语法时不显示视图行`ID`。仅当在`SELECT`中明确指定时才显示: ```java SELECT *,%VID AS ViewID FROM Sample.VSrStaff ``` `%VID`可用于进一步限制`SELECT`从视图返回的行数,如以下示例所示: ```java SELECT *,%VID AS ViewID FROM Sample.VSrStaff WHERE %VID BETWEEN 5 AND 10 ``` **因此,可以使用`%VID`代替`TOP`(或除`TOP`之外)来限制查询返回的行数。通常,`TOP`子句用于返回数据记录的一小部分。 `%VID`用于返回大多数或所有数据记录,以小的子集返回记录。此功能可能很有用,尤其是对于移植Oracle查询(`%VID`轻松映射到Oracle ROWNUM)而言。但是,与`TOP`相比,用户应了解使用`%VID`时的一些性能限制:** - `%VID`不执行第一行时间优化。 `TOP`优化为尽快返回第一行数据。 `%VID`优化以尽快返回完整的数据集。 - 如果查询指定排序的结果,则`%VID`不会执行有限的排序(这是`TOP`进行的特殊优化)。该查询首先对完整的数据集进行排序,然后使用`%VID`限制返回数据集。 `TOP`是在排序之前应用的,因此`SELECT`只能执行有限的排序,仅涉及有限的行子集。 为了节省第一行优化和有限排序优化的时间,可以将`FROM`子句子查询与`TOP`和`%VID`结合使用。在`FROM`子查询中指定上限(在本例中为10)作为`TOP`的值,而不是使用`TOP ALL`。使用`%VID`在`WHERE`子句中指定下限(在这种情况下,`> 4`)。以下示例使用此策略返回与上一个视图查询相同的结果: ```sql SELECT *,%VID AS SubQueryID FROM (SELECT TOP 10 Name,Age FROM Sample.Person WHERE Age > 75 ORDER BY Name) WHERE %VID > 4 ``` 即使显式指定了`%PARALLEL`关键字,也无法对指定`%VID`的查询执行并行执行。 # List视图属性 `INFORMATION.SCHEMA.VIEWS`持久类显示有关当前名称空间中所有视图的信息。它提供了许多属性,包括视图定义,视图的所有者以及创建和最后修改视图时的时间戳。这些属性还包括视图是否可更新,如果可更新,是否使用检查选项定义。 在嵌入式SQL中指定时,`INFORMATION.SCHEMA.VIEWS`需要`#include%occInclude`宏预处理程序指令。 `Dynamic SQL`不需要此伪指令。 `VIEWDEFINITION`属性(`SqlFieldName = VIEW_DEFINITION`)以字符串形式返回当前名称空间中所有视图的视图字段名称和视图查询表达式。例如, ```sql SELECT View_Definition FROM INFORMATION_SCHEMA.VIEWS ``` 返回诸如`“(vName,vAge)SELECT Name,Age FROM Sample.Person WHERE Age> 21”`的字符串。当从Management Portal SQL执行查询界面发出时,此字符串的显示仅限于前100个字符,其中不包括空格和换行符,并且(如有必要)附加表示省略号的省略号(`...`)。否则,发出此查询将为每个视图返回最多`1048576`个字符的字符串,在视图字段列表和查询文本之间有一个换行符,并保留了视图查询表达式中指定的空格,并(如有必要)附加了省略号(`...`)表示内容被截断。 以下示例返回当前名称空间中所有视图的视图名称(Table_Name字段)和所有者名称: ```sql SELECT Table_Name,Owner FROM INFORMATION_SCHEMA.VIEWS ``` 以下示例返回当前名称空间中所有非系统视图的所有信息: ```sql SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE Owner != '_SYSTEM' ``` `INFORMATION.SCHEMA.VIEWCOLUMNUSAGE`持久性类显示当前名称空间中每个视图的源表字段的名称: ```sql SELECT * FROM INFORMATION_SCHEMA.VIEW_COLUMN_USAGE WHERE View_Name='VSrStaff' ``` 可以使用管理门户网站SQL界面中的“目录详细信息”选项卡为单个视图显示与`INFORMATION.SCHEMA.VIEWS`相同的信息。视图的“目录详细信息”包括每个视图字段的定义(数据类型,最大长度,最小值/最大值等),以及`INFORMATION.SCHEMA`视图类未提供的详细信息。 “目录详细信息”视图信息显示还提供了用于编辑视图定义的选项。 # 列出视图依赖 `INFORMATION.SCHEMA.VIEWTABLEUSAGE`持久类显示当前名称空间中的所有视图及其依赖的表。在下面的示例中显示: ```sql SELECT View_Schema,View_Name,Table_Schema,Table_Name FROM INFORMATION_SCHEMA.VIEW_TABLE_USAGE ``` 可以调用`%Library.SQLCatalog.SQLViewDependsOn`类查询以列出指定视图所依赖的表。可以为此类查询指定`schema.viewname`。如果仅指定视图名称,则它将使用系统范围的默认架构名称。调用者必须具有指定视图的特权才能执行此类查询。在下面的示例中显示: ```java /// d ##class(PHA.TEST.SQL).View3() ClassMethod View3() { SET statemt=##class(%SQL.Statement).%New() SET cqStatus=statemt.%PrepareClassQuery("%Library.SQLCatalog","SQLViewDependsOn") IF cqStatus'=1 { WRITE "%PrepareClassQuery failed:" DO $System.Status.DisplayError(cqStatus) QUIT } SET rset=statemt.%Execute("vschema.vname") DO rset.%Display() } ``` ```sql DHC-APP>d ##class(PHA.TEST.SQL).View3() Dumping result #1 SCHEMA TABLE_NAME 0 Rows(s) Affected ``` 此`SQLViewDependsOn`查询列出了视图所依赖的表,并列出了表架构和表名。如果调用者没有该视图所依赖的表的特权,则该表及其模式将列为``。这允许没有表特权的调用者确定视图所依赖的表数量,而不是表的名称。
文章
Claire Zheng · 三月 22, 2022

如何准确理解FHIR能力?医疗IT行业的数据交换和共享难题如何破?

最在第一期“极客聊吧”中,InterSystems销售工程师们聊了聊这些话题:为什么有些医院和某些商保之间可以直接结算,有些又不能?医院和保险之间的结算难在哪儿?在InterSystems 2021全球线上峰会中提到的医保结算案例对国内实践有哪些借鉴意义?FHIR又能起到什么关键作用?医疗数据实现互联互通的关键是什么?以下是文字版。 点击查看视频。 #从商保结算谈起# 菁伟 (@Jingwei.Wang ):大家好,我是InterSystems的销售工程师王菁伟,这是我的同事祝麟和刘皆良(Jeff)。今天我们一块来聊聊HIT行业里的数据交互那点事。去医院就诊的话,我们会发现有些医院可以和某些商业保险直接结算,有的医院或者某些保险产品又不能。为什么直结这个流程没有全面开通呢? 祝麟 ( @Lin.Zhu ):我们虽然平时看病都基本实现了医保直连, 但实际上背后医院的信息科和供应商付出了大量的努力,比如供应商就需要要适应各地医保结算流程和政策的差异,这个过程的数字化还是有很大难度的,也没法一蹴而就。 Jeff ( @Jieliang.Liu ):到商保这一侧,可以观察到很多商保产品的直结清单是逐年递增。那么保险公司的产品是一家一家和医院对接的,难度恐怕更大。 菁伟 (@Jingwei.Wang ):医院和保险之间的结算过程到底为什么落地困难呢? 祝麟 ( @Lin.Zhu ):原因很多,既有政策层面的,也有技术层面的。比如医院和院外机构间通信的安全性保障就是问题,如果没有安全的公共平台进行数据交换,哪家医院也不能独立承担数据流出医院的安全风险,这在政策的制定和技术的实现方面都有挑战。 Jeff ( @Jieliang.Liu ):医院和保险之间的接口也是问题,不同的医院会采用不同厂家提供的系统,不同保险公司采用的数据接口肯定也不一样,是个典型的多对多集成的问题,工作量会比较大,实施周期也很长。 #借鉴国际成功案例# 菁伟 (@Jingwei.Wang ):去年InterSystems的全球峰会上HealthShare的分论坛里是不是就谈到了医保结算的场景?这个案例对实现直接结算有没有借鉴意义呢? 祝麟 ( @Lin.Zhu ):是的。本身医保结算这个事是个全球性的挑战。除了我们国家以外,即使是商保比较发达的欧美国家,在打通流程方面也是处于进行中的状态。这次峰会上HealthShare发布解决方案,实现了CMS,也就是美国医保局所定义的医疗服务提供方和支付方的交互规范。这个方案覆盖的正是医疗机构、支付方以及患者三者之间结算和信息交互流程。 菁伟 (@Jingwei.Wang ):也就是说满足了政策要求? Jeff ( @Jieliang.Liu ):也包含技术要求。CMS定义的交互流程和数据模型是以FHIR为载体的。 祝麟 ( @Lin.Zhu ):是的。CMS定义的交互规约既包含流程规范,也包含接口和数据规范,目前是以FHIR R4规定的,所以必须以FHIR API的形式实现。 #如何准确理解FHIR能力# 菁伟 (@Jingwei.Wang ):那么,现在有没有实际的案例使用FHIR来完成业务功能呢? Jeff ( @Jieliang.Liu ):有的。我们在国际上已经看到不少基于FHIR的业务出现。比如我们和UC Davis Health以及Centene合作进行了医保预授权的自动化项目,就是基于FHIR的。在这个项目里,UC Davis Health的角色是医疗机构,Centene是保险的支付方,采用HealthShare作为平台来支撑不同角色间的实时交互。 祝麟 ( @Lin.Zhu ):UC Davis Health的医生在Epic的电子病历系统里下达医嘱,系统把患者和医嘱信息按自定义接口发到HealthShare;HealthShare将请求转为FHIR标准再通过FHIR接口与Centene的系统交互,检查这些医嘱能不能被Centene的保险产品覆盖,再把结果通过HealthShare转回到医生那儿。这样就可以在下达医嘱时实时地通过预授权的检验,杜绝医保拒付的情况。先不说杜绝拒付问题能节省的开支,光是将预授权自动化这一项,和人工处理相比,就能把每一单预授权的处理成本从3.68美金降到0.04美金,那每处理一百万次预授权就能省下几百万美金了。 菁伟 (@Jingwei.Wang ):那么,假设我们有一个集成平台,通过平台实现FHIR API接口,不同的系统通过FHIR API与集成平台对接,是不是就能解决数据交互问题呢? 祝麟 ( @Lin.Zhu ):这是个非常好的问题。FHIR在设计之初就声明采用了剃刀原理,它大概只能覆盖80%常见的交互需求。因此,对于差异化的需求或者是新技术引入的新的数据交互需求,FHIR要借助除了API之外的额外机制来解决这个问题。在医疗行业,我们现在经常遇到医疗文档共享或者跨机构流程这样的业务场景,除了API。Jeff,你认为平台这个层面还需要什么样的一些能力来支撑这些场景呢? Jeff ( @Jieliang.Liu ):Profile。针对患者健康档案共享和支付方之间的数据交换两个不同的场景,需要分别遵循USCore profile和PDex Profile的规约。也就是说在可预见的未来,对于一家医院或者一个区域级的数据交换中心来说,需要能够支持不同的Profile以应对不同的场景。 菁伟 (@Jingwei.Wang ):这些不同的Profile之间有什么差别吗? Jeff ( @Jieliang.Liu ):首先我们需要明白Profile立意于使用FHIR支持差异化的用例或场景。因此,一个合法的Profile就只覆盖这个场景所需要使用的模型而不会涉及到其他用例的内容。 US Core和PDex 这两个Profile首先在定位上不太一样。US Core面向患者就诊过程的信息交换,对就诊中的涉及例如治疗计划、体征和检验结果这样的临床信息进行了定义;而PDex是面向医保结算的用例,就会包含报销范围,支付方的组织机构信息这样一些和医保报销相关的信息,由CPCDS这个数据集定义。当然PDex也会引用US Core中定义的内容,比如患者的身份、病史、体征、检验结果,在PDex里这些临床信息是直接引用US Core里的定义的。 祝麟 ( @Lin.Zhu ):没错,正如同我们在医院信息互联互通标准化成熟度测评过程中可以体会到文档交换和服务调用是面向不同用例的交互手段,两者的信息构造有差异。那么使用FHIR进行交互时,面对不同的应用场景时完全可能需要套用不同的Profile,甚至是借助Profile套用特定的术语。因此,Profile之间会有很多差异。 如果FHIR在中国落地,可以想象到,由于医疗技术上我们包含中医,医疗福利上我们有医保和商保,还有很多其他差异,我们也需要有中国自己定义的多个Profile去投入使用。 因此,对FHIR的支持不能仅仅体现在支持HL7官网发布的协议结构上。支持多Profile,能够根据地区、应用场景的不同导入并套用Profile对于医疗行业的集成引擎、数据平台这样的产品是一项至关重要的FHIR能力。 Jeff ( @Jieliang.Liu ):除了遵循协议之外,还有数据架构。在HealthShare的解决方案里包含了一个整合好的数据存储。 祝麟 ( @Lin.Zhu ):是的,有一份在各业务系统之上,经过整合与泛化统一存储的数据能够极大简化应用标准协议的成本。大家可以想象一下,对于使用FHIR来说,在多Profile模式下运行的一个体系,如果没有一份整合的数据,那么每次要支持一个新的Profile,特别是和上一次应用的Profile所需的资源不一样,术语可能也不一样的时候,实施方需要再一次挨个把和各个业务系统的映射再做一遍,这个代价和周期可想而知。 菁伟 (@Jingwei.Wang ):梳理和整合数据存储的话,这样一套方案就不是单纯的集成平台方案了。 祝麟 ( @Lin.Zhu ):没错,这是因为采用集成平台,和采用集成加数据整合的医院信息平台,要解决的问题是不一样的。 当单纯应用集成平台整合流程时,要解决是打破烟囱的问题,但还谈不上整合数据与数据利用。对于这样的场景,即使点对点地两两集成,也能解决问题,坦率说除非每个应用系统都能支持某个标准协议通信,否则采不采用协议进行集成并不关键。但如果要上线统一患者档案这样的业务,就需要整合和泛化数据并进行存储,如何利用这份数据就是协议可以发挥作用的地方了。 Jeff ( @Jieliang.Liu ):日本群马大学医学部附属医院就用我们的产品作为信息平台使用。应用InterSystems IRIS作为信息交换引擎从HIS、检验这样的系统里通过实时和批量数据同步接口获取数据,转换为FHIR并存储在InterSystems IRIS的FHIR存储库里。这个FHIR存储库所承担的就是临床数据中心的角色。它们的科研系统REDCap则通过FHIR对这个存储库进行查询并获得患者档案。现在这个项目也还在扩展,通过和Apple的技术融合实现患者端对自己的临床档案的访问。 祝麟 ( @Lin.Zhu ):是的,FHIR API本身就能支持数据利用和数据共享。院里要做科研的话也可以通过FHIR API查询符合条件的患者集合,比如查2021年11月到12月间就诊的低密度脂蛋白低于100的II型糖尿病患者,这是个典型的数据利用问题。如果不借助一份整合好的数据,只凭借单纯的集成平台,那就需要把这样的请求解析并分解到不同的业务系统,再把结果整合起来,才能获得结果。实施难度大,业务压力大不说,效率还没有保障。直接从支持FHIR的存储库里获取数据要高效得多。 Jeff ( @Jieliang.Liu ):使用FHIR资源仓库还有一大好处是,FHIR资源仓库并不意味着中心化的存储,而是由一系列物理上分布的资源仓库组成。这些离散的仓库各自保存特定的数据,通过资源间的相互引用形成逻辑上的统一。由于这种引用本质上松耦合,因此能够形成一个逻辑上整合的数据中心。也因为物理离散而逻辑统一,FHIR存储库非常适合用在微服务架构中。当然无论如何,物理上分布的数据也仍然需要通过FHIR统一逻辑概念和语意,以便在异构的系统间和组织机构间进行共享。 因此在应用FHIR相关的技术方面,FHIR接口是个基本的合规要求,多Profile的支持和FHIR存储库则更加关键,这是两个会直接影响FHIR是否能落地的重要特性。 #小谈互联互通# 菁伟 (@Jingwei.Wang ):标准接口和整合数据存储,这个概念听着很耳熟。 Jeff ( @Jieliang.Liu ):当然。一是互联互通的推荐架构里,是包含临床数据中心的,也是对整合应用数据提出了要求。另外,InterSystems在介绍方案时,通常也是把集成平台、数据中心看作是一个解决方案中的两个组成部分来看的。 祝麟 ( @Lin.Zhu ):没错,随着互联互通这项工作的逐渐推广,相信各家医院和区域数据中心都会收到越来越多数据开放和应用的需求。基于FHIR的数据交换和数据利用会经历越来越多的讨论,我们也会见到大量的交互场景通过FHIR实现的案例,以及基于FHIR特性的智能应用的出现。 菁伟 (@Jingwei.Wang ):感谢两位工程师与大家分享FHIR的案例和FHIR协议落地时所需要的平台能力。FHIR除了资源和接口的定义之外,还有许多特性能够帮助医疗机构打通数据流程。作为一个面向互操作性的协议,相信未来我们还会见到更多通过FHIR支撑的业务场景。
文章
Michael Lei · 五月 1, 2022

转发博客文章: 释放医疗互操作性的全部益处: 下一个前沿

临床研究必须与健康数据相连 就在不久以前,临床科研人员还需要依靠三联的纸质NCR表格,手工收集从堆积如山的手写电子病历中提炼出来的病人数据。从又大又重的《医师案头参考》(PDR)撕下几页,通过传真机发送给FDA,用于药物安全报告。业内专业人士接受了大量的培训,以确保数据经过源文件验证、双键处理,并在经过看似无休止的查询以纠正错误之后,保证其符合目的。 值得庆幸的是,随着电子健康档案的广泛采用,健康数据的数字化,这一过程得到了极大的改善。但是,鉴于临床研究进展缓慢,特别是精美的Excel表格仍由人工数据摘要完成,该领域早该有更多的技术变革,特别是围绕释放医疗互操作性的全部好处。如果我们能做到这一点,生命科学公司将有机会利用宝贵的健康数据来确保病人的安全,优化新药的疗效,并使临床开发过程更加高效,减少错误。 我们可能会比你想象的更快地将临床研究与健康数据联系起来。为什么?火神计划(Project Vulcan)正在进行中。这个项目组是最近在HL7的FHIR加速器项目中创建的,它已经召集了来自医疗、技术和生命科学领域的30多个利益相关的组织个和机构,利用FHIR这个医疗专用互操作性标准来进行临床和转化研究。自从我们在去年年初加入后,我们高兴的看到火神计划成员制定的早期想法越来越接近于功能现实。 但是,医疗互操作性究竟如何能使同时用药跟踪(在同一时间段内给予两种或多种药物)或不良事件报告(捕捉可能与药物有关的疾病)以及其他临床研究领域受益?这些答案让我们看到了未来。 互操作性彻底改变了不良事件报告 每个新药的批准都是从安全开始的。如果研究人员不能完成临床试验的第一和第二阶段,他们甚至没有机会在更大的人群中研究其药物的疗效。但要证明一种治疗方法是安全的,这就提出了严峻的挑战。 几十年来,业内人士已经知道,一些不良事件在临床试验中被忽略了。比方说,一个研究对象在其心脏病专家的照料下测试一种新的心脏候选药物时,出现了皮疹并去看皮肤科医生。一个月后,当该受试者来到他们的下一次研究访问时,他们可能忘记告知研究团队他们最近的诊断--由正在测试的研究药物引起的新皮疹。 现在,太多时候,故事就在这里结束。这条信息--以及与之相关的、可能说明药物安全性的所有信息--已经消失。其他真实世界的数据也是如此,比如病人服用的额外药物,但由未参与研究的护理团队成员开出。或者仅仅是网络外的访问和程序。 然而,如果火神计划成功,研究人员将有更好的机会通过参与者的电子病历健康档案和临床研究数据记录之间的联系来捕捉这些关键信息。 基于FHIR的互操作性还可以简化不良事件报告,使患者的完整快照可以向关键利益相关者提供重要数据。任何人--患者、研究人员或监管机构--都不会再担心出现问题,而这些问题本可以通过与真实世界的数据建立可靠的联系而轻松避免。 互操作性支持表型数据共享Phenopackets(开放的可计算的生物信息Phenopackets.org)和临床实验方案日程 除了电子病历数据可以为临床试验提供信息外,火神项目的目标之一是,希望借助于FHIR,临床试验中收集的数据可以被更广泛地访问, 而且可以用于采取行动。全球基因组学与健康联盟(GA4GH)的表型数据交换标准有望使业界分享脱敏后(去掉身份识别)的病例级病人信息,以用于登记册、知识库出版物和期刊。 任何从事临床试验的人都知道,尽管对实现研究目标至关重要,但临床试验的分步指南,很容易出现疏忽和偏离计划的情况。主要的问题是什么?就是人为失误。但通过 "火神计划",基于FHIR的分步指南活动安排表很快就能实现调度自动化,减少对手工数据输入的需求,并提高研究程序的一致性。 我们已准备好将FHIR引入临床研究 FHIR已经在推进互操作性和消除障碍。在InterSystems,我们每天都能看到FHIR对互操作性的影响,无论是通过创建用于临床决策支持的移动端APP,还是通过医院不同部门和医疗机构之间的数据无缝流动。这就是我们将FHIR纳入我们的技术栈的原因。 当火神项目实现其目标时,InterSystems将准备好立即为临床研究带来快速、无缝的数据交换。我们没有任何理由推迟更安全、更有效的药物的到来。 作者是:InterSystems公司生命科学顾问Matthew Stannard 原文--https://www.intersystems.com/pulse-blog/unlocking-benefits-of-healthcare-interoperability