搜索​​​​

清除过滤器
问题
kun an · 五月 27, 2021

按照官方教程Java QuickStart章节中下载的示例程序 xep方式访问不了

按照此网址的指示 https://gettingstarted.intersystems.com/language-quickstarts/java-quickstart/ 下载quickstarts-java示例代码 运行xepplaystocktsTask1模块程序提示InterSystems XEP is not supported by the specified server 请问有人知道具体原因吗我的server有什么不对吗。 使用客户端的server manager添加server没有server类型的选项,是因为我使用的cache版本目前不支持吗 不知您测试使用的具体是IRIS哪个版本,以及运行在哪个操作系统上。 还有提到的客户端使用的是哪个IRIS版本。低版本的客户端没法连上高版本的IRIS服务端,Caché客户端更加连不上IRIS的服务器。 您好 感谢解答。我使用的是IRISHealth_Community-2020.1.0.217.1-win_x64 运行在windows10上。我在官网教程上下载的示例代码,其余访问方式都运行正常就xep方式报错, 提示指定的server不支持, 不知道都有什么类型的server,哪些server可以支持 请参考下面资料检查是否符合运行需求以及相关配置是否正确:https://docs.intersystems.com/irisforhealth20201/csp/docbook/Doc.View.cls?KEY=BJAVXEP_intro#BJAVXEP_intro_config 其中的检查包括JDK版本、安装时的选项、服务%Service_CallIn是否打开以及环境变量CLASSPATH 的设置
文章
Michael Lei · 十二月 30, 2021

翻译--在ECP架构下部署多个IRIS 实例 - 例子

对于那些在某种程度上需要测试ECP的水平可扩展性(计算能力和/或用户和进程的并发性),但又懒得建立环境、配置服务器节点等的人来说,我刚刚在Open Exchange上发布了OPNEx-ECP部署的应用/示例。 这只是一个小项目,可以在GitHub上找到,供所有人使用。基本上,它可以让你在自己的笔记本上建立3个InterSystems IRIS实例作为应用服务器,1个实例作为数据服务器,通过ECP连接。 它还将启动一个LoadBalancer(使用WebGateway),作为一个独立于其他实例的节点,它将是进入你的系统的入口(通过HTTP),它将负责在应用服务器之间分配请求。 只需很少的工作,你就可以添加你的应用代码,并利用该项目在分布式ECP中测试你的应用。应用服务器预装了其他有趣的开源模块(ZPM, WebTerminal, RestForms2 y Restforms2-ui),还有一个小包OPNEx-Model,其中有一些类和一个REST服务作为例子来实现。 详细信息请访问Open Exchange或GitHub。 好了,希望这对你有帮助! 祝大家编程愉快!!
公告
Claire Zheng · 十一月 9, 2023

来投票选出适合发布公告的创意吧!

Hi 社区成员们! 我们非常兴奋地推出一系列全新的公告,展示您在创意门户中所提交的创意的实施情况。通过这个系列,我们将聚焦那些已转化为现实世界解决方案的令人赞叹的想法。 我们的社区一直是创造力、创新和协作的重要中心,这正说明了我们拥有一批非凡的人才。通过这些公告,我们为那些从奇思妙想到代码诞生而庆祝欢呼。本系列中的每个公告都将展示 InterSystems 产品概念的建议想法,并让您亲身体验代码的神奇魅力。 第一批得到实施的创意是: 创意 创意实施者 Global->JSON->Global converter @Robert Cemper Introduce the project of helpful one-liners @Evgeny Shvarov Examples to work with IRIS from Django @Dmitry Maslennikov @Heloisa Paiva 3DES support @yurimarx Marx Include support for gRPC protocol in IRIS @Guillaume Rongier Create a UI for convenient and easy transfer of projects to other system instances for fast deployment. @Sergey Mikhailenko 在下面的投票中投票选出您希望首先展示的想法。 一如既往地欢迎您在评论中提出有关公告内容的建议!
文章
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é维护工作而上面各项中未涵盖的内容。
文章
姚 鑫 · 二月 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()`的第三个参数,如上例所示。**
文章
姚 鑫 · 三月 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`(默认值)。
问题
Yufeng Li · 十二月 23, 2021

在IRIS 上怎么实现读写分离

在IRIS 上怎么实现读写分离? IRIS的镜像(Mirroring)支持多个报告类型(Reporting Asyncs)的异步成员,这些异步成员可以用于查询、报表运行、BI等多种场景。 我们现在是用前端调用rest api,这种情况下要怎么区分调用读服务器还是写服务器? 可以封装一个REST服务用于前端api调用,这个REST服务根据不同api操作和路径,在后台调用不同服务器上的REST API或SQL操作。或者也可以考虑使用InterSystems API管理器做这个事。 相关文章请参考:https://cn.community.intersystems.com/smartsearch?search=API 如果是指数据库层的读写分离,可以使用Sharding技术,利用Sharding技术中的计算结点和数据结点,搭建负载均衡+读写分离的数据库集群,参考: https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.UI.Page.cls?KEY=GSCALE_sharding#GSCALE_sharding_reference_plan_qs 如果服务器/实例资源有限,又想实现读负载与写负载的分离,那么基于@Qiao Peng指出的镜像异步成员,在API层(即应用程序层)通过业务流程来控制查询/写入操作的分发则是成本较低的方案。 请参考这个文档链接[Deploy Compute Nodes for Workload Separation and Increased Query Throughput](https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GSCALE_sharding#GSCALE_sharding_options_qs)
文章
Michael Lei · 三月 12, 2022

Linux TZ环境变量未被设置以及对Caché的影响

在最近的大规模基准测试活动中,我们看到过多的%sys CPU时间,对应用程序的扩展产生了负面影响。 问题 我们发现,由于TZ环境变量没有被设置,很多时间都花在了localtime()系统调用上。 我们创建了一个简单的测试程序来证实这一观察结果,设置了TZ与未设置TZ的时间差和所需的CPU资源都是惊人的。 我们发现,当TZ没有设置时,从localtime()继承使用stat()系统调用到/etc/local_time是成本很高。 建议 InterSystems强烈建议在任何Linux安装中,无论是x86还是Linux on Power,都要确认TZ环境变量的设置是否适当,以获得最佳性能。 更多详情请见。"man tzset"。 目前的Caché 2016.1现场测试包含了对日期和时间功能的优化,初步测试表明有很大的改进。 下面是测试新的内部函数调用的样本输出,在这两种情况下,在Power上的Linux都没有设置TZ。 在Caché 2016.1 FT之前: real 0m22.60s user 0m1.64s sys 0m20.89s 带有Caché 2016.1 FT: real 0m0.40s user 0m0.37s sys 0m0.00s 请在评论区说明你的应用程序在TZ环境变量方面的任何经验,以及Caché 2016.1现场测试在设置或不设置TZ时的影响。谢谢!
文章
Qiao Peng · 一月 24, 2021

解决SQL适配器连接到字符集为US7ASCII的Oracle数据库的中文乱码问题

在使用xDBC连接到字符集为US7ASCII的Oracle数据库时,大家可能遇到过中文的乱码问题,尤其是使用Oracle自己的xDBC驱动的时候。 字符集为US7ASCII的Oracle数据库虽然可以保存中文数据,但给客户端带来了很多麻烦,需要对获取和提交的数据进行转码。 在Ensemble/Health Connect/InterSystems IRIS 中使用SQL适配器连接到这样的Oracle数据库时,可以使用$ZCVT函数进行转码。 1. $ZCVT函数 $ZCVT函数是广泛使用的字符串转换函数,可以做大小写转换、编码转换、URL 和 URI 转换等。我们用其编码转换能力来解决字符集转码问题。 2. 获取的SQL结果集数据有中文时 这时,Oracle的驱动返回的中文数据通常是GB码,而不是Unicode或UTF码。可以通过$ZCVT函数对GB码的数据进行转码,转换为Unicode: Set tCorrectData = $ZCVT(tOriginalData,"I","GB18030")其中$ZCVT函数的第一个参数tOriginalData是获取到到结果集字段值;第二个参数“I”说明tOriginalData是输入字符串;第三个参数“GB18030”是说明输入字符串的字符集编码是GB18030。 上面的代码会将tOriginalValue按GB18030编码转换为Unicode编码,并将转换结果赋给变量tCorrectData。 3. 发送中文数据或中文查询条件时 首先,需要将本地Unicode的中文数据转码为GB码。还是使用$ZCVT函数: Set tSendingData = $ZCVT(tOriginalData,"O","GB18030") 其中$ZCVT函数的第一个参数tOriginalData是输出的含中文数据;第二个参数“O”说明要转换输出数据;第三个参数“GB18030”是说明输出时要转换为GB18030。 上面的代码会将tOriginalValue按Unicode编码转换为GB18030编码,并将转换结果赋给变量tSendingData。 做完这一步,Oracle驱动很可能依然不认识其中的GB码中文数据。这时,需要将GB码的中文数据转换成GB明码字符串,例如你要将查询条件 中文 传给Oracle,你需要传递 D6D0CEC4过去(中的GB码为D6D0,文的GB码为CEC4),然后再使用Oracle的函数UTL_RAW.CAST_TO_VARCHAR2,将GB明码字符串转为内部使用的中文数据。所以修改后代码如下: Set tSendingData = $ZCVT(tOriginalData,"O","GB18030") Set tTmpDataHex = "" //转换为GB明码 For i=1:1:$length(tSendingData) { Set tTmpDataHex = tTmpDataHex_$zhex($ASCII(tSendingData,i)) } //使用Oracle的UTL_RAW.CAST_TO_VARCHAR2的函数 Set tSQL = "update dept_dict set dept_name = UTL_RAW.CAST_TO_VARCHAR2('"_ tTmpDataHex_"') where dept_code = '1'" 这里用到了$ZHEX和$ASCII函数,将数据转换为其编码,并转为16进制值,从而得到GB明码。关于更多的Ensemble/Health Connect/InterSystems IRIS函数,可以参考文档。 自此,应该可以解决从Ensemble和Health Connect连接到字符集为US7ASCII的Oracle数据库所遇到的各种中文乱码问题了。 如果您遇到更多的问题,欢迎在社区提问。 点赞
文章
姚 鑫 · 七月 1, 2021

第二十四章 执行XSLT转换

# 第二十四章 执行XSLT转换 # 执行XSLT转换 要执行`XSLT`转换,请执行以下操作: - 如果使用的是`Xalan`处理器(对于`XSLT 1.0`),请使用`%XML.XSLT.Transformer`的以下类方法之一: - `TransformFile()`——转换给定XSLT样式表的文件。 - `TransformFileWithCompiledXSL()`——转换一个文件,给定一个已编译的XSLT样式表。 - `TransformStream()`——转换给定XSLT样式表的流。 - `TransformStreamWithCompiledXSL()`——转换一个流,给定一个已编译的XSLT样式表。 - `TransformStringWithCompiledXSL()`——转换给定已编译XSLT样式表的字符串。 - 如果使用`Saxon`处理器(用于XSLT 2.0),请使用`%XML.XSLT2.Transformer`的以下类方法之一: - `TransformFile()`——转换给定XSLT样式表的文件。 - `TransformFileWithCompiledXSL()`——转换一个文件,给定一个已编译的XSLT样式表。 - `TransformStream()`——转换给定XSLT样式表的流。 - `TransformStreamWithCompiledXSL()`——转换一个流,给定一个已编译的XSLT样式表。 这些方法具有相似的签名。这些方法的参数列表按顺序如下: - pSource—要转换的源XML。请参见此列表后面的表。 - pXSL -样式表或编译样式表。请参阅此列表后面的表格。 - pOutput -作为输出参数返回的结果XML。请参阅此列表后面的表格。 - pErrorHandler -一个可选的自定义错误处理程序。请参阅本章后面的“自定义错误处理”。如果不指定自定义错误处理程序,该方法将使用%XML.XSLT.ErrorHandler的新实例(对于两个类)。 - pParms -一个可选的InterSystems IRIS多维数组,包含要传递给样式表的参数。 - pCallbackHandler -定义`XSLT`扩展函数的可选回调处理程序。 - pResolver -一个可选的实体解析器。 8. (仅适用于`%XML.XSLT2.Transformer`)网关-`%Net.Remote.Gateway`的可选实例。如果要重用XSLT网关连接以获得更好的性能,请指定此参数; 作为参考,下表显示了这些方法的前三个参数,并进行了对比: XSLT变换方法的比较 Method | pSource (Input XML) |pXSL (Stylesheet) |pOutput(Output XML) ---|---|---|--- TransformFile() |String that gives a file name| String that gives a file name |String that gives a file name TransformFileWithCompiledXSL()| String that gives a file name |Compiled style sheet| String that gives a file name TransformStream()| Stream| Stream |Stream, returned by reference TransformStreamWithCompiledXSL()| Stream |Compiled style sheet |Stream, returned by reference TransformStringWithCompiledXSL()| String |Compiled style sheet| String that gives a file name # 示例 本节使用以下代码(但不同的输入文件)展示了几种转换: ```java Set in="c:\0test\xslt-example-input.xml" Set xsl="c:\0test\xslt-example-stylesheet.xsl" Set out="c:\0test\xslt-example-output.xml" Set tSC=##class(%XML.XSLT.Transformer).TransformFile(in,xsl,.out) Write tSC ``` ## 示例1:简单替换 在本例中,我们从以下输入XML开始: ```xml Content ``` 我们使用以下样式表: ```xml Content Replaced ``` 在这种情况下,输出文件将如下所示: ```xml Content Replaced ``` ## 示例2:内容提取 在本例中,我们从以下输入XML开始: ```xml Some text Some more text ``` 我们使用以下样式表: ```xml : ``` 在这种情况下,输出文件将如下所示: ```java 13: Some text 14: Some more text ``` ## 其他示例 InterSystems IRIS提供了以下附加示例: - 对于`XSLT 1.0`,请参阅`%XML.XSLT.Transformer`中的`Example()`、`Example2()`和其它方法。 - 对于`XSLT 2.0`,请参见`Samples`命名空间中的类`XSLT2.Examples`。
文章
王喆 👀 · 九月 24, 2022

使用Global进行数据可视化---商业智能(BI)

在医院但凡接触“数据”和“指标”的人,对以下场景应该是深有感触。同样的指标、同样的时间,有可能是同一个部门出的,最后“数据不一致”。除了“匪夷所思”,更有“深恶痛绝”。那么,如何解决这个问题?我的答案是商业智能(BI)。随着技术和市场的发展,有很多公司开始研发直接面向业务用户的敏捷BI工具,FineBI就是这样的一款BI工具。这个也是我接触的第一款国产BI。 项目的前提条件和设置 操作系统:Windows 64 IRIS产品:HealthConnect 2020 BI工具:FineBI JDK: JDK1.8 FineBI、JDK、HealthConnect、FineBI的相关安装步骤网上有很多,在此就暂时略过。要在FineBI上创建仪表板,我们需要一点数据,在此我使用的是开发过程中的一些测试数据,相关测试数据和互联互通的69个交互服务息息相关,有需要可以自己模拟的造。 将FineBI和IRIS连接 我们首先找到HealthConnect的安装文件,我们需要找到intersystems-jdbc-3.2.0.jar这样一个文件。大概在【安装目录】\InterSystems\HealthConnect\dev\java\lib\JDK18,如图所示: 将文件复制到FineBI的安装目录\webapps\webroot\WEB-INF\lib,如图所示: 这个时候我们启动FineBI 看到此说明FineBI启动成功,如果启动失败重启一下电脑或者检查以下JDK的环境变量是否配置 在浏览器上打开控制面板 点击【管理系统】--【数据连接】-【新建数据连接】-【数据连接管理】--【其他】--【其他JDBC】 填入内容 连接成功 创建仪表板 通过编写SQL的方式在FineBI中建立业务表: 按照此方式在【数据准备】-【数据列表】中建立多个业务表,如图所示: 新建仪表板 通过添加组件,选择表,选择样式 最终编辑成如图所示仪表板 总结 从上面演示的例子,我们可以看出,极短的时间我们就把FineBI连接到了IRIS的HealthConnect上,然后创建一些数据上的可视化的功能和东西。作为开发人员来说这很便捷,我们可以很快的完成一些数据展示的工作。同时如果把这些东西开放给一些精通业务但是对技术很生疏的人,就可以十分快速的把数据按照业务上需要的方式展示出来,一个部门乃至多个部分对出具的数据也有了更清晰的认识,在可视化的帮助下,那些乱起八糟的数据也开始变的更接近真实。 本文只展示了FineBI的使用,相信一些可以使用JDBC或者ODBC作为连接的BI工具都可以,比如最经典的PowerBI。
文章
姚 鑫 · 七月 27, 2023

第四章 HL7 架构和可用工具 - 查看数据结构

# 第四章 HL7 架构和可用工具 - 查看数据结构 ## 查看数据结构 当单击“数据结构”列中的名称时,`InterSystems` 会显示该数据结构中的所有字段。这是 `HL7` 数据结构页面。显示的以下列是最有用的: - 组件列列出了可用于访问段内字段的数字。 - 属性名称列列出了可用于访问段内字段的名称。 - 单击“数据结构”列中的条目可深入了解详细信息。 - 单击“代码表”列(如果有)中的条目可查看可在此字段中输入的有效代码。 当单击上面段结构页面中名为 `2.3:XCN` 的数据结构项时,将出现以下示例页面。该页面指出类别 `2.3` 数据结构 `XCN` 描述“扩展复合 `ID` 号和名称”并由 `14` 个字段组成。其中,有些是简单值,有些是数据结构,有些是代码。 有了这些信息,就可以为消息结构 `2.3:ADT_A01` 中的复杂 `PR1grp().PR1:Surgeon` 字段创建虚拟属性路径,如下所示: ``` PR1grp().PR1:Surgeon.familyname PR1grp().PR1:Surgeon.degree ``` ## 查看代码表 当单击“代码表”列中的名称时,它会列出并解释该字段的有效代码。这是 `HL7` 代码表页面。当单击上一节中显示的数据结构页面中名为 `2.3:200` 的代码表项时,将出现以下示例页面。 上面的示例示出类别`2.3`代码表`200`描述可以具有值`L`、`O`、`M`、`A`、`C`或`D`的“名称类型”。 这意味着,如果有一条 `DocType` 为 `2.3:ADT_A01` 的 `HL7` 消息,则它具有一个可选虚拟属性,路径为 `PR1grp().PR1:Anesthesiograph.nametype`,可以包含以下值之一:`L`、`O`、`M`、 `A`、`C` 或 `D`。 ## 使用自定义架构编辑器 自定义架构编辑器允许创建新的自定义 `HL7` 架构或编辑现有的自定义 `HL7` 架构。通常,自定义模式具有基本模式,它是标准模式或其他自定义模式。当 `InterSystems` 产品使用自定义架构来解析消息时,如果自定义架构中未定义消息类型、段或其他元素,它将使用基本架构中的定义。因此,只需在自定义架构中定义基本架构中不存在的元素,或者需要与基本架构中的定义不同的元素。无法编辑标准架构。 定义自定义架构的最常见原因是能够解析带有尾部 `Z` 段的 `HL7` 消息。 `InterSystems` 产品可以处理带有架构中未定义的尾部 `Z` 段的消息,但要执行以下任一操作,需要定义自定义架构: - 访问路由规则、数据转换或 `ObjectScript` 代码中尾部 `Z` 段中的字段路径。 - 验证尾部 `Z` 段。 如果`production`当前正在使用标准模式,并且需要访问数据转换或路由规则中的尾部 `Z` 段字段路径,则应执行以下操作: 1. 使用管理门户中的自定义架构编辑器创建新的 `HL7` 架构。输入自定义架构的名称并指定基本架构。请参阅创建新的自定义架构。 2. 定义可以出现在消息中的 `Z` 段。如果 `Z` 段与基础架构中的现有段具有相似的字段,可以从基础复制定义,然后根据需要进行修改。否则,可以创建一个新段。可以添加字段、删除字段或更改字段的顺序。请参阅定义新段。 3. 对于包含尾随 `Z` 段的每个消息类型,在从基础架构复制的自定义架构中创建消息类型和结构类型。将 `Z` 段添加到结构类型的末尾。请参阅定义新消息类型和结构类型 4. 修改`production` 中的业务服务以使用新的自定义架构而不是基本架构。 5. **通过向`production`的业务服务提供带有尾部 `Z` 段的新消息来测试`production`。如果在消息查看器中查看消息,则 `Z` 段(如果它们在架构中定义)将显示为蓝色。无法识别的段显示为黑色。**
文章
Michael Lei · 五月 8, 2021

将 Python JDBC 连接到 IRIS 数据库 - 快速笔记

关键字:Python,JDBC,SQL,IRIS,Jupyter Notebook,Pandas,Numpy ,机器学习  ## 1. 目的 这是一个用于演示的 5 分钟快速笔记,通过 Jupyter Notebook 中的 Python 3 调用 IRIS JDBC 驱动程序,以经由 SQL 语法从 IRIS 数据库实例读取数据和向 IRIS 数据库实例写入数据。  去年,我发表了关于[将 Python 绑定到 Cache 数据库](https://community.intersystems.com/post/deep-learning-demo-kit-python3-binding-healthshare-part-i)的简要笔记(第 4.7 节)。 如何使用 Python 挂入 IRIS 数据库以将其数据读入 Pandas 数据框和 NumPy 数组进行常规分析,然后再将一些经过预处理或标准化的数据写回 IRIS 中,准备进一步用于 ML/DL 管道,现在可能是时候回顾一些选项和讨论了。 一些立即浮现的快速**选项**: 1.    **ODBC**:Python 3 和原生 SQL 的 PyODBC? 2.    **JDBC**:Pyhton 3 和原生 SQL 的 JayDeBeApi? 3.    **Spark**:PySpark 和 SQL? 4.    **Python Native API for IRIS**:超越先前的 Python Binding for Cache? 5.   ** IPtyhon Magic SQL %%sql**?  [它](https://github.com/catherinedevlin/ipython-sql)可以支持 IRIS 了吗?  这里有漏掉其他选项吗?  我有兴趣尝试任何选项。  ## 2. 范围  我们是不是应该从普通的 JDBC 方法开始? 下一个快速笔记将总结 ODBC、Spark 和 Python Native API。  ### 范围内: 此快速演示涉及以下常见组件: Anaconda Jupyter Notebook  Python 3 JayDeBeApi JPyPe Pandas NumPy 一个 IRIS 2019.x 实例 ###  范围外: 本快速笔记不会涉及以下内容,但它们也很重要,可以使用特定的站点解决方案、部署和服务单独解决:  安全端到端。 非功能性能等。 问题排查和支持。 许可。    ## 3. 演示 ### 3.1 运行 IRIS 实例: 我只运行了一个 IRIS 2019.4 容器,作为“远程”数据库服务器。 您可以使用任何您有权利访问的 IRIS 实例。 zhongli@UKM5530ZHONGLI MINGW64 /c/Program Files/Docker Toolbox$ docker psCONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                PORTS                                              NAMESd86be69a03ab        quickml-demo        "/iris-main"        3 days ago          Up 3 days (healthy)   0.0.0.0:9091->51773/tcp, 0.0.0.0:9092->52773/tcp   quickml ### 3.2 Anaconda 和 Jupyter Notebook:  我们将在笔记本电脑中重用相同的设置方法,[这里](https://community.intersystems.com/post/deep-learning-demo-kit-python3-binding-healthshare-part-i)对应 Anaconda(第 4.1 节),[这里](https://community.intersystems.com/post/run-deep-learning-demo-python3-binding-healthshare-part-ii)对应 Jupyter Notebook(第 4 节)。  Python 3.x 在这一步安装。 ### 3.3 安装 JayDeBeApi 和 JPyPe: 启动 JupyterNotebook,然后在其单元格中运行以下内容设置 Python-to-JDBC/Java 桥:     !conda install --yes -c conda-forge jaydebeapi JayDeBeApi 在撰写本文时(2020 年 1 月)使用 JPype 0.7,该版本由于一个已知错误无法运行,必须降级为 0.6.3 !conda install --yes -c conda-forge JPype1=0.6.3 --force-reinstall ### 3.4 通过 JDBC 连接到 IRIS 数据库  这里有一个正式的[使用 JDBC 连接到 IRIS 的文档](https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=AFL_jdbc)。  对于通过 JDBC 执行 Python SQL,我以下面的代码为例。 它连接到此 IRIS 实例的“USER”命名空间内的数据表“`DataMining.IrisDataset`”。  ### 1. Set environment variables, if necessary<br>#import os<br>#os.environ['JAVA_HOME']='C:\Progra~1\Java\jdk1.8.0_241'<br>#os.environ['CLASSPATH'] = 'C:\interSystems\IRIS20194\dev\java\lib\JDK18\intersystems-jdbc-3.0.0.jar'<br>#os.environ['HADOOP_HOME']='C:\hadoop\bin'  #winutil binary must be in Hadoop's Home ### 2. Get jdbc connection and cursor<br><strong>import jaydebeapi<br>url = "jdbc:IRIS://192.168.99.101:9091/USER"<br>driver = 'com.intersystems.jdbc.IRISDriver'<br>user = "SUPERUSER"<br>password = "SYS"</strong><br>#libx = "C:/InterSystems/IRIS20194/dev/java/lib/JDK18"<br><strong>jarfile = "C:/InterSystems/IRIS20194/dev/java/lib/JDK18/intersystems-jdbc-3.0.0.jar"</strong> conn = jaydebeapi.connect(driver, url, [user, password], jarfile)<br>curs = conn.cursor() ### 3. specify the source data table<br><strong>dataTable = 'DataMining.IrisDataset'</strong>  ### 4. Get the result and display<br><strong>curs.execute("select TOP 20 * from %s" % dataTable)<br>result = curs.fetchall()<br>print("Total records: " + str(len(result)))<br>for i in range(len(result)):<br>    print(result[i])</strong> ### 5. CLose and clean - I keep them open for next accesses.<br><strong>#curs.close()<br>#conn.close()</strong>   Total records: 150 (1, 1.4, 0.2, 5.1, 3.5, 'Iris-setosa') (2, 1.4, 0.2, 4.9, 3.0, 'Iris-setosa') (3, 1.3, 0.2, 4.7, 3.2, 'Iris-setosa') ... ... (49, 1.5, 0.2, 5.3, 3.7, 'Iris-setosa') (50, 1.4, 0.2, 5.0, 3.3, 'Iris-setosa') (51, 4.7, 1.4, 7.0, 3.2, 'Iris-versicolor') ... ... (145, 5.7, 2.5, 6.7, 3.3, 'Iris-virginica') ... ... (148, 5.2, 2.0, 6.5, 3.0, 'Iris-virginica') (149, 5.4, 2.3, 6.2, 3.4, 'Iris-virginica') (150, 5.1, 1.8, 5.9, 3.0, 'Iris-virginica')   测试表明 JDBC 上的 Python 可以正常运行。 以下只是常规 ML 管道的一些常规数据分析和预处理,由于我们可能会在后续的演示和比较中反复涉及,因此为方便起见在这里附上。  ### 3.5 将 SQL 结果转换为 Pandas DataFrame,再转换为 NumPy 数组 如果还没有安装 Pandas 和 NumPy 软件包,可以通过 Conda 安装,类似于上面 3.3 节。 然后运行以下示例: ### transform SQL results "sqlData"to Pandas dataframe "df", then further to NumPy array "arrayN" for further ML pipelines import pandas as pdsqlData = "SELECT * from DataMining.IrisDataset"df= pd.io.sql.read_sql(sqlData, conn)df = df.drop('ID', 1)df = df[['SepalLength', 'SepalWidth', 'PetalLength', 'PetalWidth', 'Species']] # set the labels to 0, 1, 2, for NumPy matrixdf.replace('Iris-setosa', 0, inplace=True)df.replace('Iris-versicolor', 1, inplace=True)df.replace('Iris-virginica', 2, inplace=True) # turn dataframe into Numpy arrayarrayN = df.to_numpy() ### 6. CLose and clean - if connection is not needed anymore?#curs.close()#conn.close() 我们例行查看一下当前数据: df.head(5) df.describe() 现在,我们得到了一个 DataFrame,以及一个来自源数据表的标准化 NumPy 数组。   当然,我们在这里可以尝试各种常规分析,一个 ML 人员会按照下述步骤开始,在 Python 中替换 R([链接](http://www.lac.inpe.br/~rafael.santos/Docs/CAP394/WholeStory-Iris.html))。 数据源引自此处   ### 3.6 拆分数据并通过 SQL 写回 IRIS 数据库: 当然,我们可以像往常一样将数据拆分为训练集和验证集或测试集,然后将它们写回临时数据库表,实现 IRIS 一些即将推出的精彩 ML 功能: import numpy as np from matplotlib import pyplotfrom sklearn.model_selection import train_test_split # keep e.g. 20% = 30 rows as test data; trained on another e.g. 80% = 120 rowsX = arrayN[:,0:4]y = arrayN[:,4]X_train, X_validation, Y_train, Y_validation = train_test_split(X, y, test_size=0.20, random_state=1, shuffle=True) # make 80% of random rows into a Train setlabels1 = np.reshape(Y_train,(120,1))train = np.concatenate([X_train, labels1],axis=-1) # make 20% of left rows into Test setlTest1 = np.reshape(Y_validation,(30,1))test = np.concatenate([X_validation, lTest1],axis=-1) # write the train data set into a Pandas framedfTrain = pd.DataFrame({'SepalLength':train[:, 0], 'SepalWidth':train[:, 1], 'PetalLength':train[:, 2], 'PetalWidth':train[:, 3], 'Species':train[:, 4]})dfTrain['Species'].replace(0, 'Iris-setosa', inplace=True)dfTrain['Species'].replace(1, 'Iris-versicolor', inplace=True)dfTrain['Species'].replace(2, 'Iris-virginica', inplace=True) # write the test data into another Pandas framedfTest = pd.DataFrame({'SepalLength':test[:, 0], 'SepalWidth':test[:, 1], 'PetalLength':test[:, 2], 'PetalWidth':test[:, 3], 'Species':test[:, 4]})dfTest['Species'].replace(0, 'Iris-setosa', inplace=True)dfTest['Species'].replace(1, 'Iris-versicolor', inplace=True)dfTest['Species'].replace(2, 'Iris-virginica', inplace=True) ### 3. specify temp table names#dataTable = 'DataMining.IrisDataset'dtTrain = 'TRAIN02'dtTest = "TEST02" ### 4. Create 2 temporary tables - you can try drop tables then re-create them every timecurs.execute("Create Table %s (%s DOUBLE, %s DOUBLE, %s DOUBLE, %s DOUBLE, %s VARCHAR(100))" % (dtTrain, dfTrain.columns[0], dfTrain.columns[1], dfTrain.columns[2], dfTrain.columns[3], dfTrain.columns[4]))curs.execute("Create Table %s (%s DOUBLE, %s DOUBLE, %s DOUBLE, %s DOUBLE, %s VARCHAR(100))" % (dtTest, dfTest.columns[0], dfTest.columns[1], dfTest.columns[2], dfTest.columns[3], dfTest.columns[4])) ### 5. write Train set and Test set into the tales. You can try to delete old record then insert everytime. curs.fast_executemany = Truecurs.executemany( "INSERT INTO %s (SepalLength, SepalWidth, PetalLength, PetalWidth, Species) VALUES (?, ?, ?, ? ,?)" % dtTrain,     list(dfTrain.itertuples(index=False, name=None)) )curs.executemany( "INSERT INTO %s (SepalLength, SepalWidth, PetalLength, PetalWidth, Species) VALUES (?, ?, ?, ? ,?)" % dtTest,     list(dfTest.itertuples(index=False, name=None)) ) ### 6. CLose and clean - if connection is not needed anymore?#curs.close()#conn.close() 现在,如果切换到 IRIS 管理控制台或终端 SQL 控制台,应该看到已创建 2 个临时表:120 行的 TRAIN02 和 30 行的 TEST02。 那么本篇快速笔记到这里就结束了。 ## 4. 注意事项 * 以上内容可能会被更改或完善。  ## 5. 未来计划 我们将使用 IRIS 的 PyODBC、PySPark 和 Python Native API 替换第 3.3 和 3.4 节。除非有人愿意帮忙编写一篇快速笔记,我也将对此不胜感激。