#InterSystems IRIS for Health

0 关注者 · 862 帖子

InterSystems IRIS for Health™ 是全球第一个也是唯一一个专门为医疗应用程序的快速开发而设计的数据平台,用于管理全世界最重要的数据。它包括强大的开箱即用的功能:事务处理和分析、可扩展的医疗保健数据模型、基于 FHIR 的解决方案开发、对医疗保健互操作性标准的支持等等。所有这些将使开发者能够快速实现价值并构建具有突破性的应用程序。了解更多信息

文章 姚 鑫 · 八月 29, 2023 4m read

第十三章 ObjectScript - 特殊变量

特殊变量

一些特殊变量提供有关代码运行环境的信息。其中包括以下内容:

  • $HOROLOG,包含操作系统给出的当前进程的日期和时间。请参阅日期和时间值。
  • $USERNAME$ROLES,包含有关当前使用的用户名以及该用户所属角色的信息。
 write "You are logged in as: ", $USERNAME, !, "And you belong to these roles: ",$ROLES
  • $ZVERSION,其中包含标识当前运行的 IRIS 版本的字符串。

其他包括 $JOB$ZTIMEZONE$IO$ZDEVICE

其他变量提供有关代码处理状态的信息。其中包括 $STACK$TLEVEL$NAMESPACE$ZERROR

$SYSTEM 特殊变量

特殊变量 $SYSTEM 提供对大量实用方法的轻松访问。

特殊变量 $SYSTEM%SYSTEM 包的别名,其中包含提供可满足各种需求的类方法的类。引用 %SYSTEM 中方法的惯用方法是构建使用 $SYSTEM 变量的引用。例如,以下命令在类中执行 %SYSTEM.OBJ 中的 SetFlags() 方法:

 DO $SYSTEM.OBJ.SetFlags("ck")

由于特殊变量的名称不区分大小写(与类及其成员的名称不同),因此以下命令都是等效的:

 DO ##class(%SYSTEM.OBJ).SetFlags("ck")
 DO $System.OBJ.SetFlags("ck")
 DO $SYSTEM.OBJ.SetFlags("ck")
 DO $system.OBJ.SetFlags("ck")

这些类都提供了 Help() 方法,该方法可以打印类中可用方法的列表。例如:

TESTNAMESPACE>d $system.OBJ.Help()
'Do $system.OBJ.Help(method)' will display a full description of an individual method.
 
Methods of the class: %SYSTEM.OBJ
 
CloseObjects()
     Deprecated function, to close objects let them go out of scope.
 
Compile(classes,qspec,&errorlog,recurse)
     Compile a class.
 
CompileAll(qspec,&errorlog)
     Compile all classes within this namespace
....

还可以使用方法名称作为 Help() 的参数。例如:

TESTNAMESPACE>d $system.OBJ.Help("Compile")
Description of the method:class Compile:%SYSTEM.OBJ
 
Compile(classes:%String="",qspec:%String="",&errorlog:%String,recurse:%Boolean=0)
Compile a class.
<p>Compiles the class <var>classes</var>, which can be a single class, a comma separated list, 
a subscripted array of class names, or include wild cards. If <var>recurse</var> is true then 
do not output the intial 'compiling' message or the compile report as this is being called inside 
another compile loop.<br>
<var>qspec</var> is a list of flags or qualifiers which can be displayed with 
'Do $system.OBJ.ShowQualifiers()'
and 'Do $system.OBJ.ShowFlags()

锁定和并发控制

任何多进程系统的一个重要特征是并发控制,能够防止不同进程同时更改数据的特定元素,从而导致损坏。因此,ObjectScript 提供了一个锁管理系统。

基础

基本的锁定机制是 LOCK 命令。该命令的目的是延迟一个进程中的活动,直到另一进程发出可以继续进行的信号为止。

重要的是要理解锁本身并不会阻止其他进程修改关联的数据;它会阻止其他进程修改相关数据。也就是说, IRIS 不强制执行单方面锁定。锁定仅按照约定工作:它要求相互竞争的进程都使用相同的锁名称实现锁定。

下面描述一个常见的锁场景:进程A发出LOCK命令, IRIS尝试创建锁。如果进程 B 已经拥有具有给定锁名称的锁,则进程 A 将暂停。具体来说,进程A中的LOCK命令没有返回,并且不能执行连续的代码行。当进程B释放锁时,进程A中的LOCK命令最终返回并继续执行。

在许多情况下,系统会在内部自动使用 LOCK 命令,例如当使用持久对象或使用某些 SQL 命令时。

锁表

IRIS 维护一个系统范围的内存表,记录所有当前锁以及拥有这些锁的进程。该表(锁表)可通过管理门户访问,可以在其中查看锁并(在极少数情况下,如果需要)删除它们。

锁表不能超过可以指定的固定大小。有因此,锁表可能会被填满,从而无法进行进一步的锁定。填充锁通常不被认为是应用程序错误; IRIS 还提供了一个锁队列,进程会等待,直到有空间将其锁添加到锁表中。

但是,如果两个进程各自对已被另一个进程锁定的变量断言增量锁,则这种情况称为死锁,并且被视为应用程序编程错误。

0
0 95
文章 姚 鑫 · 八月 28, 2023 3m read

第十二章 ObjectScript - 命令

命令

本节概述了在 ObjectScript 常用命令。其中包括与其他语言中的命令相似的命令,以及其他语言中没有等效项的其他命令。

命令名称不区分大小写,尽管按照惯例它们在运行文本中显示为全大写。

熟悉的命令

ObjectScript 提供命令来执行熟悉的任务,如下所示:

  • 要定义变量,请使用 SET(如前所示)。

  • 要删除变量,请使用 KILL,如前所示。

  • 要控制逻辑流程,请使用以下命令:

    • IFELSEIFELSE 一起工作
    • FOR
    • WHILE,可以单独使用
    • DOWHILE 可以一起使用
    • QUIT,也可以返回一个值

    还有其他用于流量控制的命令,但使用频率较低。

  • 要捕获错误,请使用 TRYCATCH,它们一起工作。

  • 要写入值,请使用 WRITE。这会将值写入当前设备(例如,终端或文件)。

    在不带参数的情况下使用该命令会写入所有局部变量的值。

    此命令可以使用一小组格式控制代码字符来定位输出。在现有代码中,可能会看到感叹号,它开始一个新行。例如:

     write "hello world",!,"another line"
    
  • 要从当前设备(例如终端)读取值,请使用 READ

  • 要使用主设备以外的设备,请使用以下命令:

    • OPEN 使设备可供使用。
    • USE 指定一个打开的设备作为当前设备,供 WRITEREAD 使用。
    • CLOSE 使设备不再可用。
  • 要控制并发,请使用 LOCK。请注意, IRIS 锁管理系统与其他语言的类似系统不同。回顾一下它是如何运作的很重要。

如果多个进程可能访问同一变量或其他项,则可以使用此命令。

  • 要管理事务,请使用 TSTARTTCOMMITTROLLBACK 和相关命令。
  • 对于调试,请使用 ZBREAK 和相关命令。
  • 要暂停执行,请使用 HANG

用于多维数组的命令

ObjectScript 中,可以通过以下方式使用多维数组:

  • 要定义节点,请使用 SET 命令。
  • 要删除单个节点或所有节点,请使用 KILL 命令。

例如,以下命令删除整个多维数组:

 kill myarray

相反,以下代码删除节点 myarray("2 Dec 2010") 及其所有子节点:

 kill myarray("2 Dec 2010")
  • 要删除globalglobal节点但不删除其后代子节点,请使用 ZKILL
  • 要迭代多维数组的所有节点并将其全部写入,请使用 ZWRITE。这在terminal中尤其方便。以下示例终端会话显示了输出的样子:
TESTNAMESPACE>ZWRITE ^myarray
^myarray(1)="value A"
^myarray(2)="value B"
^myarray(3)="value C"

此示例使用global变量而不是局部变量,但请记住两者都可以是多维数组。

  • 要将一组节点从一个多维数组复制到另一个多维数组中,并尽可能保留目标中的现有节点,请使用 MERGE。例如,以下命令将整个内存数组 (sourcearray) 复制到新的Global (^mytestglobal) 中:
 MERGE ^mytestglobal=sourcearray

这是在调试代码时检查正在使用的数组内容的有用方法。

0
0 96
文章 姚 鑫 · 八月 27, 2023 1m read

第十一章 ObjectScript - 操作符

操作符

ObjectScript 中的运算符优先级严格是从左到右;在表达式中,运算按照它们出现的顺序执行。可以在表达式中使用显式括号来强制某些操作先于其他操作执行。

通常,即使并不严格需要括号,也会使用括号。很有用,因为它使代码的意图更加清晰。

Familiar Operators

ObjectScript 为常见活动提供以下运算符:

  • 数学运算符:加法 (+)、减法 (-)、除法 (/)、乘法 (*)、整数除法 (\)、模数 (#) 和求幂 (**)
  • 一元运算符:正 (+) 和负 (-)
  • 字符串连接运算符 (_)
  • 逻辑比较运算符:等于(=)、大于(>)、大于等于(>=)、小于(<)、小于等于(<=)
  • 逻辑补码运算符 (')

可以在任何逻辑值之前以及逻辑比较运算符之前使用它。

  • 组合逻辑值的运算符:AND (&&)、OR (||)

请注意,ObjectScript 还支持其中每种形式的较旧的、效率较低的形式:&&& 运算符的一种形式,而 ! || 的一种形式操作员。可能会在现有代码中看到这些旧的形式。

Unfamiliar Operators

ObjectScript 还包括某些语言中没有等效项的运算符。最重要的如下:

  • 模式匹配运算符 (?) 测试其左操作数中的字符是否使用其右操作数中的模式。可以指定模式出现的次数、指定替代模式、指定模式嵌套等等。

例如,如果字符串 (testthis) 的格式为美国社会保障号,则以下代码将写入值 1 (true),否则写入 0

 Set testthis="333-99-0000"
 Write testthis ?3N1"-"2N1"-"4N

这是确保输入数据有效性的重要工具,可以在类属性的定义中使用它。

  • 二进制包含运算符 ([) 返回 1(真)或 0(假),具体取决于右操作数中的字符序列是否是左操作数的子字符串。例如:
 Set L="Steam Locomotive",S="Steam"
 Write L[S
  • 二进制跟随运算符 (]) 测试左操作数中的字符是否按 ASCII 整理顺序位于右操作数中的字符之后。
  • 运算符 (]]) 之后的二进制排序测试左操作数是否按数字下标排序顺序排列在右操作数之后。
  • 间接运算符 (@) 允许对命令参数、变量名、下标列表或模式的部分或全部执行动态运行时替换。 IRIS 在执行相关命令之前执行替换。
0
0 83
文章 姚 鑫 · 八月 26, 2023 3m read

第十章 ObjectScript - 按值或按引用传递变量

按值或按引用传递变量

调用方法时,可以通过值或引用将变量值传递给该方法。在大多数情况下,这些变量是没有下标的局部变量,因此本节首先讨论这些变量。

与其他编程语言一样, IRIS 具有一个存储位置,其中包含每个局部变量的值。变量的名称充当内存位置的地址。

当将没有下标的局部变量传递给方法时,可以按值传递该变量。这意味着系统会复制该值,从而使原始值不受影响。要传递内存地址,请在参数列表中紧邻变量名称之前放置一个句点。

为了演示这一点,请考虑名为 Test.Parameters 的类中的以下方法:

ClassMethod Square(input As %Integer) As %Integer
{
    set answer=input*input
    set input=input + 10
    return answer
}

假设定义一个变量并将其按值传递给此方法:

TESTNAMESPACE>set myVariable = 5
 
TESTNAMESPACE>write ##class(Test.Parameters).Square(myVariable)
25
TESTNAMESPACE>write myVariable
5

相反,假设通过引用传递变量:

TESTNAMESPACE>set myVariable = 5
 
TESTNAMESPACE>write ##class(Test.Parameters).Square(.myVariable)
25
TESTNAMESPACE>write myVariable
15

考虑以下方法,该方法写入它收到的参数的内容:

ClassMethod WriteContents(input As %String)
{
    zwrite input
}

现在,假设有一个包含三个节点的数组:

TESTNAMESPACE>zwrite myArray
myArray="Hello"
myArray(1)="My"
myArray(2)="Friend"

如果按值将数组传递给方法,则仅传递顶级节点:

TESTNAMESPACE>do ##class(Test.Parameters).WriteContents(myArray)
input="Hello"

如果通过引用将数组传递给方法,则将传递整个数组:

TESTNAMESPACE>do ##class(Test.Parameters).WriteContents(.myArray)
input="Hello"
input(1)="My"
input(2)="Friend"

可以将Global的单个节点的值传递给方法:

TESTNAMESPACE>zwrite ^myGlobal
^myGlobal="Start"
^myGlobal(1)="Your"
^myGlobal(2)="Engines"
TESTNAMESPACE>do ##class(Test.Parameters).WriteContents(^myGlobal)
input="Start"

尝试通过引用将Global传递给方法会导致语法错误:

TESTNAMESPACE>do ##class(Test.Parameters).WriteContents(.^myGlobal)
^
<SYNTAX>

下表总结了所有可能性:

变量种类按值传递通过引用传递
没有下标的局部变量传递这些变量的标准方式允许
带下标的局部(数组)传递单个节点的值传递这些变量的标准方式
带或不带下标的Global全局变量传递单个节点的值不能以这种方式传递(全局数据不在内存中)
对象引用 (OREF)*传递这些变量的标准方式允许

* 如果有一个代表对象的变量,则可以通过对象引用 (OREF) 来引用该对象。当将 OREF 作为参数传递时,通常按值传递它。但是,由于 OREF 是指向对象的指针,因此实际上是通过引用传递对象。更改方法内对象的属性值会更改实际对象,而不是对象的副本。允许通过引用传递 OREF,并且如果想要更改 OREF 以指向不同的对象,则可以使用该方法。这不是常见用法。

0
0 93
文章 Michael Lei · 八月 26, 2023 3m read

今年两会期间,有多名两会委员联名提出了《关于建设全国统一医院电子病历系统的提案》,国家卫健委相关部门也马上给予回应,称正在研究建立全国统一的电子健康档案、电子病历。结合数字中国的主要目标之一,让数据多跑腿,群众少走路,在这一背景下,从患者端开始,建立全国统一的电子病历APP已经变得迫切而重要。这不仅有助于提高医疗服务的效率和质量,还能够让患者更好地参与到医疗决策中,实现信息的共享和整合。

电子病历与患者共享的必要性和重要性

  1. 信息共享与医疗协同: 通过建立患者全国统一的电子病历系统,医疗机构之间可以更加方便地共享患者的健康信息。这对于多学科合作诊疗、转诊和患者就诊历史的追溯具有重要意义,可以避免重复检查和繁琐的病历复印过程,提高医疗协同效率。
  2. 患者参与和知情权的加强: 电子病历使患者能够更直接地了解自己的健康状况和诊疗过程。患者可以随时访问自己的电子病历,了解诊断结果、治疗方案和用药情况,从而更好地参与医疗决策,增强自己的知情权。
  3. 紧急情况下的救治效率提升: 在紧急情况下,如意外事故或突发疾病,医护人员可以通过电子病历迅速获取患者的基本健康信息,有助于快速判断病情,做出及时救治决策。

实现方案

0
0 164
文章 姚 鑫 · 八月 25, 2023 2m read

第九章 ObjectScript - 多维数组

多维数组

ObjectScript 中,任何变量都可以是多维数组(也称为数组)。多维数组通常用于保存一组以某种方式相关的值。 ObjectScript 提供的命令和函数可以方便、快速地访问值。

可能会也可能不会直接使用多维数组,具体取决于使用的系统类和自己的偏好。当需要一个用于存储相关值集的容器时,IRIS 提供了一种基于类的替代方案。请参阅集合类。

Basics

多维数组由任意数量的节点组成,由下标定义。以下示例设置数组的几个节点,然后打印数组的内容:

 set myarray(1)="value A"
 set myarray(2)="value B"
 set myarray(3)="value C"
 zwrite myarray

此示例显示了一个典型的数组。

  • 该数组有一个下标。在这种情况下,下标是整数 123
  • 不需要提前声明数组的结构。
  • myarray 是数组本身的名称。
  • ObjectScript 提供可作用于整个数组或特定节点的命令和函数。例如:
 kill myarray

还可以KILL特定节点及其子节点。

  • 以下变体设置名为 ^myglobalGlobal数组的几个下标;也就是说,这些值被写入磁盘:
 set ^myglobal(1)="value A"
 set ^myglobal(2)="value B"
 set ^myglobal(3)="value C"
  • global引用的可能长度是有限制的。此限制会影响global名称的长度以及任何下标的长度和数量。如果超出限制,会收到 <SUBSCRIPT> 错误。请参阅global引用的最大长度。
  • 节点值的长度必须小于字符串长度限制。

多维数组为每个定义的节点保留一个存储位置,仅此而已。对于global,它使用的所有磁盘空间都是动态分配的。

结构变化

前面的示例显示了数组的常见形式。请注意以下可能的变化:

可以有任意数量的下标。例如:

 Set myarray(1,1,1)="grandchild of value A"

下标可以是字符串。以下内容有效:

 set myarray("notes to self","2 Dec 2010")="hello world"

使用注意事项

对于学习 ObjectScript 的人来说,一个常见的错误是混淆global和数组。重要的是要记住,任何变量要么是局部变量,要么是Global全局变量,并且可能有也可能没有下标。下表显示了可能性:

Kind of VariableExample and Notes
不带下标的局部变量Set MyVar=10 像这样的变量很常见。看到的大多数变量可能都是这样的。
带下标的局部变量Set MyVar(1)="alpha" <br/>Set MyVar(2)="beta"
Set MyVar(3)="gamma"
当想要传递一组相关值时,这样的本地数组非常有用。
不带下标的Global全局变量^MyVar="saved note" 在实践中,Global全局变量通常有下标。
带下标的Global全局变量Set ^MyVar($USERNAME,"Preference 1")=42
0
0 80
文章 姚 鑫 · 八月 24, 2023 2m read

第八章 ObjectScript - 变量的可用性和范围

变量的可用性和范围

ObjectScript 支持以下程序流程,(在大多数方面)与其他编程语言支持的程序流程类似:

  1. 用户可能从用户界面调用方法。
  2. 该方法执行一些语句,然后调用另一个方法。
  3. 该方法定义了局部变量 ABC

变量 ABC 在此方法的范围内。它们对于该方法是私有的。

该方法还定义了Global^D

  1. 第二个方法结束,控制返回到第一个方法。
  2. 第一个方法恢复执行。此方法不能使用不再定义的变量 AB 和 C。它可以使用^D,因为该变量立即保存到数据库中。

变量作用域总结

有几个因素控制变量在定义它的方法之外是否可用。在讨论这些之前,有必要指出以下环境细节:

  • IRIS 实例包含多个命名空间,其中包括多个系统命名空间,可能还包括定义的多个命名空间。

命名空间是任何代码运行的环境。

  • 可以在命名空间中同时运行多个进程。在典型的应用程序中,许多进程同时运行。

下表总结了可用变量的位置:

变量可用性,按变量类型细分...在定义它的方法之外(但在同一进程中)在同一命名空间的其他进程中在同一 IRIS 实例内的其他命名空间中
局部变量,私有范围*NoNoNo
局部变量,公共作用域YesNoNo
局部百分比变量YesNoNo
全局变量Global(不是百分比)YesYes除非Global映射允许这样做
Global百分比变量YesYesYes

*默认情况下,方法中定义的变量是该方法私有的,如前所述。此外,在方法中,可以将变量声明为公共变量,尽管这种做法不是首选。请参阅公共列表。

每个命名空间都有用于特定目的的默认数据库,并且可以具有允许访问其他数据库的映射。因此,Global可用于多个命名空间,即使它不是Global百分比变量。

0
0 91
文章 姚 鑫 · 八月 23, 2023 3m read

第七章 ObjectScript - Variables

Variables

ObjectScript 中,有两种变量,按它们保存数据的方式分类:

局部变量可以具有公共或私有范围。

  • 局部变量,在内存中保存数据。

局部变量可以具有公共或私有范围。

  • Global,在数据库中保存数据。这些也称为全局变量。与Global的所有交互都会立即影响数据库。例如,当设置Global值时,该更改会立即影响存储的内容;没有单独的步骤来存储值。同样,当删除Global时,数据会立即从数据库中删除。

变量名称

变量的命名遵循以下规则:

  • 对于大多数局部变量,第一个字符是字母,其余字符是字母或数字。有效名称包括 myvari
  • 对于大多数Global,第一个字符始终是脱字号 (^)。其余字符是字母、数字或句点。有效名称包括 ^myvar^my.var

IRIS 还支持一种特殊的变量,称为百分比变量;这些不太常见。百分比变量的名称以百分比字符 (%) 开头。百分比变量的特殊之处在于它们始终是公共的;也就是说,它们对进程中的所有代码都是可见的。这包括调用堆栈中的所有方法和所有过程。

定义百分比变量时,请使用以下规则:

  • 对于局部百分比变量,名称以 %Z%z 开头。其他名称保留供系统使用。
  • 对于global百分比变量,名称以 ^%Z^%z 开头。其他名称保留供系统使用。

变量类型

ObjectScript 中的变量是弱动态类型的。它们是动态类型的,因为不必声明变量的类型,并且变量可以采用任何合法值,即任何合法的文字值或任何合法的 ObjectScript 表达式。它们是弱类型的,因为用法决定了它们的计算方式。

ObjectScript 中的合法文字值具有以下形式之一:

  • 数字。示例:10017.891e3
  • 带引号的字符串,它是包含在一组匹配的引号 ("") 内的一组字符。例如:"my string"

要在字符串文字中包含双引号字符,请在其前面添加另一个双引号字符。例如: "This string has ""quotes"" in it."

根据上下文,字符串可以被视为数字,反之亦然。类似地,在某些上下文中,值可以被解释为布尔值(真或假);任何计算结果为零的内容都被视为false;其他任何内容都被视为true

创建类时,可以指定属性、方法参数的类型等。 IRIS 类机制按照预期强制执行这些类型。

Variable Length

变量值的长度必须小于字符串长度限制。

Variable Existence

通常使用 SET 命令定义变量。如前所述,当定义global 时,它会立即影响数据库。

仅当杀死global(这意味着通过 KILL 命令删除它)时,它才会变得未定义。这也会立即影响数据库。

局部变量可以通过以下三种方式之一变为未定义:

  • kill
  • 进程(定义它的过程)结束。
  • 它超出了该进程的范围。

要确定变量是否已定义,请使用 $DATA 函数。例如,以下显示了使用此功能的终端会话:

TESTNAMESPACE>write $DATA(x)
0
TESTNAMESPACE>set x=5

TESTNAMESPACE>write $DATA(x)
1

第一步,我们使用 $DATA 来查看变量是否已定义。系统显示0,表示该变量没有定义。然后我们将变量设置为 5 并重试。现在该函数返回 1

在此示例和前面的示例中,可能已经注意到没有必要以任何方式声明变量。 SET 命令就是所需要的。

如果尝试访问未定义的变量,则会收到 <UNDEFINED> 错误。例如:

TESTNAMESPACE>WRITE testvar
 
WRITE testvar
^
<UNDEFINED> *testvar
0
0 94
文章 姚 鑫 · 八月 22, 2023 3m read

第六章 ObjectScript - Routine示例

Routine示例

下面显示了一个名为 demoroutine 的示例例程,它是用 ObjectScript 编写的。它包含的过程与上一节示例类中所示的方法执行完全相同的操作。

 ; this is demoroutine 
 write "Use one of the following entry points:"
 write !,"random"
 write !,"input"
 write !,"interesting"
 quit 
 
 //this procedure can be called from outside the routine
random() public {
    set rand=$RANDOM(10)+1        ; rand is an integer in the range 1-10
    write "Your random number: "_rand
    set name=$$getnumbername(rand)
    write !, "Name of this number: "_name
 }

 //this procedure can be called from outside the routine
input() public {
    read "Enter a number from 1 to 10: ", input
    set name=$$getnumbername(input)
    write !, "Name of this number: "_name
 }
 
 //this procedure can be called only from within this routine
getnumbername(number) {
    set name=$CASE(number,1:"one",2:"two",3:"three",
        4:"four",5:"five",6:"six",7:"seven",8:"eight",
        9:"nine",10:"ten",:"other")
    quit name
}

 /* write some interesting values
 this procedure can be called from outside the routine
 */
interesting() public {
    write "Today's date: "_$ZDATE($HOROLOG,3)
    write !,"Your installed version: "_$ZVERSION
    write !,"Your username: "_$USERNAME
    write !,"Your security roles: "_$ROLES  
    }

请注意以下要点:

  • 唯一真正以插入符号 (^) 开头的标识符是globals的名称。但是,在运行文本和代码注释中,习惯上引用例程就好像其名称以插入符号开头一样,因为在调用例程时使用插入符号(如本页后面所示)。例如,例程 demoroutine 通常称为 ^demoroutine
  • 例程名称不必包含在例程中。然而,许多程序员将例程名称作为注释包含在例程的开头或作为例程中的第一个标签。
  • 该例程有多个标签:randominputgetnumbernameinteresting

标签用于指示过程(如本示例中所示)、函数和子例程的起点。还可以将它们用作某些命令的目标。

标签在例程中很常见,但也可以在方法中使用它们。

标签也称为入口点或标签。

  • randominput 子例程调用 getnumbername 子例程,该子例程是例程私有的。

我们可以在终端中执行此例程的部分内容,作为演示。首先,下面显示了一个终端会话,我们在其中运行例程本身。

TESTNAMESPACE>do ^demoroutine
Use one of the following entry points:
random
input
TESTNAMESPACE>

当我们运行例程时,我们只是获得帮助信息,如所见。不需要以这种方式编写例程,但这是常见的。请注意,例程在第一个标签之前包含 QUIT,以确保当用户调用例程时,处理在该标签之前停止。这种做法也不是必需的,但也很常见。

接下来,下面显示了几个子例程的行为方式:

TESTNAMESPACE>do input^demoroutine
Enter a number from 1 to 10: 7
Name of this number: seven
TESTNAMESPACE>do interesting^demoroutine
Today's date: 2018-02-06
Your installed version: IRIS for Windows (x86-64) 2018.1 (Build 513U) Fri Jan 26 2018 18:35:11 EST
Your username: _SYSTEM
Your security roles: %All
TESTNAMESPACE>

方法可以包含与例程相同的语句、标签和注释。也就是说,这里有关例程内容的所有信息也适用于方法的内容。

0
0 79
文章 姚 鑫 · 八月 21, 2023 3m read

第五章 ObjectScript

方法和例程都可以用 ObjectScript 编写,但大多数现代代码都是使用方法编写的。方法包含在类中,这允许将类似的方法分组在一起,在类参考中自动生成文档,以及使用 IRIS 的面向对象功能。

这并不意味着routines 不重要。许多有用的系统实用程序都是作为例程编写的,并且在编译类时会生成例程。

示例类

下面显示了一个名为 User.DemoClass 的示例类,其中包含用 ObjectScript 编写的方法。此示例使我们有机会了解一些常见的 ObjectScript 命令、运算符和函数,并了解代码在方法内的组织方式。

Class User.DemoClass
{

/// Generate a random number.
/// This method can be called from outside the class.
ClassMethod Random() [ Language = objectscript ]
{
    set rand=$RANDOM(10)+1        ; rand is an integer in the range 1-10
    write "Your random number: "_rand
    set name=..GetNumberName(rand)
    write !, "Name of this number: "_name
}

/// Input a number.
/// This method can be called from outside the class.
ClassMethod Input() [ Language = objectscript ]
{
    read "Enter a number from 1 to 10: ", input
    set name=..GetNumberName(input)
    write !, "Name of this number: "_name
}

/// Given an number, return the name.
/// This method can be called only from within this class.
ClassMethod GetNumberName(number As %Integer) As %Integer [ Language = objectscript, Private ]
{
    set name=$CASE(number,1:"one",2:"two",3:"three",
        4:"four",5:"five",6:"six",7:"seven",8:"eight",
        9:"nine",10:"ten",:"other")
    quit name
}

/// Write some interesting values.
/// This method can be called from outside the class.
ClassMethod Interesting() [ Language = objectscript ]
{
    write "Today's date: "_$ZDATE($HOROLOG,3)
    write !,"Your installed version: "_$ZVERSION
    write !,"Your username: "_$USERNAME
    write !,"Your security roles: "_$ROLES
}

}

请注意以下要点:

  • Random()Input() 方法调用GetNumberName() 方法,该方法是此类的私有方法,不能从类外部调用。
  • WRITEQUITSETREAD 是命令。该语言还包括用于删除变量的其他命令、用于控制程序流的命令、用于控制 I/O 设备的命令、用于管理事务(可能是嵌套的)的命令等等。

命令名称不区分大小写,尽管按照惯例它们在运行文本中显示为全大写。

  • 该示例包括两个运算符。加号(+)执行加法,下划线(_)执行字符串连接。

ObjectScript 提供了常用的运算符和一些其他语言中未见的特殊运算符。

  • $RANDOM$CASE$ZDATE 是函数。

该语言提供了字符串操作、多种转换、格式化操作、数学操作等的函数。

  • $HOROLOG$ZVERSION$USERNAME$ROLES 是系统变量(在 IRIS 中称为特殊变量)。大多数特殊变量包含 IRIS 操作环境、当前处理状态等方面的值。
  • ObjectScript 支持注释行、块注释和语句末尾的注释。

我们可以在终端中执行该类的方法,作为演示。在这些示例中,<TESTNAMESPACE> 是终端中显示的提示符。同一行提示符后面的文本是输入的命令。之后的行显示系统作为响应写入终端的值。

TESTNAMESPACE>do ##class(User.DemoClass).Input()
Enter a number from 1 to 10: 7
Name of this number: seven
TESTNAMESPACE>do ##class(User.DemoClass).Interesting()
Today's date: 2021-07-15
Your installed version: IRIS for Windows (x86-64) 2019.3 (Build 310U) Mon Oct 21 2019 13:48:58 EDT
Your username: SuperUser
Your security roles: %All
TESTNAMESPACE>
0
0 101
文章 姚 鑫 · 八月 20, 2023 2m read

第四章 IRIS 编程简介 - Macros

Macros

ObjectScript 还支持定义替换的宏。定义可以是一个值、整行代码或(使用 ##continue 指令)多行。使用宏来确保一致性。例如:

#define StringMacro "Hello, World!"

write $$$StringMacro

Include Files

可以在例程中定义宏,并稍后在同一例程中使用它们。更常见的是,在中心位置定义它们。为此,需要创建并使用包含文件。包含文件定义宏并且可以包含其他包含文件。

这些代码元素如何协同工作

可以混合使用 ObjectScriptPythonSQL、类定义、宏、例程等的原因是 IRIS 不直接使用编写的代码。相反,当编译代码时,系统会生成它使用的较低级别的代码。这是由 ObjectScript 引擎使用的 ObjectScriptOBJ 代码,以及由 Python 引擎使用的 PythonPYC 代码。

有多个步骤。无需详细了解这些步骤,但最好记住以下几点:

  • 对于除 Python 方法之外的所有元素,类编译器将类定义和 ObjectScript 代码处理为 INT 代码。 Python代码被处理成PY代码。

在某些情况下,编译器会生成并保存您不应编辑的其他类。例如,当编译定义 Web 服务和 Web 客户端的类时,就会发生这种情况。

类编译器还为每个类生成类描述符。系统代码在运行时使用它。

  • 对于 ObjectScript 代码,预处理器(有时称为宏预处理器或 MPP)使用包含文件并替换宏。它还处理例程中的嵌入式 SQL

这些更改发生在临时工作区中,并且代码不会更改。

  • 其他编译器为例程创建 INT 代码。
  • INT 代码和 PY 代码是中间层,其中通过直接Global访问来处理对数据的访问。该代码是人类可读的。
  • INT代码用于生成OBJ代码,PY代码用于生成PYC代码。 IRIS 虚拟机使用此代码。一旦将代码编译为 OBJPYC 代码,代码执行就不再需要 INTPY 例程。
  • 编译类后,可以将它们置于部署模式。 IRIS 有一个实用程序,可以删除给定类的类内部和中间代码;可以在部署应用程序时使用此实用程序。

如果检查 IRIS 系统类,可能会发现某些类看不到,因为它们处于部署模式。

注意:所有类定义和例程都与生成的代码存储在同一 IRIS 数据库中。这一事实使代码更易于管理。 IRIS 提供了一组强大的源代码控制挂钩, 开发人员已使用这些挂钩多年。也可以使用这些挂钩。

0
0 154
文章 姚 鑫 · 八月 19, 2023 1m read

第三章 IRIS 编程简介 - SQL

SQL

IRIS 提供了 SQL 的实现,称为 SQL。可以在方法和例程中使用 SQL

ObjectScript 使用 SQL

可以使用以下一种或两种方式从 ObjectScript 执行 SQL

  • 动态 SQL%SQL.Statement%SQL.StatementResult 类),如下例所示:
 SET myquery = "SELECT TOP 5 Name, Title FROM Sample.Employee ORDER BY Salary"
 SET tStatement = ##class(%SQL.Statement).%New()
 SET tStatus = tStatement.%Prepare(myquery)
 SET rset = tStatement.%Execute()
 DO rset.%Display()
 WRITE !,"End of data"

可以在 ObjectScript 方法和例程中使用动态 SQL

  • 嵌入式SQL,如下例所示:
 &sql(SELECT COUNT(*) INTO :myvar FROM Sample.Employee)
    IF SQLCODE<0 {WRITE "SQLCODE error ",SQLCODE," ",%msg  QUIT}
    ELSEIF SQLCODE=100 {WRITE "Query returns no results"  QUIT}
 WRITE myvar

第一行是嵌入式 SQL,它执行 SQL 查询并将值写入名为 myvar 的主变量中。

下一行是普通的ObjectScript;它只是写入变量 myvar 的值。

可以在 ObjectScript 方法和例程中使用嵌入式 SQL

Python 使用 SQL

Python 使用 SQL 与从 ObjectScript 使用动态 SQL 类似。可以使用以下一种或两种方式从 Python 执行 SQL

  • 可以直接执行SQL查询,如下例所示:
import iris
rset = iris.sql.exec("SELECT * FROM Sample.Employee ORDER BY Salary") 
for row in rset:
    print(row)

第二行执行 SQL 查询并返回存储在变量 rset 中的结果集。

  • 也可以先准备 SQL 查询,然后执行它,如下例所示:
import iris
statement = iris.sql.prepare("SELECT * FROM Sample.Employee ORDER BY Salary")
rset = statement.execute()
for row in rset:
    print(row)

在此示例中,第二行返回一个 SQL 查询,该查询在第三行上执行以返回结果集。

可以使用这两种方法之一在 Python 终端或 Python 方法中执行 SQL 查询。

0
0 125
文章 姚 鑫 · 八月 18, 2023 2m read

第二章 IRIS 编程简介 - 同时使用类和例程

同时使用类和例程

IRIS 中,可以使用例程中的类。例如,下面显示了例程的一部分,其中我们引用了 Sample.Employee 类:

 //get details of random employee and print them
showemployee() public {
    set rand=$RANDOM(10)+1        ; rand is an integer in the range 1-10
    write "Your random number: "_rand
    set employee=##class(Sample.Employee).%OpenId(rand)  
    do employee.PrintEmployee()
    write !,"This employee's salary: "_employee.Salary
      
    }

类似地,方法可以调用例程中的标签。例如,以下代码调用例程employeeutils中的标签ComputeRaise

Method RaiseSalary() As %Numeric
{
    set newsalary=$$ComputeRaise^employeeutils(..Salary)
    return newsalary
}

Globals简介

IRIS 支持一种在其他编程语言中不存在的特殊变量;这是一个全局变量,通常简称为Global。在 IRIS 中,术语Global表示该数据可供访问该数据库的所有进程使用。这种用法与其他编程语言不同,在其他编程语言中,Global意味着“可供该模块中的所有代码使用”。Global的内容存储在 IRIS 数据库中

IRIS 中,数据库仅包含Global;甚至代码也存储在Global中。在最低级别,对数据的所有访问都是通过直接Global访问完成的,即通过使用直接与Global一起使用的命令和函数。

当使用持久类时,可以通过以下方式创建、修改和删除存储的数据:

  • ObjectScript 中,使用 %New()%Save()%Open()%Delete() 等方法。
  • Python 中,使用 _New()_Save()_Open()_Delete() 等方法。
  • ObjectScript 中,使用直接global 访问。
  • Python中,使用gref()方法提供直接的全局访问。
  • 通过使用 SQL

在内部,系统始终使用直接global访问。

程序员不一定必须直接使用global,但了解它们以及它们的使用方式会很有帮助。

0
0 92
文章 姚 鑫 · 八月 17, 2023 2m read

第一章 IRIS 编程简介

简介

IRIS 是一个高性能多模型数据平台,具有内置的通用编程语言 ObjectScript,以及对 Python 的内置支持。

IRIS 支持多进程并提供并发控制。每个进程都可以直接、高效地访问数据。

IRIS 中,可以根据喜好编写类、例程或它们的组合。在所有情况下,存储的数据最终都包含在称为全局变量的结构中。 IRIS 编程具有以下特点:

  • 类和例程可以互换使用。
  • 类和例程可以互相调用。
  • 类提供面向对象的功能。
  • 数据库存储已集成到 ObjectScriptPython 中。
  • 类可以以简化编程的方式保存数据。如果使用持久类,数据可以同时作为对象、SQL 表和全局变量使用。
  • 可以直接从类或例程访问全局变量,这意味着可以灵活地按照想要的方式存储和访问数据。

可以选择适合需求的方法。

Classes

IRIS 支持类。可以使用系统类,也可以定义自己的类。

IRIS 中,类可以包含熟悉的类元素,例如属性、方法和参数(在其他类语言中称为常量)。它还可以包含通常不在类中定义的项目,包括触发器、查询和索引。

IRIS 类定义使用类定义语言 (CDL) 来指定类及其成员,例如属性、方法和参数。可以使用 PythonObjectScript 在方法内部编写可执行代码。对于每个方法,使用 Language 关键字指定将使用哪种语言编写该方法,如下例所示。

下面显示了一个类定义:

Class Sample.Employee Extends %Persistent
{

/// The employee's name.
Property Name As %String(MAXLEN = 50);

/// The employee's job title.
Property Title As %String(MAXLEN = 50);

/// The employee's current salary.
Property Salary As %Integer(MAXVAL = 100000, MINVAL = 0);

/// This method prints employee information using ObjectScript.
Method PrintEmployee() [ Language = objectscript] 
{
    Write !,"Name: ", ..Name, " Title: ", ..Title
}

}

如果不指定方法使用哪种语言,编译器将假定该方法是用 ObjectScript 编写的。

Routines

当在 IRIS 中创建例程时,可以使用 ObjectScript。下面显示了用 ObjectScript 编写的例程的一部分:

    SET text = ""
    FOR i=1:5:$LISTLENGTH(attrs)
    {
        IF ($ZCONVERT($LIST(attrs, (i + 1)), "U") = "XREFLABEL")
        {
            SET text = $LIST(attrs, (i + 4))
            QUIT
        }
    }
    
    IF (text = "")
    {
        QUIT $$$ERROR($$$GeneralError,$$$T("Missing xreflabel value"))
    }
0
0 337
文章 姚 鑫 · 八月 16, 2023 4m read

第二十四章 参考 - HL7业务服务的设置- 忽略入站 ACK

忽略入站 ACK

如果为 True,业务服务将忽略任何入站 ACK 消息,以避免创建 ACK 反馈循环。

Local Facility Application

以冒号分隔的 LocalFacility:LocalApplication 代码,表示通过此业务服务接收 HL7 消息的设施和应用程序。如果此业务服务创建自己的 ACK,则本地设施应用程序会为 ACK 消息提供 SendingFacility:SendingApplication 代码;否则,该设置将被忽略。

Message Schema Category

应用于传入消息类型以生成完整的 DocType 规范的类别。与文档类型名称 (MSH:9) 结合生成 MessageType 规范,然后使用该规范在给定 HL7 模式类别的 MessageTypes 部分中查找 MessageStructure / DocType

此设置还可以包含多个以逗号分隔的类型名称,后跟 =,然后是 DocTypeCategory 或完整的 DocType 值,以应用于包含该类型名称的 HL7 消息。给定部分类型名称末尾的尾随星号 (*) 与以该条目开头的任何类型匹配。

HL7 消息对象的 DocType 属性

例如:MessageSchemaCategory='2.3.1, ADT_*=2.5, BAR_P10=2.4, ORM_O01_6=2.4:RDE_O01'

请注意,验证或搜索表类索引可能需要 DocType 分配。

如果您尚未为 HL7 业务服务准备自定义架构定义,则可以暂时将此字段留空。但是,请勿将其永久留空,除非您还禁用路由过程的验证,否则将自动发生验证错误。请参阅“验证”。

NACK Error Code

控制当处理传入消息时出现错误时此服务生成的 NACK 消息的 MSA:1 中的错误代码。默认值为 ContentE,对于消息内容错误返回代码 E,对于在尝试处理消息时遇到的系统错误返回代码 R

这种区别很重要,因为production 期望系统错误能够得到解决,这样如果远程客户端稍后再次尝试,这些错误可能就不会发生,而消息内容和验证错误预计需要在源头进行更正,并且不值得重试以相同的形式。某些客户端系统可能期望或需要不同的错误行为;因此, 产品提供了四种附加行为。下表描述了四个选项。

CodeMeaning
ContentE使用 MSA 错误代码 E 报告消息内容中的错误,并使用代码 R 拒绝由于(可重试)系统错误
ContentR*返回 R 表示内容错误,E 表示系统错误
AllE对于所有内容和系统错误均返回 E
AllR对于所有内容和系统错误返回 R

Save Replies

指定是否保存发送回远程系统的回复消息的副本。还可以选择指定是否使用配置的搜索表类(如果有)对它们进行索引。选择以下选项之一:

  • None — 不保存或索引任何回复消息。
  • NotOKs — 仅保存不是简单 OK ACK 消息的回复,例如,保存错误 NACKS 和查询响应。
  • All — 保存发送到远程系统的所有回复消息的副本。
  • IndexNotOKs — 保存不是简单 OK ACK 消息的回复,并使用配置的搜索表对它们进行索引。这是默认行为,除非已覆盖此类中的 IndexRepliesSaveOKACKsIndexACKs 参数。请注意,IndexRepliesSaveOKACKIndexACK 现已弃用。
  • IndexAll — 保存所有回复消息的副本并使用配置的搜索表对其进行索引。

使用 ACK 提交代码

对或错。如果为 True,则在为 HL7 消息版本 2.3 或更高版本创建ACK 消息时,业务服务会将增强模式 ACK 提交代码之一放置在 MSA 段 AcknowledgmentCode 字段中。

HL7 业务服务具有“使用 ACK 提交代码”设置,该设置适用于消息架构类别为 2.3 或更高版本的情况。它可以是对的,也可以是错的。如果为 True,则在为 HL7 消息版本 2.3 或更高版本创建 ACK 消息时,业务服务会将增强模式 ACK 提交代码之一放置在 MSAAcknowledgmentCode 字段中。该代码可以是以下两个字母序列之一:

CodeMeaning in Original ModeMeaning in Enhanced Mode
AAApplication AcceptApplication acknowledgment: Accept
AEApplication ErrorApplication acknowledgment: Error
ARApplication RejectApplication acknowledgment: Reject
CAAccept acknowledgment: Commit Accept
CEAccept acknowledgment: Commit Error
CRAccept acknowledgment: Commit Reject
0
0 124
文章 姚 鑫 · 八月 15, 2023 3m read

第二十三章 参考 - HL7业务服务的设置- DocTypeResolution

DocTypeResolution

指定如何根据 MSH:9 中的消息类型解析 DocType。选择以下选项之一:

  • Standard标准 — 将有效消息架构类别值与在相应架构类别中查找 MSH:9 消息类型值的消息结构名称相结合。这是默认设置。
  • Ignore 9.3 — 与“标准”类似,但如果 MSH:9 有三个或更多部分,则忽略其他部分。标准行为是使用第 3 部分作为类型名称的一部分(如果它没有子部分),因为某些模式包含三部分类型名称。
  • Use 9.3 — 与“标准”类似,但如果 MSH:9 具有三个或更多部分,则使用附加部分作为适用模式类别中文档结构的文字名称。请谨慎使用,因为消息到达时可能带有 MSH:9.3 值,而所选架构类别中不存在其结构。
  • Literal 文字 — 将有效消息架构类别值与解释为消息结构名称的文字 MSH:9 消息类型值相结合。仅与每个消息类型都有相应的结构定义的自定义架构一起使用。

Override Segment Terminator

(仅限 FTP)用作段终止符的以逗号分隔的 ASCII 控制字符列表。这些值可以是十进制格式或十六进制格式,前面带有 x。例如,要将换行符指定为段终止符,请输入 10x0A。默认值为回车符,十进制值为 13,十六进制值为 x0D

Framing

控制 HL7 业务服务如何解释传入的 HL7 消息数据包。如果不确定使用什么值,请接受 HL7 业务服务的默认灵活框架。

下表列出了此设置的有效值。

Framing TypeInbound / OutboundMeaning
FlexibleInbound根据接收到的数据内容确定帧样式。
Flexible!Inbound根据接收到的第一条消息的数据内容确定帧样式,并要求后续消息具有相同的帧样式。
NoneBoth没有框架;以字符串 MSH 开头的每一行都是新消息的开始。
MLLPBoth最小较低层协议 — 使用 ASCII 11 前缀和由 ASCII 28 后跟 ASCII 13 组成的后缀构建每个 HL7 消息。
MLLP[nn]/[mm]Both使用非标准 ASCII 值的 MLLP。使用由 nn 指示的 ASCII 字符值组成的前缀构成每个 HL7 消息。还提供由 mm 指示的 ASCII 字符值后跟 ASCII 13(回车符)组成的后缀。
AsciiLFBoth使用 ASCII10(换行符)构建消息,将每条消息与后续消息分隔开。
AsciiCRBoth使用额外的 ASCII13(回车符)构建消息,将每条消息与后续消息分隔开。
Ascii[nn]Both使用后缀将每条消息与后续消息分开的帧消息。该后缀由 nn 指示的 ASCII 字符值组成。
Ascii[nn]/[mm]Both在每条消息之前使用前缀字符构建消息。该前缀由 nn 指示的 ASCII 字符值组成。还提供由 mm 指示的 ASCII 字符值组成的后缀,但不带尾部 ASCII 13
LLPBoth(已过时)较低层协议 — 将每个 HL7 消息构造在冗余校验和块中。
MsgEnvelopeOutbound逐字使用消息信封属性(如果存在)。如果信封中存在字符串 <!--HL72MSG-->, 会将其替换为消息内容;否则消息将跟随信封文本。
MLLPMsgEnvelopeOutboundMsgEnvelope相同,但是在信封内的消息周围也使用MLLP前缀和后缀。

当成帧类型为 MLLP 时, 会自动检测关闭成帧之前消息中出现的额外回车符 (ASCII 13)。这向表明空行未用于分隔消息,因此它假定任何空行都是消息内容的一部分并且可以安全地忽略。

根据 HL7 标准,段终止符是回车符 (CR)。但是,也接受回车/换行 (CRLF) 字符。

可以指定多个字符。例如,如果需要非标准帧,例如 HL7 消息的消息开始 $Char(2) 和消息结束 $Char(3,4),则可以使用 Ascii[nn]/[mm] 帧选项,如下所示:

Ascii2/3,4

注意:在“框架”字段中输入 ASCII 值时,必须以数值形式给出。例如,输入小写 x 作为 Ascii120,而不是 Ascii'x'

0
0 145
文章 Michael Lei · 八月 10, 2023 2m read

InterSystems 常见问题解答

※如果您想比较使用Mirror、Shadow或其他机制复制的数据库,请使用此方法。

您可以使用 DATACHECK 实用程序来比较Global。请参阅下面的文档。
DataCheck 概述 [IRIS]

***

Routines比较使用系统例程 %RCMP 或管理门户。

以下是如何在管理门户中使用它。

0
0 177
文章 姚 鑫 · 八月 10, 2023 3m read

第十八章 定义 HL7 搜索表

HL7 搜索表类 EnsLib.HL7.SearchTable,自动索引填充的 HL7 属性。

如果需要搜索更多的项,可以创建一个子类。子类继承Identifier属性,以及使搜索表工作的基础结构。具体操作请参见在产品中使用虚拟文档中的“定义搜索表类”。

对于HL7, 支持PropType的附加值。除了在产品中使用虚拟文档中列出的类型之外,还可以使用DateTime:HL7

创建搜索表时,不要使用保留的包名;参见开发产品中的“保留包名”。

默认索引的属性

当选择EnsLib.HL7。searchtable作为搜索表类,使能够在HL7消息中搜索以下虚拟属性。

  • MSHTypeName

消息结构名称。为了创建这个字符串,将HL7消息中的以下值连接起来: - MSH消息头段

字段`9`(消息类型)

子字段`1`(消息类型`:ADT`, `ORM`等)

- 文字字符_
- `MSH`消息头段

字段`9`(消息类型)

子字段`2`(触发事件:`A01、A12、O01_2`等)

结果是一个格式为ADT_A01, ADT_A12, ORM_O01_2等的消息结构名称。

  • MSHControlID

此消息的唯一标识号。production程序从:

- `MSH`消息头段
- 字段10(消息控制ID)

将此值解释为区分大小写的字符串。

  • PatientID

此消息的患者标识符。随着HL7标准的发展,这个领域的位置也发生了变化。出于这个原因,在以下所有位置查找此值。这样,无论消息符合哪个HL7模式类别,都可以找到患者标识符: - PID患者标识符段

字段`2`(患者外部标识符)

子字段`1`(患者标识符)

- `PID`患者标识符段

字段`3`(患者标识符列表),列表中的所有条目

子字段`1`(患者标识符)

- `PID`患者标识符段

字段`4`(患者标识符列表),列表中的所有条目

子字段`1`(患者标识符)
  • PatientName

PID患者标识符段

字段5(患者姓名)

  • PatientAcct

PID患者标识符段

字段18(患者账号)

子字段1 (ID)

示例

下面的示例包含一个使用{}语法的虚拟属性路径。这个<Item>元素指的是HL7消息中第1段第10字段的值:

<Item DocType=""
      PropName="MSHControlID"
      PropType="String:CaseSensitive"
      StoreNulls="true" >
      {1:10}
</Item>

下面这个更复杂的<Item>元素使用objectscript_操作符连接三个字符串。从左到右依次是:

  • 1,字段4内的值
  • 文字-字符
  • 1,字段3内的值
<Item DocType=""
      PropName="SendingFacilApp" >
      {1:4}_"-"_{1:3}
</Item>

下面的<Item>示例使用了大多数可能的语法选项:连接、虚拟属性、字符-ObjectScript字符串函数$PIECE

XData SearchSpec [ XMLNamespace="http://www.intersystems.com/EnsSearchTable" ]
{
<Items>
 <Item DocType="Mater:ORM_O01 "
       PropName="RelationKey" >
 $P(
 {ORCgrp(1).OBRuniongrp.OBRunion.OBR:UniversalServiceID.text},"-",1,2
 )_"-"_{MSH:12}
 </Item>
</Items>}

下面的示例搜索表类提供了几个有效<Item>条目的示例。这个类继承自EnsLib.HL7。searchtable,这是HL7搜索表所需要的。每组<Item>条目上面的注释描述了这组条目的目的。关于{}[]语法的详细信息,请参见在生产中使用虚拟文档的“语法指南”一节。

Class Demo.HL7.MsgRouter.SearchTable Extends EnsLib.HL7.SearchTable
{

XData SearchSpec [ XMLNamespace="http://www.intersystems.com/EnsSearchTable" ]
{
  <Items>
   <!-- Items that do not depend on DocType, indexing any HL7 message -->
   <Item DocType="" PropName="SendingFacilApp" >{1:4}_"|"_{1:3}</Item>
   <Item DocType="" PropName="RecvingFacilApp" >{1:6}_"|"_{1:5}</Item>
   <Item DocType="" PropName="MSHDateTime" PropType="DateTime:HL7" >{1:7}</Item>

   <!-- Get fields from named segments found in any HL7 message -->
   <Item DocType="" PropName="PatientName" >[PID:5]</Item>
   <Item DocType="" PropName="InsuranceCo" >[IN1:4]</Item>

   <!-- Get patient name from any HL7 message declared type ADT_A05 -->
   <Item DocType=":ADT_A05" PropName="PatientName" >{3:5}</Item>

   <!-- Get specific field from specific segment when the        -->
   <!-- HL7 message is assigned a specific DocType. Only in this -->
   <!-- case can you use names for segments, instead of numbers. -->
   <Item DocType="Demo.HL7.MsgRouter.Schema:ORM_O01 " PropName="ServiceId" >
     {ORCgrp().OBRuniongrp.OBRunion.OBR:UniversalServiceID.text}
   </Item>
   <Item DocType="2.3.1:ORU_R01 " PropName="ServiceId" >
     {PIDgrpgrp().ORCgrp(1).OBR:UniversalServiceID.text}
   </Item>
  </Items>
}

}
0
0 106
文章 姚 鑫 · 八月 8, 2023 3m read

第十六章 定义 HL7 的 DTL 数据转换 - 转换长段字段

转换长段字段

DTL 转换使用的 ObjectScript 方法 GetValueAtHL7 段字段截断为 3.6MB。因此,当转换长度超过 3.6MB 的字段时,无法在 DTL 编辑器中使用从左到右的拖动操作。例如,如果 OBX:5 字段超过 3.6MB,则无法使用 DTL 编辑器将源字段拖动到目标,因为它将被截断。同样,如果要转换的字段长度超过 3.6MB,则自定义代码不应调用 GetValueAt

要转换长度超过 3.6MB 的字段,需要使用代码操作将自定义代码添加到转换中。此自定义代码必须在的 EnsLib.HL7.Segment 中包含以下方法之一,以将字段的值从源读取到流中:GetFieldStreamRaw()GetFieldStreamUnescaped()GetFieldStreamBase64()

这些 Get 方法采用 3 个参数:流输出参数、字段的 VDoc 路径和 pRemainder 输出参数。 ``pRemainder` 参数将填充被提取的字段之后的所有字段。例如:

/// Segment:  OBX|1|2|3|4|5|6|7
do GetFieldStreamRaw(.stream, "OBX:5", .rem)
/// rem contains: |6|7

一旦自定义代码在流中具有字段值,必须使用 EnsLib.HL7.Segment 的以下方法之一将值存储在目标中:StoreFieldStreamRaw()StoreFieldStreamUnescaped()StoreFieldStreamBase64()

这些 Store 方法接受三个参数:要存储在字段中的流、要在其中存储流的字段的 VDoc 路径以及 pRemainder 参数。如果未指定 pRemainder 参数,则删除正在存储的字段之后的所有目标字段。例如:

/// Before: OBX|1|2|3|4|5|6|7
do StoreFieldStreamRaw(stream, "OBX:5")
/// After: OBX|1|2|3|4|<stream> 
/// |6|7 are gone because a remainder was not specified.

如果指定了 pRemainder,则存储的字段之后的所有字段都将替换为 pRemainder 中的内容。

/// Before: OBX|1|2|3|4|5|6|7
do StoreFieldStreamRaw(stream, "OBX:5", "|six|seven")
/// After: OBX|1|2|3|4|<stream>|six|seven

重要提示:一旦调用 Store 方法,目标段就变得不可变,因此它必须是对段进行的最后更改。

以下示例演示如何从源中提取字段并将其存储在目标中。它假设自定义代码在调用 Store 方法之前对 3.6MB+ 字段之后的目标字段进行了编辑;需要这种方法是因为调用 Store 方法后段变得不可变。示例代码不会从源中获取剩余部分并将其存储在目标中,因为这会恢复已对目标长字段之后的字段进行的编辑。因此,您可以从源中获取流字段,但从目标中获取其余部分,并将这两个字段都存储在目标中:

/// previous code makes edits to fields that come after OBX:5 in the target
do source.GetFieldStreamRaw(.stream, "OBX:5")
do target.GetFieldStreamRaw(.dummy, "OBX:5", .rem)
do target.StoreFieldStreamRaw(stream, "OBX:5", rem)
///Segment is now immutable

这样做可以防止对 OBX:5 之后的目标字段所做的编辑被恢复或删除。

0
0 118
文章 Weiwei Gu · 八月 7, 2023 1m read

InterSystems 常见问题解答标题

您可以为以下 Web Gateway 错误消息/系统响应设置单独的错误页面:

  • 服务器错误
  • 服务器繁忙
  • 服务器无法使用
  • 服务器超时
  • 连接关闭

在 Web Gateway 管理界面上进行设置([Management Portal] > [System Administration] > [Configuration] > [Web Gateway Management] > [Configuration] > [Default Parameters])。

在“默认参数”(Default Parameters  )菜单的“错误页面”部分中,设置要显示的 html 页面的文件名或发生错误时要重定向到的 URL。

 

0
0 149
文章 姚 鑫 · 八月 6, 2023 3m read

第十四章 配置Production - 定义 HL7 的路由规则集

HL7 接口创建路由规则集时,目标是根据源消息中找到的段告诉production如何处理源消息。有时找到哪些片段很重要;有时,在这些细分中找到哪些值很重要。

在普通规则集中,每个规则都会向调用该规则集的业务流程返回一个值。在路由规则集中,规则通常将 HL7 消息定向到目的地,并可能在发送之前转换 HL7 消息。

创建规则集时,不要使用保留的包名称

  1. 当使用业务规则向导创建新的 HL7 路由流程时, 会创建一个新的空路由规则集来伴随新的路由流程。其信息表包含以下值:
  • Package Name 包名称 - 包含production类的包。例如,如果使用向导将路由进程添加到名为 TestRule.MyTest 的产品中,则关联的路由规则的包名称为:TestRule
  • Rule Name规则名称 - 在向导中选择的简单路由规则名称,例如:MyRule

包名称和规则名称的组合在命名空间内唯一标识规则。任何规则定义的全名是由点 (.) 连接的包名称和规则名称,如下所示:TestRule.MyRule

配置 HL7 路由流程时,该全名(而不是规则名称)是 BusinessRuleName 字段中使用的正确值。业务流程向导会自动进行设置。

  • Routing Engine Class 路由引擎类 — 向导中的默认路由器类;不要改变它:EnsLib.HL7.MsgRouter.RoutingEngine
  1. 还可以输入其他字段以用于自己的规则报告目的:
  • Report Group报告组 - 用于对报告规则进行分组的值
  • Report Name报告名称 - 规则报告组的显示值
  • Short Description 简短描述 - 此规则定义的可选简短描述
  1. 创建新规则后,可以向其中添加条件和操作。
  • 条件首先评估 AND 运算符,然后评估 OR
  • 条件可以引用 HL7 消息对象的属性。在 Conditions 中,特殊变量 Document 表示 HL7 消息对象,如以下示例所示。对于 HL7 批处理文档,可以使用特殊变量 Document.Parent 来表示父消息对象。
Document.Name
Document.Parent.DocType
Document.{PIDgrp.PV1grp.PV1:18}
Document.{PIDgrp.PID:PatientName.familylastname}
Document.{ORCgrp(1).OBRuniongrp.OBRunion.OBR:4.3}

注意:为了与过去的版本兼容,支持特殊变量 HL7HL7.Parent 作为 DocumentDocument.Parent 的替代变量。

点将文档变量与属性名称分隔开。这个名字可能是:

  • 任何类属性:DocTypeTypeCategoryBuildMapStatusName

  • 虚拟属性,使用以下任一约定引用:

    • Curly brackets

    {segmentPath:field}

    • Square brackets

    [segmentName:field]

    • Round brackets or parentheses

    (multi-valued-property-path)

    • Angle brackets

    <context|expression>

  1. 完成接下来几个主题中的说明,以创建路由规则集所需的任何源、目标或转换项。这些项目可能是:
  • HL7 业务服务,用于将消息路由到规则
  • DTL 数据转换,在发送消息之前转换消息
  • HL7 业务操作,将消息路由到外部应用程序 -HL7 路由进程可以是源或目标

创建项目时,返回到消息路由规则编辑器以将它们添加到规则定义的相应字段中。

返回Production配置页面上的图表。选择对应的HL7路由进程。在 BusinessRuleName 字段中,输入新路由规则集的全名。

0
0 128
文章 姚 鑫 · 八月 4, 2023 3m read

第十二章 配置Production - 添加HL7序列管理器

添加HL7序列管理器

HL7消息可能由于各种原因而乱序,特别是在多个处理器处理它们时。在某些情况下,需要确保按照正确的顺序处理HL7消息。在这种情况下,可以将HL7序列管理器添加到production的适当部分。

HL7序列管理器是一个业务流程,它接受传入的HL7消息(可能来自多个源),然后按照消息中的MSH:13SequenceNumbers字段指定的顺序将消息转发到目标配置项。

序列管理器可以检测重复的消息和消息之间的时间间隔。它还确定顺序消息之间的时间间隔何时大到足以表明问题。它的灵敏度级别可以使用它的配置设置来调整。

要构建用于HL7消息路由生产的HL7序列管理器,必须创建并配置它,然后将其集成到生产中。本主题将解释每个步骤。

重要:HL7序列管理器是HL7兼容的存储转发应用程序,不支持HL7标准第2章2.10.1节中定义的HL7序列号协议。

创建HL7序列管理器

HL7序列管理器添加到production中:

  1. Management Portal“production Configuration”页面(在“Home”页面选择“Interoperability > Configure > production”)中显示production结果。
  2. Processes列中,单击Add按钮(加号)。
  3. ProcessClass 列表中选择 EnsLib.HL7.SequenceManager
  4. 对于名称,键入此业务流程的名称。该名称在业务流程中应该是唯一的。请勿使用句点或空格。

默认值是该进程所基于的类的名称。

  1. 单击“确定”。

如果需要,一个作品可以有多个序列管理器。

集成和配置 HL7 序列管理器

要将新的 HL7 序列管理器集成到production中,必须将其与接收传入消息的业务服务相关联,并在它整理出正确的序列后与其发送的消息的目标目的地相关联。去做这个:

  1. 选择 HL7 业务服务。在“目标配置名称”字段中,输入新HL7 序列管理器的名称。
  2. 返回配置 HL7 序列管理器。为其提供成功消息的输出目标配置名称列表。
  3. 如果希望序列管理器检查重复消息,请将启用重复消息检查设置为 True

如果要保存重复消息以用于故障排除,请创建 HL7 业务操作来接收它们。在重复消息目标字段中输入新 HL7 业务操作的名称。

  1. 如果希望序列管理器检查无序消息,请将执行序列号检查设置为发送方或接收方,并通过设置大间隙大小和消息等待超时的值来配置序列检查的详细信息。否则,将“执行序列号检查”设置为“无”。

如果要保存无序消息以用于故障排除,请创建 HL7 业务操作来接收它们。在“无序消息目标”字段中,输入新 HL7 业务操作的名称。

  1. 如果希望序列管理器在将消息发送到 产品之外之前对其进行转换,请将“执行输出转换打开”设置为“发送方”或“接收方”,并为“输出工具应用程序”设置一个值。否则,将“执行输出转换打开”设置为“无”。
  2. 识别序列管理器应简单发送到输出目标配置名称而不检查或转换它们的任何直通消息类型。
  3. 根据需要配置序列管理器的其他设置。

以编程方式访问 HL7 序列数据

可以通过 SQL 访问序列管理器的运行时数据。为此,请对表 EnsLib_HL7.SM.RuntimeData.Thread 执行查询。该表提供以下字符串字段:

Application

发送或接收应用程序的名称,取自 HL7 消息。

Facility

发送或接收设施的名称,取自 HL7 消息。

Thread

以下字符串之一:

  • main
  • resend

Type

以下字符串之一:

  • Sender

  • Receiver

NextSequenceNumber

标识给定设施、应用程序、线程和类型的序列中的下一个编号。

示例 SQL 查询可能如下所示:

SELECT Application,Thread,Type,NextSequenceNumber FROM EnsLib_HL7.SM.RuntimeData.Thread WHERE Facility = 'mine'
0
0 112
InterSystems 官方 Claire Zheng · 八月 3, 2023

InterSystems 已纠正了两个缺陷。

第一个缺陷可能导致 ECP 应用程序服务器挂起。此缺陷仅与 ARM 和 IBM Power 处理器相关;存在于 InterSystems IRIS®、InterSystems IRIS for Health™ 和 HealthShare® Health Connect 版本2022.1.22022.1.3中。该修复被标识为 DP-423661。该缺陷将在所有未来版本中得到解决。

在极少数情况下,第二个缺陷可能会导致dejournaling挂起。此缺陷存在于 InterSystems IRIS®、InterSystems IRIS for Health™ 和 HealthShare® Health Connect 版本2020.42021.x2022.x2023.1中。该修复被标识为 DP-423505。该缺陷将在所有未来版本中得到解决,并已在2023.1.1中得到纠正。

InterSystems 已发布版本2022.1.3的更新发行版,以便快速提供这些修复。相关的版本标识符是:

  • 原发布:2022.1.3.668.0
  • 更新发布:2022.1.3.670.1

这些修复也可以通过 Ad hoc 分发获得。

如果您对此警报有任何疑问,请联系 全球响应中心

0
0 117
文章 姚 鑫 · 八月 3, 2023 3m read

第十一章 配置Production - 集成和配置 HL7 业务服务

集成和配置 HL7 业务服务

要将新的 HL7 业务服务集成到production中,必须将其与其中继消息的路由流程或业务操作相关联。此外,如果希望业务服务接收非标准消息结构,将需要创建自定义 HL7 架构定义来解析和验证这些消息。去做这个:

  1. 完成创建 HL7 业务服务所需的任何目标配置名称或消息架构类别项的说明。这些项目可能是:
  • HL7 路由进程(针对路由接口)。请参阅下一节。
  • HL7 业务操作(如果设计绕过此接口的路由过程,只是将消息从传入业务服务中继到传出业务操作)。请参阅本章后面的“添加 HL7 业务操作”。
  • 自定义 HL7 架构定义,用于解析传入的 HL7 消息。
  1. 返回生产配置页面上的图表。选择新的 HL7 业务服务。如果“目标配置名称”和“消息架构类别”字段之前为空,请立即配置它们,然后单击“应用”。
  2. 根据需要配置业务服务的其他设置。详细信息请参见“参考”中的“HL7业务服务设置”。

添加 HL7 路由进程

要将 HL7 路由流程添加到production中,必须创建它,将其集成到产品中,并根据需要对其进行配置。以下小节提供了详细信息。

创建 HL7 路由流程

要将 HL7 路由流程添加到production

  1. 在管理门户的生产配置页面中显示生产(从主页选择互操作性 > 配置 > Production)。
  2. 在“进程”列中,单击“添加”按钮(加号)。
  3. 单击业务流程选项的HL7 Message Router;路由器类默认为EnsLib.HL7.MsgRouterRoutingengine
  4. 对于HL7 Router Name,键入此业务流程的名称。名称在业务流程中应该是唯一的。不要使用句号或空格。

默认值是此流程所基于的类的名称。

  1. 对于路由规则名称,执行以下操作之一:
  • 在“路由规则名称”下拉列表中选择已创建的路由规则。
  • 选择“自动创建规则”,在“路由规则名称”中输入规则名称。在这种情况下,向导在与产品相同的包中创建路由规则类。
  1. 单击OK。

集成和配置HL7路由过程

要将新的HL7路由流程集成到production中,必须将其与接收其传入消息的业务服务以及根据这些消息确定其操作的路由规则集关联起来。要做到这一点:

  1. 选择HL7业务服务。在屏幕右侧的菜单中,单击“设置”页签,打开“基本设置”菜单。在Target Config Names字段中,输入新的HL7路由进程的名称。
  2. 创建路由规则集。在配置图中选择路由过程。在“业务规则名称”字段中,输入新路由规则集的全名。
  3. 根据需要配置路由过程的其他设置。具体操作请参见参考资料中的“HL7路由进程设置”。
0
0 122
文章 姚 鑫 · 八月 2, 2023 3m read

第十章 配置Production

本章介绍如何配置产品以包含 HL7 路由接口。它还描述了如何创建新的 HL7 路由制作。

创建新的 HL7 路由Produtcion

可以创建一个新的HL7路由产品,如下所示:

  1. Management Portal中,切换到适当的名称空间。

为此,请在标题栏中选择Switch,单击名称空间,然后单击OK

  1. 选择互操作性>列表>产品。
  2. 选择New以调用Production Wizard
  3. 输入“Package Name”“Production Name”“Description”
  4. 选择HL7 Messaging production类型并选择OK

starter production有一个接口,其元素为:

  • HL7FileService — 一个禁用的HL7文件服务,具有默认设置
  • MsgRouterHL7路由进程,带有空路由规则集
  • HL7FileOperation - 一个禁用的HL7文件操作,具有默认设置

在构建HL7路由产品时,需要创建和配置许多这样的接口。可以从启用这些起始元素、复制它们、重命名它们并修改它们以满足需要开始。在构建接口时,经常会出现这样的情况:在配置一个项目时,必须输入尚未创建的另一个项目的名称。明确的命名约定对于避免混淆至关重要。

除了接口元素之外,starter产品还提供了几个元素,它们不路由HL7消息,但为产品提供支持功能:

  • Bad Message Handler坏消息处理程序——用于验证失败的消息的内置目的地。
  • Ens.Alert警报——一个路由流程,带有路由规则集,可以配置该路由规则集,将警报消息路由到不同的电子邮件业务操作,这取决于警报的来源(即哪个元素出了问题)和各种条件(例如一天中的时间),以适应公司日程安排和过程。
  • PagerAlertEmailAlert——电子邮件业务操作,可以配置为发送文本消息(如警报)到寻呼机或电子邮件地址。

添加HL7业务服务

向产品中添加HL7业务服务:

  1. Management Portal“production Configuration”页面(在“Home”页面选择“Interoperability > Configure > production”)中显示生产结果。
  2. Services列中,单击Add按钮(加号)。
  3. 单击HL7 Input选项卡。
  4. 从输入类型列表中单击下列其中一个:
  • TCP
  • File
  • FTP
  • HTTP
  • SOAP

此选项为业务服务选择主机类。

  1. 对于HL7 Service Name,键入此业务服务的名称。名称在业务服务中应该是唯一的。不要使用句号或空格。

默认值是此服务所基于的类的名称。

  1. 于HL7 Service Target,请选择以下选项之一:
  • Create New Router创建新路由器——将一个路由流程添加到产品中,并配置业务服务以使用该流程作为目标。稍后可以编辑详细信息。
  • None for Now—未为此业务服务指定目标。
  • 从列表中选择—在这种情况下,还可以从下拉列表中选择一个现有的业务主机。
  1. 单击OK。

除了此处使用的 HL7 业务服务之外, 还提供两个简单的业务服务:EnsLib.File.PassthroughServiceEnsLib.FTP.PassthroughService。如果只需要通过生产传递文件,并且不想将文件解析或格式化为 HL7,则可以选择其中任何一个。

0
0 164
文章 Kelly Huang · 八月 2, 2023 18m read

这是一个使用 IKO 在 k3d 上部署  iris-oauth-fhir  的示例。

*  iris-oauth-fhir 是一个示例,用于部署带有 OAuth2 身份验证功能的 FHIR 服务器,InterSystems IRIS for Health 作为资源服务器,Google OpenId 则作为授权服务器。

* k3d 作为一个轻量级封装器,用于在 docker 中运行 k3s (Rancher Lab 的最小 Kubernetes 发行版)

IKO 是一个在 Kubernetes 上部署 InterSystems IRIS for Health 的工具。

2. 目录表

0
0 151
文章 姚 鑫 · 七月 31, 2023 2m read

第八章 HL7 架构和可用工具 - 测试转换

显示段地址

要显示段地址,请将光标悬停在阴影列中的段名称上。工具提示显示以下内容:

  • 在虚拟属性路径中使用的段地址
  • 该段的描述性名称

显示字段地址

要显示字段地址,请将光标悬停在消息结构中的字段上。工具提示显示以下内容:

  • 在虚拟属性路径中使用的字段地址(作为数字)
  • 在虚拟属性路径中使用的字段地址(作为名称)
  • 指示该字段的语法规则的字符。字符可以这样开头:
SymbolMeaning
!(仅限 1) 该字段为必填项;它必须只发生一次。
?01)该字段是可选的,但如果出现,则可能只出现一次。
+1 次或多次)该字段可以重复一次或多次。
*0 次或多次)该字段可以重复零次或多次。
&该字段可能存在,并且可能重复,但仅在某些条件下。
n*(0n) 该字段最多重复 n 次。
(m)m 是字段中的最大字符数。该字段的每次重复都可以包含此数量的字符。

批量消息

如果字段用尖括号 (<,>) 括起来,则它是指向子文档的链接。单击它可查看该文档的摘要报告和消息数据。

测试转换

要测试转换:

  1. 单击转换文档?。
  2. 对于选择数据转换,选择数据转换。
  3. 对于选择显示选项,请选择以下选项之一:
    • 仅转换结果 — 仅显示转换后的文档。
    • 原始消息和结果一起显示 - 同时显示原始文档和转换后的文档。
  4. 现在执行以下一项或两项操作:
    • 单击“确定”以显示转换后的文档。
    • 单击将结果保存到文件吗?将转换后的文档保存到文件中。在这种情况下,还要指定路径和文件名。

默认目录是活动命名空间的管理目录。例如,如果将 IRIS 安装到目录 C:\MyIRIS 并且当前命名空间为 MyNamespace,则该文件将保存为 C:\MyIRIS\Mgr\MyNamespace\filename

0
0 116
文章 Lilian Huang · 七月 31, 2023 2m read

FHIR® SQL Builder或 Builder 是 InterSystems IRIS 医疗版数据平台 的一个组件。它是一种复杂的投射工具,用于将 InterSystems IRIS  医疗版数据平台FHIR 存储库中的数据创建为自定义的 SQL 模式,而无需将数据移动到单独的 SQL 存储库中。 Builder 专门设计用于与 InterSystems IRIS 医疗版数据平台中的 FHIR 存储库和多模型数据库配合使用。

Builder 的目标是使数据分析师和商业智能开发人员能够使用熟悉的SQL分析工具使用 FHIR,而无需学习新的查询语法。 FHIR 数据以复杂的有向图编码,无法使用标准 SQL 语法进行查询。基于图的查询语言 FHIRPath 旨在查询 FHIR 数据,但它是非关系型的。 Builder 使数据管理员能够使用表、列和索引创建其 FHIR 存储库的自定义 SQL 来投射,使数据分析师能够查询 FHIR 数据,而无需学习 FHIRPath 或 FHIR 搜索语法的复杂性。
存储库将加载 FHIR 资源,您所需要做的就是配置 FHIR SQL BUILDER。
对于配置,导航到http://localhost:55037/csp/fhirsql/index.csp# /

有关如何进行配置的更多详细信息,请观看此教程视频

0
0 231