搜索​​​​

清除过滤器
文章
姚 鑫 · 二月 18

第二十八章 T 开头的术语

# 第二十八章 T 开头的术语 # 以 T 开头的术语 ### 表 (table) **InterSystems SQL** 表是一种由表示特定实体的行和表示每个实体特定数据点的列组成的数据结构。 ### 目标角色 (target role) **系统** 在受保护的 `IRIS` 应用中,由应用程序授予给已经是其他角色(称为匹配角色)成员的用户的角色。如果用户拥有匹配角色,则在使用应用程序时,用户还可以被授予一个或多个额外的目标角色。 ### 目标用户 (target user) **系统** 试图认证到 `LDAP` 服务器的用户。`IRIS` 通过在特定 `LDAP` 配置的“编辑 `LDAP` 配置”页面上的 `LDAP` 唯一搜索属性字段中使用提供的值,尝试在 `LDAP` 数据库中查找该用户。可以从 `LDAP` 配置页面(系统管理 > 安全 > 系统安全 > `LDAP` 配置)访问“编辑 `LDAP` 配置”页面。(请注意,如果启用了 `Kerberos`,页面名称和菜单选项中会包含 `Kerberos`。) ### TCP/IP **通用** 传输控制协议/互联网协议(`Transmission Control Protocol/Internet Protocol`),是可以管理关系客户端和关系服务器之间连接的通信协议之一。也称为 `TCP`。 ### 临时全局 (temporary global) **系统** 存储在临时数据库 `IRISTEMP` 中的全局。请参见临时全局和 `IRISTEMP` 数据库。 ### 终端 (Terminal) **系统** 正式而言,该术语指的是 `Windows` 终端应用程序。非正式而言,该术语也可以指 `ObjectScript shell`,即 `IRIS` 的交互式命令行接口。终端应用程序包括 `ObjectScript shell`,但也提供菜单和其他选项。请参见“使用终端”和“使用 `ObjectScript Shell`”。 ### 事务 (transaction) **通用** 一个逻辑工作单元。应用程序开发人员可以使用 `SQL` 或 `ObjectScript` 命令定义事务。`IRIS` 将事务中对全局的更新记录在日志文件中。如果事务不完整,可以回滚。 ### 瞬态属性 (transient property) **对象(Objects)** 瞬态属性存储在内存中,但不存储在磁盘上。 ### 翻译方法 (translation methods) **对象(Objects)** 翻译方法用于在 `ODBC`、显示、逻辑和存储格式之间转换值。 ### 触发器 (trigger) **InterSystems SQL** 由开发人员定义的一系列操作,在 `SQL` 应用程序或使用 `SQL` 存储的对象应用程序的各个点执行。触发器是由对表执行的 `INSERT`、`UPDATE` 或 `DELETE` 操作启动的数据库操作。触发器有助于维护完整性约束和其他数据依赖关系。
文章
Louis Lu · 六月 10, 2024

类定义中如何使用列式存储

列式存储是 InterSystems IRIS 提供的一项较新的技术。与传统的基于行的存储不同,它通过将数据存储在列而不是行中来优化查询处理,从而实现更快的访问和检索相关信息。 下面是使用SQL创建此类表的例子 CREATE TABLE table (column1 type1, column2 type2, column3 type3) WITH STORAGETYPE = COLUMNAR -- ex 1 CREATE TABLE table (column1 type1, column2 type2, column3 type3 WITH STORAGETYPE = COLUMNAR) -- ex 2 我们知道InterSystems IRIS 是支持多模型的DMBS, 它可以无缝的通过关系型或对象的方式访问通一数据, 我们使用下面的方式在使用Object Script类定义的时候定义列存储: 1. 如果你想对类中的所有属性都定义为列存储,则直接通过在类中添加parameter 的方式实现: Parameter STORAGEDEFAULT = "columnar" 如前面的例子,我们使用object script定义就会是这样: Class Post.Address Extends %Persistent [Final] { Parameter STORAGEDEFAULT = "columnar"; Parameter USEEXTENTSET=1; Property City As %String(MAXLEN = 12); Property ZIP As %String(MAXLEN = 9); Property Country As %String(MAXLEN = 12); } 其中 Parameter STORAGEEDFAULT = "columnar" 告诉系统,所有数据都以列的方式保存(意味着每一列都有其自己的global节点) Parameter USEEXTENTSET = 1 告诉系统,为了生成的效率,hashed 的global 使用短名称命名。 你可以将任意表定义为使用列存储。但是将列存作为默认存储模式的表,必须添加Final 或 NoExtent 的类关键字,也就是不能再被继承。 2. 也可以仅对表中的某些字段定义为使用列式存储,要实现此种设计进需要在属性上添加 STORAGEDEFAULT = "columnar" Class Post.Address Extends %Persistent { Parameter STORAGEDEFAULT = "row"; Parameter USEEXTENTSET=1; Property City As %String(MAXLEN = 12); Property ZIP As %String(MAXLEN = 9); Property Country As %String(MAXLEN = 12, STORAGEDEFAULT = "columnar"); } 这个例子中的City 和 ZIP 仍使用行式存储,也就是数据会存储在global ^Post.AddressD 中,而Country会以列式的方式存储在不同的global节点中。 在这个例子中,使用列式存储会是一个更好的方法,因为如果我们有一个包含不同国家不同城市的数据库,国家的数目是有限的,而城市的数目则不是。 3. 还可以对现有行存储的类,针对某些字段添加列式索引 Class Sample.BankTransaction Extends %Persistent [ DdlAllowed ] { // Line below is optional Parameter STORAGEDEFAULT = "row"; Property Amount As %Numeric(SCALE = 2); Index AmountIndex On Amount [ type = columnar ]; . . . } 在这个例子中,金额这样的数字类型字段,使用行式存储,但对其建立列式索引,会极大提高针对该字段的统计类sql查询效率,比如SUM、Avg等。
文章
姚 鑫 · 七月 17, 2021

第六章 使用%File对象

# 第六章 使用%File对象 如果想要操作文件本身,需要使用`%Library.File`的`%New()`方法实例化`%File`对象。该类还提供了允许使用该文件的实例方法。 注意:本节提供了几个使用`%File`对象的示例,以供说明。 对于简单的文件读写,使用`%Stream.FileCharacter`和%`Stream.FileBinary`。因为它们提供了额外的功能,例如,以正确的模式自动打开文件。 ## 创建%File对象的实例 要使用文件,需要使用`%New()`方法实例化表示该文件的%File对象。该文件可能已经存在,也可能不存在于磁盘上。 以下示例在默认目录中为文件`export.xml`实例化一个%File对象。 ```java set fileObj = ##class(%File).%New("export.xml") ``` ## 打开和关闭文件 实例化`%File`对象后,需要使用`open()`方法打开文件,以读取或写入该文件: ```java USER>set status = fileObj.Open() USER>write status 1 ``` 使用`Close()`方法关闭文件: ```java USER>do fileObj.Close() ``` ## 检查%File对象的属性 一旦实例化了文件,就可以直接检查文件的属性。 ```java USER>write fileObj.Name export.xml USER>write fileObj.Size 2512 USER>write $zdate(fileObj.DateCreated) 11/18/2020 USER>write $zdate(fileObj.DateModified) 11/18/2020 USER>write fileObj.LastModified 2020-11-18 14:24:38 USER>write fileObj.IsOpen 0 ``` 请注意,`LastModified`是人类可读的时间戳,而不是`$H`格式的日期。 属性“大小Size”、“创建日期DateCreated”、“修改日期DateModified”和“最后修改日期LastModified”是在访问时计算的。为不存在的文件访问这些属性会返回-2,表示找不到该文件。 注意:Windows是目前唯一跟踪实际创建日期的平台。其他平台存储最后一次文件状态更改的日期。 ```java USER>write ##class(%File).Exists("foo.xml") 0 USER>set fooObj = ##class(%File).%New("foo.xml") USER>write fooObj.Size -2 ``` 如果文件已打开,可以通过访问`CanonicalName`属性来查看其规范名称,这是根目录的完整路径。 ```java USER>write fileObj.CanonicalName USER>set status = fileObj.Open() USER>write fileObj.IsOpen 1 USER>write fileObj.CanonicalName c:\intersystems\IRIS\mgr\user\export.xml ``` ## 从文件中读取 要读取文件,可以打开文件,然后使用`Read()`方法。 以下示例读取`messages.log`的前`200`个字符。 ```java USER>set messages = ##class(%File).%New(##class(%File).ManagerDirectory() _ "messages.log") USER>set status = messages.Open("RU") USER>write status 1 USER>set text = messages.Read(200, .sc) USER>write text *** Recovery started at Mon Dec 09 16:42:01 2019 Current default directory: c:\intersystems\IRIS\mgr Log file directory: .\ WIJ file spec: c:\intersystems\IRIS\mgr\IR USER>write sc 1 USER>do messages.Close() ``` 要从文件中读取整行,请使用`ReadLine()`方法,该方法继承自`%Library.File`的父类`%Library.AbstractStream`。 下面的示例读取`E:\temp\new.txt`的第一行。 ```java /// desc: 读取数据 /// w ##class(Demo.FileDemo).ReadFileData("E:\temp\new.txt") ClassMethod ReadFileData(str) { s fileObj = ##class(%File).%New(str) s status = fileObj.Open("RU") w status,! s text = fileObj.ReadLine(,.sc) w text,! w sc,! d fileObj.Close() q "" } ``` ## 写入文件 要写入文件,可以打开文件,然后使用`Write()`或`WriteLine()`方法。 以下示例将一行文本写入新文件。 ```java /// desc: 写入数据 /// w ##class(Demo.FileDemo).WriteFileData("E:\temp\new.txt") ClassMethod WriteFileData(str) { s fileObj = ##class(%File).%New(str) s status = fileObj.Open("RUWSN") w status,! s status = fileObj.WriteLine("Writing to a new file.") w status,! w fileObj.Size,! d fileObj.Rewind() s text = fileObj.ReadLine(,.sc) w text,! q "" } ``` ## 倒回文件 从文件读取或写入文件后,希望使用`Rewind()`方法倒回文件,以便可以从文件开头执行操作。 从上一个示例停止的地方开始,`fileObj`现在位于其末尾。倒回文件并再次使用`WriteLine()`会覆盖该文件。 ```java USER>set status = fileObj.Rewind() USER>write status 1 USER>set status = fileObj.WriteLine("Rewriting the file from the beginning.") USER>write status 1 USER>write fileObj.Size 40 ``` 关闭文件并重新打开它也会倒回文件。 ```java USER>do fileObj.Close() USER>set status = fileObj.Open("RU") USER>write status 1 USER>set text = fileObj.ReadLine(,.sc) USER>write sc 1 USER>write text Rewriting the file from the beginning. ``` ## 清除文件 要清除文件,可以打开文件,然后使用`Clear()`方法。这将从文件系统中删除该文件。 以下示例清除默认目录中的`junk.xml`。 ```java USER>write ##class(%File).Exists("junk.xml") 1 USER>set fileObj = ##class(%File).%New("junk.xml") USER>set status = fileObj.Open() USER>write status 1 USER>set status = fileObj.Clear() USER>write status 1 USER>write ##class(%File).Exists("junk.xml") 0 ```
文章
Nicky Zhu · 一月 11, 2021

类、表和Globals——工作原理

当我向技术人员介绍InterSystems IRIS时,我一般会先讲其核心是一个多模型DBMS。 我认为这是其主要优势(在DBMS方面)。数据仅存储一次。您只需访问您想用的API。 - 您想要数据的概要?用SQL! - 您想用一份记录做更多事情?用对象! - 想要访问或设置一个值,并且您知道键?用Globals! 乍一看挺好的,简明扼要,又传达了信息,但当人们真正开始使用InterSystems IRIS时,问题就来了。类、表和Globals是如何关联的?它们之间有什么关系?数据是如何存储的? 本文我将尝试回答这些问题,并解释这些到底是怎么回事。 ## 第一部分 模型偏见 处理数据的人往往对他们使用的模型有偏见。 开发者们把数据视为对象。对他们而言,数据库和表都是通过CRUD(增查改删,最好是基于ORM)交互的盒子,但底层的概念模型都是对象(当然这对于我们大多数使用面向对象编程语言的开发者来说没错)。 而DBA大部分时间都在搞关系型DBMS,他们把数据视为表。对象只是行的封装器。 对于InterSystems IRIS,持久类也是一个表,将数据存储在Global中,因此需要进行一些澄清。 ## 第二部分 举例 假设您创建了类Point: ```objectscript Class try.Point Extends %Persistent [DDLAllowed] { Property X; Property Y; } ``` 您也可以用DDL/SQL创建相同的类: ``` CREATE Table try.Point ( X VARCHAR(50), Y VARCHAR(50)) ``` 编译后,新类将自动生成一个存储结构,将原生存储在Global中的数据映射到列(对于面向对象开发者而言,是属性): ``` Storage Default { %%CLASSNAME X Y ^try.PointD PointDefaultData ^try.PointD ^try.PointI ^try.PointS %Library.CacheStorage } ``` 这是怎么回事? 自下向上(加粗文字很重要): - Type: 生成的存储类型,本例中是持久对象的默认存储 - StreamLocation - 存储流的Global - IndexLocation - 索引Global - IdLocation - 存储ID自增计数器的Global - **DefaultData** - 存储将Global值映射到列/属性的XML元素 - **DataLocation** - 存储数据的Global 现在我们的DefaultData是PointDefaultData,让我们分析下它的结构。本质上Global节点有这样的结构: - 1 - %%CLASSNAME - 2 - X - 3 - Y 所以我们可能期望我们的Global是这样的: ``` ^try.PointD(id) = %%CLASSNAME, X, Y ``` 但如果我们输出 Global 它会是空的,因为我们没有添加任何数据: ``` zw ^try.PointD ``` 让我们添加一个对象: ``` set p = ##class(try.Point).%New() set p.X = 1 set p.Y = 2 write p.%Save() ``` 现在我们的Global变成了这样 ``` zw ^try.PointD ^try.PointD=1 ^try.PointD(1)=$lb("",1,2) ``` 可以看到,我们期望的结构%%CLASSNAME, X, Y是用 $lb("",1,2) 设置的,它对应的是对象的X和Y属性(%%CLASSNAME 是系统属性,忽略)。 我们也可以用SQL添加一行: ``` INSERT INTO try.Point (X, Y) VALUES (3,4) ``` 现在我们的Global变成了这样: ``` zw ^try.PointD ^try.PointD=2 ^try.PointD(1)=$lb("",1,2) ^try.PointD(2)=$lb("",3,4) ``` 所以我们通过对象或SQL添加的数据根据存储定义被存储在Global中(备注:可以通过在PointDefaultData 中替换X和Y来手动修改存储定义,看看新数据会怎样!)。 现在,如果我们想执行SQL查询会怎样? ``` SELECT * FROM try.Point ``` 这段sql查询被转换为ObjectScript代码, 遍历^try.PointD,并根据存储定义(其中的 PointDefaultData 部分)填充列。 下面是修改。让我们从表中删除所有数据: ``` DELETE FROM try.Point ``` 看看我们的Global变成什么样了: ``` zw ^try.PointD ^try.PointD=2 ``` 可以看到,只剩下ID计数器,所以新对象/行的ID=3。我们的类和表也继续存在。 但如果我们运行会怎样: ``` DROP TABLE try.Point ``` 它会销毁表、类并删除Global。 ``` zw ^try.PointD ``` 看完这个例子,希望您现在对Global、类和表如何相互集成和互补有了更好的理解。根据实际需要选用正确的API会让开发更快、更敏捷、bug更少。
文章
Lilian Huang · 七月 20, 2022

FHIR 中的问卷和表格(Questionnaire & Forms):从创建到使用

本文将讨论 FHIR 中的问卷和问卷反馈(Questionnaire and Questionnaire Response), 从创建表单到上传到服务器以及如何填写它们。 tl;dr : 通过使用该工具链接“ this online tool” ,您可以轻松的开始构建您自己的表单,或者使用现有模版。 通过使用InterSystems 本地FHIR 服务器链接“ this InterSystems local FHIR server” ,您可以轻松的存储您的FHIR资源和问卷。 通过使用此应用程序“this app” ,您可以像医生一样操作,对您的 FHIR 服务器上的每位患者进行问卷调查和回复。 需要注意的是,该应用程序不使用 Content-Type 'application/json+fhir' 进行通信,而只是使用 Content-Type 'application/json' ,所以它不会像我们的本地 InterSystems FHIR 服务器那样工作。 这就是为什么我创建了这个 GitHub 存储库“this GitHub repo”,其中包含应用程序的修改版本,使用 Content-Type 'application/json+fhir',拥有本地 FHIR 服务器和指向问卷生成器工具的链接以及一些解释。 克隆 repo 后,通过执行 docker-compose up -d, npm ci, npm run build 然后出现 npm run start ,您将可以访问该应用程序,通过选择您想要的 FHIR 服务器和您想要工作的患者使用,您将能够填写调查问卷并将其保存到您的服务器中,只需单击 2 次。 End of tl;dr 接下来是 GitHub 的自述文件。 1. 使用本地 fhir 服务器的 FHIR 表单应用程序包括如下 1. App for FHIR forms using a local fhir server(使用本地 fhir 服务器的 FHIR 表单应用程序) 2. Requirements(要求) 2.1. Add Node.js and npm to your path(将 Node.js 和 npm 添加到您的路径) 2.2. Install Dependencies(安装依赖项) 3. Local FHIR server(本地FHIR服务器) 4. Using the app(使用应用程序) 4.1. Build the application(构建应用程序) 4.2. Run the Application(运行应用程序) 5. FHIR form / questionnaire (FHIR表格/问卷) 5.1. Creating your own FHIR form(创建您自己的 FHIR 表单) 5.2. Importing your FHIR form(导入您的 FHIR 表格) 这是一个基于此“this repo”的应用程序,可用于显示, “FHIR” “SDC” “Questionnaire”并收集数据作为 FHIR 问卷反馈的资源。 通过使用docker-compose up -d ,您将可以访问本地 FHIR 服务器“local FHIR server” 然后可以使用该服务器来测试应用程序。 2. 要求 该应用程序依赖于“LHC-Forms “ 渲染,用于显示表单的小部件,它支持部分 FHIR 问卷(版本 STU3 和 R4) 和结构化数据捕获实现指导“Structured Data Capture ImplementationGuide“。此小部件将与依赖项一起安装。 为可以尝试一些示例表单,这个库里在这个下面e2e-test/data/附带了一些表单, 会在构建时自动加载到本地 FHIR 服务器。 2.1. 将 Node.js 和 npm 添加到您的路径 文件 bashrc.lforms-fhir-app 指定了我们正在为开发使用的 Node.js 的版本,下载Node.js的该版本,并将其 bin 目录添加到你的路径。 2.2. 安装依赖项 通过运行此命令,您将能够安装应用程序运行所需的一切。 npm ci 3. 本地FHIR 服务器 如果您没有 FHIR 服务器来试用此应用程序,您可以在 fhir-form 文件夹中启动并使用由 InterSystems 技术支持的本地 FHIR 服务器: docker-compose up -d 等待一段时间后,您的本地 FHIR 服务器已启动,您可以使用 http://localhost:32783/fhir/r4请注意,此链接已在应用程序中注册。 4. 使用应用程序 要使用该应用程序,您必须构建“build” 并启动“start” 它。您现在可以使用应用程序的菜单访问您选择的任何 FHIR 服务器,但如果您愿意,您可以使用此本地 FHIR 服务器“ local FHIR server”。 4.1. 构建应用程序 npm run build 这将在“dist”目录中创建用于生产的文件,但也会从node_modules 复制一些需要的文件中。 4.2.运行应用程序 npm run start 将启动一个在 8000 端口运行的 http 服务器。 现在在localhost:8000/lforms-fhir-app/浏览到应用程序。 在这里您可以选择要连接的服务器。 如果要使用本地 FHIR 服务器,请启动本地 FHIR 服务器“start the local FHIR server”, 然后在应用程序上选择第一个选项 http://localhost:32783/fhir/r4 5. FHIR表格/问卷 5.1. 创建您自己的 FHIR 表单 通过使用这个在线工具“this online tool”, 您可以轻松地从头开始构建自己的表单或使用现有的表单。 我们建议您导入 e2e-tests/data/R4 文件夹中现有的一个,然后从这里开始了解该工具的工作原理。 5.2. 导入您的FHIR表格 使用该应用程序,您可以轻松导入本地表单并使用上传按钮upload 立即使用它们。 如果您使用的是工具”formbuilder tool “, 如果您有支持Content-Type 'application/json' 的 FHIR 服务器,则可以使用导出按钮将您正在创建的表单直接导出到 fhir 服务器。 如果您的服务器不支持 Content-Type 'application/json' 而只支持 Content-Type 'application/json+fhir' 例如,作为我们的本地 FHIR 服务器“local FHIR server “,您必须将表单导出到文件,然后在应用程序上 ,将文件上传到服务器,因为应用程序以 Content-Type 'application/json+fhir' 进行通信。 原文请点击该链接:https://community.intersystems.com/post/questionnaire-forms-fhir-creation-usage#3-local-fhir-server
文章
Hao Ma · 一月 4, 2023

IRIS, Caché监控指导 - 系统健康检查

以下是我们应客户的要求拟定的Caché系统健康检查的建议。InterSystems的工程师们认为其中的项目足以了解客户当前的系统健康状况。 这些项目中有些,比如Buttons, pButtons报告是必须的,其他内容,尤其是问卷部分,越多回答对系统健康的了解也越清楚。InterSystems公司的技术支持中心WRC(World Response Center),在合适的条件下可以协助用户解读健康检查的结果。 在后面的内容中, 我会详细介绍这些检查的项目,比如报告的执行步骤,已经如何简单的发现问题。 检查的内容也适用于IRIS,仅仅是执行的步骤上有细微的区别,后面文章会详细说。 ## 健康检查项目 本健康检查只用于Caché系统本身的内容, 不包括Caché上使用的各种应用。 建议用户收集下列两部分数据和资料: ### 系统运行数据 - [ ] 所有Caché实例服务器的网络架构图,包含所有的数据服务器,应用服务器,镜像服务器,灾备服务器。还应该包含网段的划分, 相关的Web服务器,负载均衡设备的部署等情况。以及一切客户认为和Caché工作相关的网络配置的情况。 - [ ] Caché数据库使用的存储设备的信息, 不限于类型,大小,品牌等等任何可以帮助了解存储设备的信息。 - [ ] 所有数据库上一次的完整性检查报告。 - [ ] 所有Caché实例的 - [ ] 系统监控检查报告(Buttons) - [ ] 24小时系统性能报告(pButtons): 所有关联的系统,比如一个Caché数据服务器以及和它连接的应用服务器(ECP服务器),应该在尽量相同的时间执行24小时pButton测量 - [ ] 一年内或自上次启动后(以其中更长时间为准)的Console日志 - [ ] 导出的日常任务(Task) - [ ] 导出的后台任务历史列表 - [ ] 系统时钟同步的配置 - [ ] 所有CSP Gateway的配置文件,以及CSP Gateway工作的Apache Web Server, Nginx Web Server,Windows IIS的配置文件。 - [ ] 如果用户使用了外部备份,请提供外部备份的操作步骤及使用的脚本程序。 ### 维护工作的问卷 以下问题的回答能帮助InterSystems的工程师更好的了解客户的Caché工作情况,以及更方便的分析上面采集的数据。 - [ ] 请列出近一年内Caché的软硬件变动 - [ ] 是否有测试环境(TestBed), 测试服务器的梳理,配置 - [ ] 请提供Caché的日常维护的情况说明,尽可能提供以下日常维护的方案,执行频率,执行时长等等。包括但不限于: - [ ] 备份恢复 - 方案,Caché在线备份还是外部备份。如果是Caché在线备份,各种备份类型的安排情况(全备份,增量备份,累计备份) - 执行频率,执行的时间点 - 各种数据量情况下的执行时长,不如全备份的时长,增量备份的数据量是多少,执行时长是多少等等 - [ ] 数据库完整性检查 - 完整性检查的方案,频率 - 数据库的大小及对应的完整性检查的执行时长 - [ ] 告警通知 - 告警通知发送的方式。(告警通知默认是Console log里严重级别为2,3的条目) - 告警通知的处理流程 - 告警通知的产生:是否有客户定制的通知消息 - Console Log中出现的严重级别为1的消息(Warning消息)是否被通知,或者是否有任何处理方式 - [ ] 性能测量 - 提供业务活动量在一段时间内的变动模式, 比如一周,一天中业务量的忙时,闲时,以及是否月初活着月底有大的报表生成等等 - 详细列出各种周期性执行的和Caché性能相关的操作的时间点和时长,处了上面提到的备份恢复,数据库完整性检测等,还可以是任意的Caché操作,以及Caché所在的虚拟机,服务器的操作,还可以包括可能影响Caché性能表现的连接的第3方的业务系统监控系统,审计系统的与之有关的操作 - 是否有常规的性能测试方案,包括Caché上的指标测量(pButtons), 以及操作系统的性能指标测量 - 无论以何种形式,是否能提供Caché系统的性能基准。这个性能基准应该以客户的业务活动量做为采样周期,比如以周为单位 - 上述指标是否能提供图表的展示 - [ ] 尽可能的提供近一年中在Caché日常维护中遇到的各种故障及异常的列表。对列表中的每一项,尽量提供详细的描述和信息,包括并不限于: - 是否报告InterSystems, 如果报告了, WRC号码是多少 - 发生的频率如何? - 如果已经有解决,解决的方案是什么? - 如果没有经过人工处理,那么故障恢复的时长平均是多少? - 维护工程师对故障产生的原因以及造成后果的分析讨论的结果,如果有。 - [ ] 其他内容(可选) - Caché维护团队的工作分配, 以及相关的外部团队的职责,比如应用实施方,用户的其他IT团队,硬件维护,硬件监控团队等等。 - 对Caché维护最期待的改进,工具的提供等 - 其他任何有关Caché维护工作而上面各项中未涵盖的内容。
文章
Michael Lei · 五月 24, 2021

大数据平台的五个等级

作为一个软件架构师,如果要设计一个企业级的架构来满足当前的业务需求时,你需要达到5级的水平,这是一个巨大的挑战。有了InterSystems IRIS。这是有可能的。通过1个产品,你可以得到SQL + NoSQL + ESB + BI + Open Analytics + Real Time Virtual cubes + NLP + AutoML + ML(使用Python)和高级云支持 + Sharding支持。 以Oracle为例,你需要Oracle数据库+ Oracle NoSQL+ Oracle BI+ Oracle SOA套件+一些附加组件,如R、Partitioning和RAC以及一些Oracle云产品的NLP和AI功能。对于开源架构、IBM或者其他友商来说,也是类似的,你需要的组件只可能更多。 医疗机构在数字化转型在技术上最大的挑战之一,就是技术栈过于丰富、快速变化以及对人的技术要求很高(这也是为什么全栈工程师最值钱的原因);一个统一、高效、稳定、现代化、专为医疗定制的一体化数据平台能帮助客户很好地解决这个问题。IRIS for Health 是您的不二选择。
文章
Michael Lei · 六月 1, 2022

部分IRIS-2022-年度编程大奖赛作品展示——定制化 IRIS 互操作production的监控页面

InterSystems Production 监控是管理门户中的一个页面,用于显示当前运行的Production监控信息。我喜欢这个页面的样子,但这并不适合所有人。 2022年5月13日,我在开发者社区上看到这个帖子。 https://community.intersystems.com/post/creating-custom-monitoring-page 我同意马克的观点,Production监控很复杂。我想创建一个更漂亮干净的监控页面。 我开始着手制作一个利用类方法提供Production数据的 CSP(Cache Server Page)页面。 我与马克分享了我的第一次尝试。他根据自己的想法定制了这个页面。我喜欢他对页面的布局,使其在视觉上更有吸引力。我把他的设计整合到我的应用程序Production监控中。 我看到马克对业务服务的显示进行了过滤,只显示需要注意的服务。他在页面的底部添加了服务器的名称和它的镜像状态。 你可以在Open Exchange和当前的竞赛中找到我的Production监控器的应用。 https://openexchange.intersystems.com/package/production-monitor
公告
Claire Zheng · 十一月 22, 2021

欢迎段海华——我们开发者社区中文版的新版主!

大家好! 我们很高兴地向大家介绍我们开发者社区中文版的新版主——段海华( @Duan.Haihua)! 让我们以热烈的掌声欢迎段海华( @Duan.Haihua),以下是他的个人介绍。 段海华,东华医为利润中心副主管 以下是他的个人介绍 @Duan.Haihua: – 我主持参加了多家医院的互联互通评审工作,并主持了互联互通成熟度测评(Health Information Connectivity Maturity Evaluation, HICME)工具的开发与维护。我有丰富的基于InterSystems产品和项目工作经验,对互联互通测评相关标准有较深刻的理解。 – 通过开发者社区,我希望能够帮助刚开始接触互联互通标准的开发者快速理解相应内容,分享互联互通测评过程中常见问题的解决方案,为开发者对系统标准化改造过程提供参考意见。 热烈欢迎! 感谢段海华的付出( @Duan.Haihua)!我们相信你会成为一名优秀的版主! 👏🏼 热烈欢迎👏!!!
文章
Michael Lei · 八月 18, 2022

使用csvgen从文件或URL地址中以编程方式导入CSV

Hi 社区的朋友们,大家好! 有时我们需要以编程方式自动将CSV数据从文件或者UR网址L导入到InterSystems IRIS。我们希望创建具有适当数据类型的类并导入数据。 我在Open Exchange上发布了一个模块csvgen,它正是这样做的。 如果你只需要将CSV文件导入IRIS,你可以这么做: USER>do ##class(community.csvgen).Generate("/usr/data/titanic.csv",,"Data.Titanic") Class name: Data.Titanic Header: PassengerId INTEGER,Survived INTEGER,Pclass INTEGER,Name VARCHAR(250),Sex VARCHAR(250),Age INTEGER,SibSp INTEGER,Parch INTEGER,Ticket VARCHAR(250),Fare MONEY,Cabin VARCHAR(250),Embarked VARCHAR(250) Records imported: 891 USER> 或者你的CSV文件在互联网上, 例如GitHub上面的新冠疫情数据 你可以这样获得数据: USER>d ##class(community.csvgen).GenerateFromURL("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_daily_reports/05-29-2020.csv",",","Data.Covid19") Class name: Data.Covid19 Header: FIPS INTEGER,Admin2 VARCHAR(250),Province_State VARCHAR(250),Country_Region VARCHAR(250),Last_Update DATE,Lat MONEY,Long_ DOUBLE,Confirmed INTEGER,Deaths INTEGER,Recovered INTEGER,Active INTEGER,Combined_Key VARCHAR(250),Incidence_Rate DOUBLE,Case-Fatality_Ratio DOUBLE Records imported: 3522 USER> Installation安装 从ZPM安装: USER>zpm zpm:USER>install csvgen csvgen 模块是打包了 CSV2CLASS method . ObjectiveScript 的profile还不是很理想,欢迎各种建议意见。谢谢!
文章
Jeff Liu · 五月 15

一些 FHIR 互操作性适配器示例

各位开发者,大家好! 或许您不得不实现一些场景,这些场景不需要 FHIR 仓库但需要转发 FHIR 请求、管理响应,并且可能运行转换或在两者之间提取一些值。 在这里,您会找到一些可以使用 *InterSystems IRIS For Health* 或 *HealthShare Health Connect* 实现的示例。 在这些示例中,我使用了具有 [FHIR 互操作性适配器](https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.UI.Page.cls?KEY=HXFHIR_fhir_adapter)和 `HS.FHIRServer.Interop.Request` 消息的互操作性生产配置。 第一个场景从头开始构建 FHIR 请求(可以来自文件,也可以来自 SQL 查询),然后将其发送到外部 FHIR 服务。![图片](/sites/default/files/inline/images/scenario-fhirclient-file-simple.png) 下一个场景是一种 FHIR 传递,用于将请求和响应传递到外部 FHIR 仓库,另外还管理 OAuth 令牌。![图片](/sites/default/files/inline/images/scenario-fhirserver-passthrough.png) 最后一个场景包括接收 FHIR 请求,然后将其转发到外部 FHIR 服务,但会提取信息或更改其间的某些字段。![图片](/sites/default/files/inline/images/scenario-fhirservice-handler.png) 您将在 Open Exchange 应用程序中找到实现细节 :) 希望这对您有用!
问题
water huang · 四月 22, 2021

m里面如何获取cpu的序列号?

m 里面如何获取cpu的序列号? 可以调用操作系统的命令来获取CPU序列号。例如在Cache' for Windows上,可以执行:SAMPLES>s args=3SAMPLES>s args(1)="CPU"SAMPLES>s args(2)="get"SAMPLES>s args(3)="ProcessorID"SAMPLES>d $ZF(-100,"","wmic",.args)ProcessorId0FABFBFF000506EX0FABFBFF000006EX0FABFBFF000006EX0FABFBFF000006EX 乔工,请问 $zf函数的使用,在哪里可以查询到它的所有使用说明 InterSystems Cache'InterSystems IRIS 刚才试了一下,这个不行呢 感谢你的回答 但是我用的是ensemble2016 是Windows吗?在Windows命令行,执行wmic CPU get ProcessorID,能得到CPU序列号吗? Ensemble 2016有点久,没有$ZF(-100)。用$ZF(-1): https://cedocs.intersystems.com/ens20161/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS_fzf-1#RCOS_B80417 是Windows,在Windows命令行,执行wmic CPU get ProcessorID,能得到CPU序列号 刚才试了 还是不行 用$ZF(-1), 可以将OS命令输出保存到文件里。例如:w $ZF(-1,"wmic CPU get ProcessorID > c:\temp\cpuinfo.txt") 系统是windows 10 试了,不行,返回的值是1 返回值是1,说明报错了。确认一下是否OS命令写正确了。另外,输出不是看返回值,是看输出的文件 我直接复制的你写的这个命令。
文章
姚 鑫 · 三月 31, 2021

第十四章 使用SQL Shell界面(二)

# 第十四章 使用SQL Shell界面(二) # 存储和调用SQL语句 ## 通过数据回调 SQL Shell自动将在终端会话期间发出的每个成功的SQL语句存储在本地缓存中,并为其分配一个顺序号。这些数字用于在当前Terminal过程中重新调用以前的SQL语句。 SQL Shell仅将数字分配给成功的SQL语句。如果在准备SQL语句期间发生错误,则不会分配任何编号。这些数字分配不是特定于名称空间的。以下是可用的数字调用命令: - `#`:可以使用#列出所有先前缓存的SQL语句及其分配的编号。 - `#n`:可以通过在SQL Shell提示符下指定#n来调用并执行先前的SQL语句,其中`n`是SQL Shell分配给该语句的整数。 - `#0`:可以通过在SQL Shell提示符下指定`#0`来调用并执行最近准备的SQL语句。 `#0`调用最近准备的SQL语句,而不必调用最近执行的SQL语句。因此,调用和执行SQL语句对#0调用哪个SQL语句没有影响。 通过数字调用SQL语句不会为该语句分配新的数字。 SQL Shell在终端会话的持续时间内顺序分配数字;退出并重新进入SQL Shell或更改名称空间不会影响数字分配或先前分配的数字的有效性。 要删除所有号码分配,请使用`#CLEAR`并在显示的提示符下确认此操作。这将删除所有先前的号码分配,并从1重新开始号码分配。 ## 通过名字回调 可以选择为SQL语句分配名称,然后按名称重新调用该语句。这些名称用于重新调用从任何当前用户的Terminal进程发出的SQL语句。通过名称保存和调用SQL语句有两种方法: - 使用`SAVEGLOBAL`保存到全局;使用`OPEN`从全局调用。 - 使用`SAVE`保存到文件;使用`LOAD`从文件中调用。 ### 保存到全局变量 要将全局名称分配给最新的SQL语句,请使用sql shell命令`saveglobal`名称,该名称可以缩写为`SG`名称。然后,可以使用SQL Shell命令打开名称来调用全局的SQL语句。如果`Executemode`是立即的,则SQL shell都会调用并执行该语句。如果延迟了`executemode`,则将准备该语句,但在指定`GO`命令之前,不会执行该语句。 每次使用打开名称以全局名称调用SQL语句时,SQL shell会为语句分配新号码。旧的和新数字都对调用数字仍然有效。 名称可以包含除空白字符之外的任何可打印字符。名称中的字母区分大小写。名称可以是任何长度。名称特定于当前命名空间。可以多次使用不同名称保存相同的SQL语句;所有已保存的名称都保持有效。如果使用已分配的名称保存SQL语句,则SQL Shell会提示是否希望覆盖现有名称,将其重新分配给新的SQL语句。 为当前命名空间分配全局名称。可以使用SQL Shell `L`(或列表)命令列出当前命名空间的所有分配的全局名称。分配后,所有当前用户的终端进程都可以使用名称。在创建它结束的终端进程后,分配的名称仍然存在。如果没有名称分配,则列表返回“保存”消息的“无语句”。 要删除全局名称分配,请使用清除名称。要删除当前命名空间的所有全局名称分配,请在显示的PROMP下使用清除并确认此操作 ### 保存到文件 要将文件名分配给最新的SQL语句,请使用SQL Shell命令保存名称。然后,可以使用SQL Shell命令加载名称来调用SQL语句。如果`Executemode`是立即的,则SQL shell都会调用并执行该语句。每次使用`Load Name`按文件名调用SQL语句时,SQL Shell会将新号码分配给语句。旧的和新数字都对召回数字仍然有效。 名称可以包含除空白字符之外的任何可打印字符。名称中的字母区分大小写。名称可以是任何长度。名称特定于当前命名空间。可以多次使用不同名称保存相同的SQL语句;所有已保存的名称都保持有效。如果尝试使用已分配的名称保存SQL语句,则SQL Shell会提示是否希望覆盖现有名称,将其重新分配给新的SQL语句。 为当前命名空间分配名称。分配后,所有当前用户的终端进程都可以使用名称。在创建它结束的终端进程后,分配的名称仍然存在。 # 清除缓存查询Query SQL shell提供了清除(缩写`p`)命令,以清除当前命名空间中的所有缓存查询。此命令清除名称空间中的所有缓存查询,而不仅仅是使用SQL Shell生成的查询。 `$SYSTEM.SQL.Purge()`方法和管理门户操作下拉列表选项为提供了更具体的选项,仅清除所选择的缓存查询或清除命名空间中的所有缓存查询。 # 配置SQL shell - 可以使用Management Portal配置SQL Shell默认值。 - 可以使用SQL Shell参数配置单个SQL shell。更改SQL Shell参数覆盖SQL shell的当前调用的系统范围默认值;它不会更改系统范围的SQL shell默认值。 以下是可用的SQL Shell配置选项,相应的shell参数和默认设置: 管理门户shell配置| Shell 参数| 默认 ---|---|--- Select Mode| selectmode| Logical SQL Dialect (TSQL) |dialect (TSQL) |IRIS Schema Search Path| path| none Result Column Alignment| colalign |Delimiter Command Prefix (TSQL)| commandprefix (TSQL)| none Result Output Display Mode |displaymode |Current Device Display Path| displaypath|none Display File| displayfile| none Display File Translate Table| displaytranslatetable|none Echo Mode |echo| On Execute Mode| executemode|| Immediate Messages Mode| messages| On IF condition to allow execution || 1 | |log| Off 标记为(TSQL)的参数主要用于从SQL Shell执行`Sybase`或`MSSQL` `Transact-SQL`代码。 ## 配置SQL Shell系统范围默认值 转到管理门户,选择系统管理,配置,SQL和对象设置,SQL。选择SQL Shell选项卡。查看并设置SQL Shell系统范围的当前默认设置。 如果更改一个或多个配置设置,则在管理门户路径之后立即由屏幕的左上角的星号(`*`)表示。例如,系统>配置> SQL *。按SAVE按钮接受更改。激活更改,星号消失。 ## 为SQL shell配置参数 SQL Shell配置参数特定于当前终端进程上的当前SQL Shell调用。设置跨名称空间应用。但是,如果退出SQL Shell,则所有SQL Shell参数都会重置为系统宽的默认值。 Intersystems Iris提供系统默认值;您可以使用Set Save建立当前进程的不同默认值,如下所述。 SQL shell set命令(没有参数)显示当前shell配置参数,如以下示例所示。在此示例中,该组显示系统默认值,这些值是调用SQL Shell时建立的值: ```java [SQL]USER>>SET commandprefix = "" dialect = IRIS displayfile = displaymode = currentdevice displaypath = displaytranslatetable = echo = on executemode = immediate log = off messages = on path = SQLUser selectmode = logical [SQL]USER>> ``` 要显示单个配置参数的当前设置,请指定`set param`。例如,`SET SelectMode`返回当前选择介绍设置。 可以使用`SQL Shell Set`命令设置shell配置参数。 SQL Shell调用的持续时间持续一个设定值;每次调用SQL shell时,参数都会重置为默认值。设置可以使用以下任一语法表单: ```java SET param value SET param = value ``` 参数和值都不区分大小写。允许空间,但不需要,之前和之后。 SQL Shell `Set Save`命令将当前shell配置参数设置保存为用户默认值。这些默认值应用于当前进程的所有后续SQL Shell调用。它们也被应用于SQL Shell默认值,以在该用户调用的终端过程中的任何后续调用的SQL Shell。它们仍然有效,直到特别重置。使用`Set`保存不会影响当前正在运行的SQL Shell调用。 SQL Shell `Set Clear`命令清除(重置为系统默认值)当前进程的当前shell配置参数设置。 Intersystems IRIS将此重置应用于当前进程的后续SQL Shell调用,或者当前用户调用的任何新终端进程。设置清除不会影响当前运行的SQL Shell调用。 既不设定保存也没有设置清除更改系统范围的SQL Shell Shell默认设置,使用管理门户进行配置和显示。 ## Setting COLALIGN 可以使用`Set Colalign`来指定用于显示查询`ResultSet`数据和列标题的空格格式。可用选项包括: - 分隔符:`ResultSet`标题/数据列将基于标准分隔符(标签)对齐。这是默认值。 - 标题:`ResultSet`标题/数据列将基于列标题的长度和标准分隔符(标签)对齐。 - 数据:`ResultSet`标题/数据列将基于列数据属性的精度/长度和标准分隔符(标签)对齐。 ## 设置displaymode和displaytranslatetable 可以使用`Set DisplayMode`指定用于显示查询数据的格式,如以下示例所示: ```java DHC-APP>DO $SYSTEM.SQL.Shell() SQL Command Line Shell ---------------------------------------------------- The command prefix is currently set to: . Enter q to quit, ? for help. DHC-APP>>SET DISPLAYMODE XML displaymode = xml DHC-APP>> ``` `DisplayMode`默认值是`CurrentDevice`,其在TXT格式中显示终端上的查询数据。可以指定`set displaymode = cur`恢复`CurrentDevice`默认值。 其他可用选项有`TXT`、`HTML`、`PDF`、`XML`和`CSV`。 格式的选择决定了文件类型。 InterSystems IRIS创建这种类型的文件,将查询数据写入该文件,并在可能的情况下启动适当的程序来显示该查询数据文件。 对于除TXT之外的所有选项,将创建第二个文件来记录结果集消息。 默认情况下,SQL Shell在InterSystems IRIS mgr\Temp\目录中创建这些文件,并分配一个随机生成的带有适当文件类型后缀的文件名。 生成的消息文件名与数据文件名相同,除了附加的字符串`“Messages”`。 对于`HTML`、`PDF`和`XML`选项,消息文件具有与查询数据文件相同的文件类型后缀。 对于`CSV`选项,消息文件具有`TXT`文件类型后缀。 以下是`DisplayMode = TXT`时创建的文件的示例: ``` C:\InterSystems\IRIS\mgr\Temp\sGm7qLdVZn5VbA.txt C:\InterSystems\IRIS\mgr\Temp\sGm7qLdVZn5VbAMessages.txt ``` 每次运行查询时,SQL shell都会创建一个具有随机生成的文件名的新文件。 如果显示屏是`txt`或`csv`,则可以选择在执行格式转换时指定要应用的翻译表的名称可以指定`SET DISPLAYTRANSLATE`或`SET DISPLAYTRANSLATERATE`。转换表名称值区分大小写。 如果`DisplayMode`被设置为除`CurrentDevice`以外的值,则任何查询结果集包含控制字符的数据会导致生成的警告消息。通常,控制字符仅在逻辑模式下出现在查询结果集数据中。例如,列表结构中的数据包含在逻辑模式下显示的控制字符。因此,建议将`DisplayMode`设置为`CurrentDevice`以外的值时,还将`SelectMode`设置为显示或ODBC。 ### 设置displayfile和displaypath 如果`DisplayMode`设置为`“CurrentDevice以外的值”`,则可以使用`DisplayFile`和`DisplayPath`参数指定目标文件位置: - `DISPLAYFILE:`设置为一个没有后缀的简单文件名; 例如:`SET DISPLAYFILE = myfile`。 也可以将该参数设置为部分限定路径,系统间的IRIS将该路径追加到`DISPLAYPATH`值或默认目录中,根据需要创建子目录; 例如:`SET DISPLAYFILE = mydir\myfile`。 如果设置了`DISPLAYPATH`,系统将在指定的目录中创建一个以该文件名命名的文件; 如果没有设置`DISPLAYPATH`,系统将在InterSystems IRIS mgr\Temp\目录下创建一个以该文件名命名的文件。 - `DISPLAYPATH:`根据操作系统平台的不同,设置为以斜杠(`“/”`)或反斜杠(`“\”`)结尾的现有的全限定目录路径结构。 如果设置了`DISPLAYFILE`,系统将在此目录下创建一个名为`DISPLAYFILE`的文件; 如果没有设置`DISPLAYFILE`,系统将在该目录下创建一个随机生成的文件名文件。 如果目录`“DISPLAYPATH”`不存在,InterSystems IRIS将忽略`“DISPLAYPATH”`和`“DISPLAYFILE”`的设置,使用默认目录和随机生成的默认文件名。 必要时,系统自动在`DISPLAYPATH`值的末尾添加斜杠(或反斜杠)和/或从`DISPLAYFILE`值的开始删除斜杠(或反斜杠),以创建有效的完全限定目录路径。 设置`DISPLAYMODE`、`DISPLAYFILE`和`DISPLAYPATH`: ```java DHC-APP>>SET DISPLAYMODE XML displaymode = xml DHC-APP>>SET DISPLAYFILE = myfile displayfile = myfile DHC-APP>>SET DISPLAYPATH = C:\temp\mydir\ displaypath = C:\temp\mydir\ DHC-APP>> ``` 执行查询时,SQL shell将生成以下文件。第一个包含查询数据。第二个包含Query执行产生的任何消息: ```java C:\temp\mydir\myfile.xml C:\temp\mydir\myfileMessages.xml ``` 如果既不指定`DISPLAYFILE`也不指定`DISPLAYPATH`,系统将在Mgr\Temp\目录下为InterSystems IRIS安装(例如,`C:\InterSystems\IRIS\Mgr\Temp\`)创建一个随机生成的文件名。 如果显示屏未设置为`CurrentDevice`,则每次使用`displayfile`集运行查询时,命名文件中的任何现有数据都会被新查询数据替换为新的查询数据。每次使用`displayfile`未设置查询时,SQL shell都会使用随机生成的文件名和新的相应邮件文件创建一个新文件。 如果`displaymode`设置为`currentDevice`,则`DisplayFile`和`DisplayPath`参数无效。 ## 设置executemode SQL Shell支持立即和延迟的SQL语句执行。立即执行准备并在按Enter键时执行指定的SQL语句。延迟执行准备在输入Enter时,但在指定转到SQL提示符之前,不会执行它。 可用选项已立即设置`ExecuteMode`(默认值),设置`ExecuteMode`延迟和设置`ExecuteMode`以显示当前模式设置。以下示例设置执行模式: ```java DHC-APP>>SET EXECUTEMODE DEFERRED Executemode = deferred ``` 延迟执行允许准备多个SQL查询,然后按名称或编号调用它们以进行执行。要执行准备好的SQL语句,请调用所需的语句(来自适当的命名空间),然后指定`Go`。 以下示例显示了在延迟模式下准备三个查询。前两个保存并分配了调用名称;第三个未分配一个名称,但可以通过数字来调用: ```java DHC-APP>>SELECT TOP 5 Name,Home_State FROM Sample.Person 1. SELECT TOP 5 Name,Home_State FROM Sample.Person --------------------------------------------------------------------------- DHC-APP>>SAVE 5sample ...statement saved as: 5sample DHC-APP>>SELECT TOP 5 Name,Home_State FROM Sample.Person ORDER BY Home_State 2. SELECT TOP 5 Name,Home_State FROM Sample.Person ORDER BY Home_State --------------------------------------------------------------------------- DHC-APP>>SAVE 5ordered ...statement saved as: 5ordered DHC-APP>>SELECT Name,Home_State FROM Sample.Person ORDER BY Home_State 3. SELECT Name,Home_State FROM Sample.Person ORDER BY Home_State --------------------------------------------------------------------------- ``` 以下示例显示了延迟模式执行前一个示例中定义的两个查询的执行。请注意,此示例通过名称调用一个查询(在调用SQL Shell提供新号码时,并按编号调用一个查询: ```java DHC-APP>>go C:\InterSystems\Cache\mgr\Temp\ffQlXfFdbGnOxA.xml Messages.xml statement prepare time(s)/globals/lines/disk: 0.0526s/45464/263430/5ms execute time(s)/globals/lines/disk: 0.2948s/153553/1042318/75ms --------------------------------------------------------------------------- ``` ## Setting ECHO 可以使用`Set Echo`来指定是否将查询结果恢复到SQL Shell。如果指定`SET Echo = OFF`,则准备查询,定义缓存查询,并执行查询。终端没有查询结果。这在以下示例中显示: ```java DHC-APP>>set echo=off echo = off DHC-APP>>SELECT Name,Age FROM Sample.Person 4. SELECT Name,Age FROM Sample.Person -------------------------------------------------------------------------- ``` 如果指定`SET Echo = ON`(默认值),则将查询结果显示给终端。这在以下示例中显示: ```java DHC-APP>>set echo=on echo = on DHC-APP>>SELECT Name,Age FROM Sample.Person 5. SELECT Name,Age FROM Sample.Person --------------------------------------------------------------------------- DHC-APP>>go C:\InterSystems\Cache\mgr\Temp\LVZpPfjfxXXJBg.xml Messages.xml statement prepare time(s)/globals/lines/disk: 0.0001s/5/187/0ms execute time(s)/globals/lines/disk: 0.1613s/152365/1040157/0ms --------------------------------------------------------------------------- ``` `SET Echo`如果`displaymode = currentDevice`(默认值)仅有意义。 `SET ECHO`和`SET MESSAGES`指定终端显示的内容; 它们不会影响查询的准备或执行。 如果`SET MESSAGES=OFF和SET ECHO=OFF`,则查询准备好了,一个缓存的查询被创建,查询执行创建一个查询结果集,但是没有返回给终端。 ## Setting MESSAGES 可以使用`SET MESSAGES`来指定是否显示查询错误消息(如果不成功)或查询执行信息(如果成功): - 如果查询执行不成功:如果指定`SET MESSAGES=OFF`,则终端不会显示任何信息。 如果指定`SET MESSAGES=ON`(默认值),则返回查询错误提示,如下所示`:error #5540: SQLCODE: -30 message: Table 'SAMPLE`。 值得注意的没有找到。 - 如果查询执行成功:如果指定`SET MESSAGES=OFF`,则只显示查询结果和受影响的`n`行。 如果指定`SET MESSAGES=ON`(默认值),则查询结果和受影响的`n`行(`s`行)后面紧跟着语句准备度量、语句执行度量和生成的缓存查询的名称。 准备和执行指标以运行时间(以毫秒为单位)、全局引用总数、执行的命令总数和磁盘读取延迟(以毫秒为单位)来衡量。 设置`DISPLAYMODE`不会改变`SET MESSAGES=ON`时显示的信息。 一些`DISPLAYMODE`选项同时创建一个查询结果集文件和一个消息文件。 该消息文件包含结果集消息,而不是`set messages =ON`时显示到终端的查询准备和执行消息。 设置消息并设置`echo`指定终端上显示的内容;它们不会影响查询的准备或执行。如果`SET MESSAGENT = OFF`和`SET ECHO = OFF`,则准备成功的查询,创建缓存的查询,查询执行创建查询结果集,但没有返回到终端。 ## Setting LOG 可以使用`Set`日志指定是否将SQL Shell活动记录到文件。可用选项包括: - `SET LOG OFF`: 默认值。 Intersystems IRIS不会为当前SQL Shell记录活动。 - `SET LOG ON`: Intersystems Iris将SQL Shell活动记录到默认日志文件。 - `SET LOG pathname`:Intersystems Iris将SQL Shell活动记录到`Pathname`指定的文件。 `SET LOG ON`在IRIS\mgr\namespace中创建一个日志文件,其中namespace是进程当前命名空间的名称。 这个默认日志文件名为xsqlnnnn。 其中nnnn是当前进程的进程ID (pid)号。 日志文件可以挂起并恢复。 创建日志文件后,`SET log OFF`会挂起对该日志文件的写入。 设置`LOG ON`恢复写入默认日志文件。 日志重新启动:日志恢复时,将日期时间写入日志文件。 设置`LOG ON`总是激活默认日志文件。 因此,如果暂停写入指定的路径名日志文件,则在恢复时必须指定`SET log pathname`。 激活日志文件创建终端上显示的SQL Shell活动的副本;它不会重定向SQL Shell终端输出。 SQL Shell Log为失败的SQL执行和SQL代码记录SQL错误,并为成功的SQL执行而导致的行计数。 SQL Shell日志不会记录结果集数据。 如果日志已处于活动状态,则指定“设置”登录无效。如果日志已处于活动状态,则指定设置日志路径名暂停当前日志并激活路径名指定的日志。、 ## Setting PATH 可以使用SET路径架构来设置Schema Search Path,SQL用于提供不合格表名的正确架构名称。架构可以是单个架构名称,或者逗号分隔的架构名称列表,如下例所示: ```java DHC-APP>>SET PATH cinema,sample,user path = cinema,sample,user ``` 没有任何参数的设置路径删除了当前架构搜索路径,恢复系统范围的默认模式名称。 如果未指定`SET`路径架构,或者在指定的模式中找不到表,则SQL Shell使用系统范围的默认模式名称。 ## Setting SELECTMODE 可以使用`SetSeliteMode`指定用于显示查询数据的模式。 ```java DHC-APP>>SET SELECTMODE DISPLAY selectmode = display ``` 可用选项显示,逻辑和ODBC。逻辑是默认值。要确定当前模式,请指定`SETELESMODE`,无需值: ```java DHC-APP>>SET SELECTMODE logical selectmode = logical ``` `%List`数据使用非打印字符进行编码。因此,当`SelectMode =逻辑`时,SQL shell将`%List`数据值显示为`$listbuild`语句,例如以下`$lb("White","Green")`。时间数据类型数据支持分数秒。因此,当`SelectMode = ODBC`时,SQL Shell显示分数秒,这与ODBC标准不对应。实际的ODBC时间数据类型截断分数秒。 还可以使用`SET SELECTMODE`指定输入数据是否将从显示格式转换为逻辑存储格式。 要进行此数据转换,必须使用`select`运行时模式编译SQL代码。 在执行时,`SET SELECTMODE`必须设置为`LOGICAL`(默认值)。
文章
姚 鑫 · 二月 21, 2021

第四十三章 Caché 变量大全 $ZTIMEZONE 变量

# 第四十三章 Caché 变量大全 $ZTIMEZONE 变量 包含格林威治子午线的时区偏移量。 # 大纲 ``` $ZTIMEZONE $ZTZ ``` # 描述 `$ZTIMEZONE`可以通过两种方式使用: - 返回计算机的本地时区偏移量。 - 为当前进程设置本地时区偏移量。 `$ZTIMEZONE`包含从格林威治子午线偏移的时区(以分钟为单位)。 (格林威治子午线包括整个英国和爱尔兰。)此偏移量表示为-1440到1440范围内的有符号整数。格林威治以西的时区指定为正数;格林威治东部的时区指定为负数。 (时区必须以分钟为单位,因为并非所有时区都以小时为单位。)默认情况下,`$ZTIMEZONE`初始化为计算机操作系统设置的时区。 注意:`$ZTIMEZONE`将本地时间调整为固定的偏移量。它不适应夏令时或其他当地时间的变化。 InterSystems IRIS从基础操作系统获取本地时间,该操作系统将本地时间变体应用于为该计算机配置的位置。因此,使用`$ZTIMEZONE`调整的本地时间将从配置的语言环境中获取其本地时间变化,而不是在`$ZTIMEZONE`中指定的时区。 使用格林威治子午线(`$ZTIMEZONE = 0`)的时区计数来计算UTC时间。它与当地格林威治时间不同。格林威治标准时间(GMT)一词可能令人困惑;格林威治的当地时间与冬季的UTC相同。在夏季,它与UTC的差异为一小时。这是因为应用了称为英国夏令时的本地时间变体。 对于使用`$ZTIMEZONE`的函数和程序,经过的本地时间始终是连续的,但是时间值可能需要季节性调整以与本地时钟时间相对应。 ## 设定时区 可以使用`$ZTIMEZONE`设置当前InterSystems IRIS进程使用的时区。设置`$ZTIMEZONE`不会更改默认的InterSystems IRIS时区或计算机的时区设置。 注意:更改`$ZTIMEZONE`特殊变量是为某些特殊情况设计的功能。更改`$ZTIMEZONE`并不是更改InterSystems IRIS用于本地日期/时间操作的时区的一致方法。除非已准备好处理所有导致的不一致的程序,否则不应更改`$ZTIMEZONE`特殊变量。 在某些平台上,更改时区可能比更改`$ZTIMEZONE`特殊变量更好。如果平台具有特定于进程的时区设置(例如POSIX系统上的TZ环境变量),则进行外部系统调用来更改特定于进程的时区可能比更改`$ZTIMEZONE`更好。在操作系统级别更改特定于流程的时区将更改UTC的本地时间偏移,并应用确定何时应用本地时变的相应算法。如果默认系统时区在北半球,而所需的过程时区在南半球,则这尤其重要。更改`$ZTIMEZONE`会将本地时间更改为与UTC偏移的新时区,但是确定何时应用本地时变的算法保持不变。 使用`SET`命令将`$ZTIMEZONE`设置为指定的带符号整数分钟数。数字的前导零和小数部分将被忽略。如果在设置`$ZTIMEZONE`时指定非数字值或无值,则InterSystems IRIS会将`$ZTIMEZONE`设置为0(格林威治子午线)。 例如,北美东部标准时间(EST)在格林威治以西五个小时。因此,要将当前的InterSystems IRIS流程设置为EST,则需要指定300分钟。要指定格林威治以东一小时的时区,请指定–60分钟。要指定格林威治本身,可以指定0分钟。 设置`$ZTIMEZONE`: - 影响无参数的`$NOW()`当地时间值。它更改了`$NOW()`的时间部分,并且此时间更改也可以更改当前进程的`$NOW()`的日期部分。 `$NOW()`精确地反映了`$ZTIMEZONE`设置,其值未针对本地时变进行调整。 - 影响`$HOROLOG`当地时间值。 `$HOROLOG`从`$ZTIMEZONE`获取其时区值,然后季节性调整本地时间,例如夏令时。因此,`$HOROLOG`始终符合本地时钟时间,但全年的`$HOROLOG`经过时间不是连续的。 - 影响`%SYSTEM.Util`类方法`IsDST()`,`UTCtoLocalWithZTIMEZONE()`和`LocalWithZTIMEZONEtoUTC()`。 - 不会影响`$ZTIMESTAMP`或`$ZHOROLOG`值。 - 不会影响`$ZDATE`,`$ZDATEH`,`$ZDATETIME`,`$ZDATETIMEH`,`$ZTIME`和`$ZTIMEH`函数执行的日期和时间格式转换。 - 不会影响`$NOW(n`)函数。 - 不会影响`%SYSTEM.Process`类的`FixedDate()`类方法,该方法将`$HOROLOG`中的日期设置为固定值。 更改`$ZTIMEZONE`后发生以下异常: - `$ZDATETIME($HOROLOG,1,7)`通常返回UTC时间,但是如果`$ZTIMEZONE`已更改,它将不返回UTC时间。 - 如果`$ZTIMEZONE`已更改,`$ZDATETIME($HOROLOG,1,5)`将不会返回正确的时区偏移量。 - 如果`$ZTIMEZONE`已更改,则本地时间和UTC时间之间的`$ZDATETIME($HOROLOG,-3)`和`$ZDATETIMEH($ZTIMESTAMP,-3)`转换将不正确。 ## 其他时区方法 可以通过调用`TimeZone()`类方法来获取相同的时区信息,如下所示: ```java DHC-APP>WRITE $SYSTEM.SYS.TimeZone() -480 ``` 可以使用tformat值为5或6的`$ZDATETIME`和`$ZDATETIMEH`函数,将本地时间变化作为日期和时间字符串的一部分返回,如以下示例所示 ```java DHC-APP>WRITE !,$ZDATETIME($HOROLOG,1,5) 02/10/2021T18:24:21+08:00 ``` 该字符串的最后一部分(+08:00)表示系统的本地时间变化设置,以格林威治子午线为单位,以小时和分钟为单位进行偏移。注意,这种变化不一定是时区偏移量。在上述情况下,时区位于格林威治(-5:00)西部5小时,但是本地时区(夏令时)将时区时间偏移一小时到-04:00。设置`$ZTIMEZONE`将更改`$ZDATETIME($HOROLOG,1,5)`返回的当前处理日期和时间,但不会更改系统本地时间变化设置。 ## `$ZDATETIMEH`使用时区设置 可以将`$ZDATETIMEH`与`dformat = -3`一起使用,以将协调世界时(UTC)日期和时间值转换为本地时间。该函数将UTC值(`$ZTIMESTAMP`)作为输入。它使用本地时区设置来返回相应的日期和时间,并在适用的情况下应用本地时变(例如夏时制)。 ```java /// d ##class(PHA.TEST.SpecialVariables).ZTIMEZONE() ClassMethod ZTIMEZONE() { SET clock=$HOROLOG SET stamp=$ZDATETIMEH($ZTIMESTAMP,-3) WRITE !,"本地/本地日期和时间: ",$ZDATETIME(clock,1,1,2) WRITE !,"UTC/本地日期和时间: ",$ZDATETIME(stamp,1,1,2) } ``` ```java DHC-APP>d ##class(PHA.TEST.SpecialVariables).ZTIMEZONE() 本地/本地日期和时间: 02/10/2021 18:31:27.00 UTC/本地日期和时间: 02/10/2021 18:31:27.94 ``` ## 使用`$ZTIMEZONE`的本地/UTC转换方法 `%SYSTEM.Util`类的两个类方法在本地日期和时间与UTC日期和时间之间进行转换:`UTCtoLocalWithZTIMEZONE()`和`LocalWithZTIMEZONEtoUTC()`。这些方法受`$ZTIMEZONE`更改的影响。 ```java /// d ##class(PHA.TEST.SpecialVariables).ZTIMEZONE1() ClassMethod ZTIMEZONE1() { WRITE $SYSTEM.Util.UTCtoLocalWithZTIMEZONE($ZTIMESTAMP),! WRITE $HOROLOG,! WRITE $SYSTEM.Util.LocalWithZTIMEZONEtoUTC($H),! WRITE $ZTIMESTAMP } ``` ```java DHC-APP>d ##class(PHA.TEST.SpecialVariables).ZTIMEZONE1() 65785,66819.613 65785,66819 65785,38019 65785,38019.614 ``` # 示例 以下示例返回当前时区: ```java /// d ##class(PHA.TEST.SpecialVariables).ZTIMEZONE2() ClassMethod ZTIMEZONE2() { SET zone=$ZTIMEZONE IF zone=0 { WRITE !,"时区是格林威治标准时间" } ELSEIF zone>0 { WRITE !,"时区是 ",zone/60," 格林威治以西" } ELSE { WRITE !,"时区是 ",(-zone)/60," 格林威治以东" } } ``` ```java DHC-APP>d ##class(PHA.TEST.SpecialVariables).ZTIMEZONE2() 时区是 8 格林威治以东 ``` 以下示例显示了设置时区可以更改日期和时间: ```java /// d ##class(PHA.TEST.SpecialVariables).ZTIMEZONE3() ClassMethod ZTIMEZONE3() { SET zonesave=$ZTIMEZONE WRITE !,"当前时区的日期: ",$ZDATE($HOROLOG) IF $ZTIMEZONE=0 { SET $ZTIMEZONE=720 } ELSEIF $ZTIMEZONE>0 { SET $ZTIMEZONE=($ZTIMEZONE-720) } ELSE { SET $ZTIMEZONE=($ZTIMEZONE+720) } WRITE !,"Date halfway around the world: ",$ZDATE($HOROLOG) WRITE !,"格林威治天文台的日期: ",$ZDATE($ZTIMESTAMP) SET $ZTIMEZONE=zonesave } ``` ```java DHC-APP> d ##class(PHA.TEST.SpecialVariables).ZTIMEZONE3() 当前时区的日期: 02/10/2021 Date halfway around the world: 02/10/2021 格林威治天文台的日期: 02/10/2021 ``` 以下示例确定本地时间是否与时区时间相同: ```java /// d ##class(PHA.TEST.SpecialVariables).ZTIMEZONE4() ClassMethod ZTIMEZONE4() { SET localnow=$HOROLOG, stamp=$ZTIMESTAMP WRITE !,"当地日期和时间: ",$ZDATETIME(localnow,1,1) SET clocksecs=$PIECE(localnow,",",2) SET stampsecs=$EXTRACT(stamp,7,11)-($ZTIMEZONE*60) IF clocksecs=stampsecs { WRITE !,"没有本地时间变量:" WRITE !,"本地时间是时区时间" } ELSE { IF clocksecs=stampsecs+3600 { WRITE !,"夏令时变体:" WRITE !,"从时区时间偏移1小时的本地时间" } ELSE { WRITE !,"当地时间和时区时间为" WRITE !,(clocksecs-stampsecs)/60," 分钟不同" } } QUIT } ``` ```java DHC-APP>d ##class(PHA.TEST.SpecialVariables).ZTIMEZONE4() 当地日期和时间: 02/10/2021 18:40:21 没有本地时间变量: 本地时间是时区时间 ```
文章
姚 鑫 · 六月 16, 2021

第九章 将XML导入到对象中

# 第九章 将XML导入到对象中 本章介绍如何使用%XML.Reader将XML文档导入到 IRIS对象中。 **注意:使用的任何XML文档的XML声明都应该指明该文档的字符编码,并且文档应该按照声明的方式进行编码。如果未声明字符编码, IRIS将使用前面的“输入和输出的字符编码”中描述的默认值。如果这些默认值不正确,请修改XML声明,使其指定实际使用的字符集。** 还可以使用`%XML.Reader`读取任意XML文档并返回DOM(文档对象模型)。 # 创建XML读取器概述 IRIS提供了一些工具,用于读取XML文档并创建与该文档的元素相对应的启用XML的 IRIS对象的一个或多个实例。基本要求如下: - 该对象的类定义必须扩展`%XML.Adaptor`。除了少数例外,该对象引用的类还必须扩展`%XML.Adaptor`。 提示:如果相应的XML模式可用,可以使用它来生成类(以及任何支持的类)。 - 要导入XML文档,创建`%XML.Reader`的实例,然后调用该实例的方法。这些方法指定XML源文档,将XML元素与启用XML的类相关联,并将源中的元素读取到对象中。 `%XML.Reader`使用类中的`%XML.Adaptor`提供的方法执行以下操作: - 它使用InterSystems IRIS SAX接口解析和验证传入的XML文档。验证可以包括DTD或XML架构验证。 - 它确定是否有任何启用了XML的对象与XML文档中包含的元素相关,并在读取文档时创建这些对象的内存中实例。 **请注意,`%XML.Reader`创建的对象实例不存储在数据库中;它们是内存中的对象。如果要将对象存储在数据库中,则必须调用%Save()方法(对于持久对象),或者将相关属性值复制到持久对象并保存它。应用程序还必须决定何时插入新数据和何时更新现有数据;`%XML.Reader`无法进行此区分。** 下面的终端会话显示了一个简单的示例。在这里,我们将XML文件读入一个新对象,检查该对象,然后保存该对象: ```java /// w ##class(PHA.TEST.Xml).ReadXml() ClassMethod ReadXml() { Set reader = ##class(%XML.Reader).%New() Set file="E:\temp\samplePerson.xml" Set status = reader.OpenFile(file) if $$$ISERR(status) { do $System.Status.DisplayError(status) quit } Write status,! Do reader.Correlate("Person","Sample.Person") Do reader.Next(.object,.status) if $$$ISERR(status) { do $System.Status.DisplayError(status) quit } Write object.Name,! Do object.%Save() q "" } ``` 此示例使用以下示例XML文件: ```java Worthington,Jeff R. 1976-11-03 Elm City 27820 Best,Nora A. Weaver,Dennis T. ``` # 创建导入方法 ## 总体方法结构 方法应按以下顺序执行以下部分或全部操作: 1. 创建`%XML.Reader`的实例。 2. 也可以指定此实例的`Format`属性,以指定要导入的文件的格式。 默认情况下,InterSystems IRIS假定XML文件为文字格式。如果文件是SOAP编码格式,则必须指明这一点,以便可以正确读取该文件。 3. 可以选择设置此实例的其他属性。 4. 请使用`%XML.Reader`的以下方法之一 - `OpenFile()` -打开文件。 - `OpenStream()`-打开一个流。 - `OpenString()` -打开一个字符串。 - `OpenURL()` -打开一个URL。 在每种情况下,可以选择性地为该方法指定第二个参数,以覆盖`Format`属性的值。 5. 将这个文件中的一个或多个XML元素名与具有相应结构的支持InterSystems IRIS XML的类关联起来。 有两种方法可以做到这一点: - 使用`Correlate()`方法,它有以下签名: ``` method Correlate(element As %String, class As %String, namespace As %String) ``` 其中`element`是XML元素名,class是InterSystems IRIS类名(带包),`namespace`是可选的名称空间`URI`。 如果使用`namespace`参数,则匹配仅限于指定命名空间中的指定元素名。 如果将命名空间参数指定为"",则与`Next()`方法中给出的默认命名空间相匹配。 如果不使用`namespace`参数,则只使用元素名进行匹配。 提示:可以反复调用`Correlate()`方法来关联多个元素。 - 使用`CorrelateRoot()`方法,它有以下签名: ``` method CorrelateRoot(class As %String) ``` 其中class是InterSystems IRIS类名(带包)。此方法指定XML文档的根元素与指定的类相关。 6. 按如下方式实例化类实例: 如果使用`Correlate()`,则遍历文件中的相关元素,一次循环一个元素。在循环中,使用Next()方法,该方法具有以下签名: ``` method Next(ByRef oref As %ObjectHandle, ByRef sc As %Status, namespace As %String = "") as %Integer ``` 其中`OREF`是该方法创建的对象,`sc`是状态,`Namespace`是文件的默认名称空间。 - 如果使用`CorrelateRoot()`,请调用`next()`方法一次,这会导致实例化相关类。 `Next()`方法在到达文件末尾时返回0。如果在此之后再次调用`next()`,则将从文件顶部开始再次循环遍历文件中的对象。(指定的关联仍然有效。) ## 错误检查 **上一节提到的大多数方法都返回状态。应该在每个步骤之后检查状态,并在适当的情况下退出。** ## 基本导入示例 名为`test.xml`的以下XML文件: ```xml 姚 鑫 ``` 我们首先定义一个启用XML的类`MyApp.Person`,它是`Person`的对象表示: ```java Class MyApp.Person Extends (%Persistent, %XML.Adaptor) { Parameter XMLNAME = "Person"; Property Name As %String; Storage Default { %%CLASSNAME Name ^MyApp.PersonD PersonDefaultData ^MyApp.PersonD ^MyApp.PersonI ^MyApp.PersonS %Library.CacheStorage } } ``` 要将此文件导入到`MyAppPerson`类的实例中,我们可以编写以下方法: ```java /// w ##class(PHA.TEST.Xml).ImportXml() ClassMethod ImportXml() { // 创建%XML.Reader的实例 Set reader = ##class(%XML.Reader).%New() // 开始处理文件 Set status = reader.OpenFile("E:\temp\testPerson.xml") If $$$ISERR(status) {do $System.Status.DisplayError(status)} // 将类名与XML元素名相关联 Do reader.Correlate("Person","MyApp.Person") // 从XML文件读取对象 While (reader.Next(.object,.status)) { Write object.Name,! } // 如果在处理过程中发现错误,则将其显示 If $$$ISERR(status) {do $System.Status.DisplayError(status)} q "" } ``` ```java DHC-APP>w ##class(PHA.TEST.Xml).ImportXml() 姚 鑫 ``` 此方法执行几个任务: - 它使用InterSystems IRIS `SAX`接口解析输入文件。这包括根据文档的DTD或架构(如果指定)验证文档。 - `Correlate()`方法将类`MyApp`关联起来。 `MyPerson`与XML元素``; ``中的每个子元素都成为`MyPerson`的一个属性。 - 它从输入文件中读取每个``元素,直到没有剩余元素。 - 最后,如果循环因错误而终止,则该错误将显示在当前输出设备上。 如上所述,此示例不将对象存储到数据库。因为`MyPerson`是持久对象,所以可以通过在`While`循环中添加以下行来完成此操作: ```java /// w ##class(PHA.TEST.Xml).ImportXml() ClassMethod ImportXml() { // 创建%XML.Reader的实例 Set reader = ##class(%XML.Reader).%New() // 开始处理文件 Set status = reader.OpenFile("E:\temp\testPerson.xml") If $$$ISERR(status) {do $System.Status.DisplayError(status)} // 将类名与XML元素名相关联 Do reader.Correlate("Person","MyApp.Person") // 从XML文件读取对象 While (reader.Next(.object,.status)) { Write object.Name,! Set savestatus = object.%Save() If $$$ISERR(savestatus) {do $System.Status.DisplayError(savestatus)} } // 如果在处理过程中发现错误,则将其显示 If $$$ISERR(status) {do $System.Status.DisplayError(status)} q "" } ``` ![image](6AAE53278D13494E959BC90CC739F33C) ## 通过HTTPS URL访问文档 对于`OpenURL()`方法,如果文档位于需要`SSL/TLS`的`URL`,请执行以下操作: 1. 使用管理门户创建包含所需连接详细信息的`SSL/TLS`配置。这是一次性的步骤。 2. 使用`%XML.Reader`时,请设置读取器实例的`SSLConfiguration`属性。对于该值,请指定在上一步中创建的SSL/TLS配置的名称。 或者,当使用`%XML.Reader`,还可以执行以下操作: 1. 创建`%Net.HttpRequest`实例。 2. 将该实例的`SSLConfiguration`属性设置为等于管理门户中创建的`SSL/TLS`配置的配置名称。 3. 使用`%Net.HttpRequest`的实例作为`OpenURL()`的第三个参数。 例如: ![image](31D8EC126E9F4C3D92C558742C3FC0B7) ```java Class YX.Config Extends (%Persistent, %XML.Adaptor) { Parameter XMLNAME = "update"; Property version As %String; Property name As %String; Property url As %String; } ``` ```java /// 请求http的xml,映射到本地类 /// w ##class(PHA.TEST.Xml).ReadXmlHttp("http://192.168.10.3/dthealth/web/csp/version.xml") ClassMethod ReadXmlHttp(url) { set reader = ##class(%XML.Reader).%New() set request = ##class(%Net.HttpRequest).%New() set request.SSLConfiguration="yx" set status = reader.OpenURL(url,,request) If $$$ISERR(status) {do $System.Status.DisplayError(status)} // 将类名与XML元素名相关联 Do reader.Correlate("update","YX.Config") While (reader.Next(.object,.status)) { Write object.version,! Write object.name,! Write object.url,! } q "" } ``` ```java DHC-APP>w ##class(PHA.TEST.Xml).ReadXmlHttp("http://192.168.10.3/dthealth/web/csp/version.xml") 27 Herb http://192.168.31.124/dthealth/web/csp/Herb.apk ``` ### 在服务器需要身份验证时访问文档 **如果服务器需要身份验证,请创建`%Net.HttpRequest`的实例,并设置该实例的用户名和密码属性。还可以如上所述使用SSL(因此还要设置`SSLConfiguration`属性)。然后使用`%Net.HttpRequest`的实例作为`OpenURL()`的第三个参数,如上例所示。**