搜索​​​​

清除过滤器
文章
姚 鑫 · 五月 2, 2021

第一章 简介global

# 第一章 简介global InterSystems IRIS®的核心功能之一是其多维存储引擎。此功能允许应用程序以紧凑、高效的多维稀疏数组存储数据。这些数组称为全局数组。 本章介绍: - 什么是全局变量(`globals` ),以及可以对其执行的操作。 - 全局变量的逻辑和物理结构,包括在分布式数据库体系结构中使用全局变量。 - 如何使用全局变量在应用程序中存储和检索数据。 - 如何使用全局变量。 # 特点 全局变量提供了一种在持久的多维数组中存储数据的易于使用的方法。 例如,可以使用名为`^Settings`的全局变量将值`“Red”`与键`“Color”`相关联: ```java SET ^Settings("Color")="Red" ``` 可以利用全局变量的多维特性来定义更复杂的结构: ```java SET ^Settings("Auto1","Properties","Color") = "Red" SET ^Settings("Auto1","Properties","Model") = "SUV" SET ^Settings("Auto2","Owner") = "Mo" SET ^Settings("Auto2","Properties","Color") = "Green" ``` 全局变量具有以下功能: - 简单易用-全局变量和其他编程语言变量一样易于使用。 - 多维-可以使用任意数量的下标指定全局内节点的地址。 例如,在 `^Settings("Auto2","Properties","Color")`中,下标`Color`是全局设置中的第三级节点。 下标可以是整数、数字或字符串值,并且不需要是连续的。 - 稀疏-用于寻址全局节点的下标高度压缩,不需要连续的值。 - 高效-全局变量上的操作(插入、更新、删除、遍历和检索)都经过高度优化,可实现最高性能和并发性。还有用于特殊操作(如批量插入数据)的其他命令。有一组特殊的全局变量是为临时数据结构设计的(例如,用于对记录进行排序)。 - 可靠-InterSystems IRIS数据库提供了许多机制来确保存储在全局数据库中的数据的可靠性,包括逻辑级和物理级日志记录。执行数据库备份操作时,将备份存储在全局数据库中的数据。 - 分布式IRIS提供了多种方法来控制存储在全局数据库中的数据的物理位置。可以定义用于存储全局的物理数据库,或将全局的部分分布到多个数据库中。使用InterSystems IRIS的分布式数据库功能,可以在数据库和应用程序服务器系统网络中共享全局数据。此外,通过镜像技术,存储在一个系统上的全局数据库中的数据可以自动复制到另一个系统上。 - **并发-全局支持多个进程之间的并发访问。在单个节点(数组元素)中设置和检索值始终是原子的:不需要锁定即可保证可靠的并发访问。此外,InterSystems IRIS支持一组强大的锁定操作,可用于为涉及多个节点的更复杂情况提供并发性。使用对象或SQL访问时,会自动处理此并发。** - **事务性-InterSystems IRIS提供定义事务边界的命令;可以启动、提交或回滚事务。在回滚的情况下,事务内对全局变量所做的所有修改都将被撤消;数据库的内容将恢复到事务前的状态。通过将各种InterSystems IRIS锁定操作与事务结合使用,可以使用全局变量执行传统的`ACID`事务。(`ACID`事务提供原子性、一致性、隔离性和持久性。)。使用对象或SQL访问时,事务会自动处理。** 注意:本文档中描述的全局变量不应与另一种类型的InterSystems IRIS数组变量混淆:进程私有全局变量。进程私有全局变量不是持久的;它们仅在创建它们程序期间持续。进程私有全局变量也不是并发的;它们只能由创建它们的进程访问。进程专用全局可以通过其多字符名称前缀:`^||`或`^|"^"|`轻松地与全局区分开来。 # 例如 一个简单的例子就可以展示全局变量的易用性和性能。下面的程序示例创建一个`10,000`个节点的数组(如果存在,则首先将其删除)并将其存储在数据库中。可以尝试这样做,以了解全局变量的性能: ```java /// w ##class(PHA.TEST.Global).GlobalSimple() ClassMethod GlobalSimple() { Set start = $ZH // get current time Kill ^Test.Global For i = 1:1:10000 { Set ^Test.Global(i) = i } Set elap = $ZH - start // get elapsed time Write "Time (seconds): ",elap q "" } ``` ```java DHC-APP> w ##class(PHA.TEST.Global).GlobalSimple() Time (seconds): .00307 ``` 我们还可以看到迭代和读取数组中的值需要多长时间(确保首先运行上面的示例来构建数组): -读取持久数组- ```java /// w ##class(PHA.TEST.Global).ReadGlobalSimple() ClassMethod ReadGlobalSimple() { Set start = $ZH // get current time Set total = 0 Set count = 0 // get key and value for first node Set i = $Order(^Test.Global(""),1,data) While (i '= "") { Set count = count + 1 Set total = total + data // get key and value for next node Set i = $Order(^Test.Global(i),1,data) } Set elap = $ZH - start // get elapsed time Write "Nodes: ",count,! Write "Total: ",total,! Write "Time (seconds): ",elap,! q "" } ``` ```java DHC-APP>w ##class(PHA.TEST.Global).ReadGlobalSimple() Nodes: 10000 Total: 50005000 Time (seconds): .001879 ``` # 在应用程序中使用 在InterSystems IRIS应用程序中,全局变量有多种使用方式,包括: - 作为对象和SQL引擎共享的底层存储机制。 - 作为用于为对象和SQL数据提供各种索引(包括位图索引)的机制。 - 作为用于执行不适合进程存储器的某些操作的工作空间。例如,当没有预先存在的索引可用于排序数据时,SQL引擎使用临时全局变量对数据进行排序。 - 用于在对象或SQL访问方面难以表达或效率低下的持久性对象或SQL表上执行专用操作。例如,可以定义一个方法(或存储过程或Web方法)来对表中保存的数据执行专门的分析。通过使用方法,这样的操作是完全封装的;调用者只需调用该方法。 - 实现特定于应用程序的自定义存储结构。许多应用程序需要存储难以用关系表示的数据。使用全局变量,可以定义自定义结构,并通过对象方法将其提供给外部客户端。 - 用于InterSystems IRIS系统使用的各种特殊用途的数据结构,例如配置数据、类定义、错误消息和可执行代码。 全局变量不受关系模型的限制。 它们提供了开发针对特定应用程序优化的定制结构的自由。 对于许多应用程序来说,明智地使用全局变量可能是提供性能的秘密武器,而这种性能是关系应用程序开发人员梦寐以求的。 无论应用程序是否直接使用全局变量,了解它们的操作都是有用的。 理解全局及其功能将帮助设计更高效的应用程序,并为确定应用程序的最佳部署配置提供帮助。
文章
Louis Lu · 一月 7, 2021

创建“虚拟”的SOAP Web 服务

在 Caché 中处理 SOAP 请求时,有时需要通过直接访问(有时是编辑)所发送的 XML(即 SOAP 请求和随后的 SOAP 响应)来调试错误。 如果要调试 Caché Web 服务,使用 SoapUI (https://www.soapui.org/) 之类的工具手动创建和控制 SOAP 请求通常很有用,这样可以很容易地在 Caché Web 服务上看到调整的效果。 但是如果已经有 Web 服务(可能不是 Caché),并且想要调试相关的 Caché Web 客户端该怎么办? 您可能已将 SOAP 响应 XML 保存在文件中(例如 Caché SOAP 日志),您需要一个“虚拟”Web 服务将其发送到 Caché Web 客户端,就像实际的 Web 服务一样操作。 由于我经常在技术支持的过程中需要调试客户的 Caché Web 客户端,我创建了这样一个“虚拟”的Web 服务 – 见下文: Class JSUtil.DummyWebService Extends %CSP.Page { /// Mimic a SOAP Web Service by sending the specified SOAP Response XML. /// Typically this XML will be copied-and-pasted from a SOAP log. Parameter CONTENTTYPE = "text/xml"; /// File containing the SOAP Response XML: Parameter XMLFILENAME = "C:\data\soapresponse.txt"; ClassMethod OnPage() As %Status { set XML="" set stream = ##class(%Stream.FileCharacter).%New() set sc = stream.LinkToFile(..#XMLFILENAME) while 'stream.AtEnd { set XML = XML_stream.Read() } write XML quit $$$OK } } 要使用 JSUtil.DummyWebService 类: 1.将参数 XMLFILENAME 的值更改为包含来自 Web 服务的 SOAP 响应的 XML 的位置。 通常,此文件可内容可通过手动剪切和粘贴 Caché SOAP 日志中的响应 XML 消息来创建。 2.使用 Studio 的“View Web Page”获取此 CSP 页面的 URL,它应显示响应的XML消息内容。 3.将上面的 URL 粘贴到 Caché Web 客户端的 LOCATION 参数中。 现在,当调用 Caché Web 客户端时,它将收到参数 XMLFILENAME 指向的 SOAP 请求 XML。 我已经多次使用这种方法来帮助调试 Caché Web 客户端。 参考以下示例: SOAP 日志的“Web 客户端的输入”中包含以下错误: ERROR #6203: Unexpected Element (完整的 SOAP 日志可在此处找到:[_https://github.com/ISC-schulman/InterSystems/raw/master/soaplog.txt_](https://github.com/ISC-schulman/InterSystems/raw/master/soaplog.txt)) 我们还有 Web 服务的 WSDL ([_https://github.com/ISC-schulman/InterSystems/raw/master/example.wsdl_](https://github.com/ISC-schulman/InterSystems/raw/master/example.wsdl)),但无法访问 Web 服务本身。 (虽然这对于 InterSystems 支持来说很常见,但不可否认,对于客户可能并不常见 – 这只是一个简单的示例,说明如何使用 DummyWebService。) 首先,使用 DummyWebService 重现错误: 1.使用 SOAP 向导从提供的 WSDL 生成 Web 客户端。 所有参数均使用默认值(尽管您可以指定包名称。) 2.查看 SOAP 日志,然后将 Web 服务响应的XML(“Input to Web client”)剪切并粘贴到文件中: OK   3.通过 JSUtil.DummyWebService 中的参数 XMLFILENAME 指向此文件。 4.使用 Studio 的“Display Web Page”查看 DummyWebService – 它应显示步骤 2 中创建的文件内容。 5.将步骤 4 中的 URL 剪切并粘贴到步骤 1 中生成的 Web 客户端的 LOCATION 参数中。 6.调用 Web 客户端,例如  set client = ##class(MyWebService.RequestWSSoapHttpPort).%New()  do client.createAsynchronuosRequest("x") quit 7. 验证(例如通过 SOAP 日志)是否发生相同错误,即“ERROR #6203: Unexpected Element”。   接下来我们解决这个错误。 这里会经历一些过程或反复试验,但同样只是为了说明如何使用 DummyWebService。 1.像之前一样使用 SOAP 向导和提供的 WSDL 生成 Web 客户端 – 指定不同的包名称以防止覆盖第一个 Web 客户端。 另外,参数全部采用默认值,除了一处: 在 SOAP 向导的步骤 3 中选择“对于文档样式的 Web 方法使用未包装的消息格式(Use unwrapped message format for document style web methods)” 2.重复上面的步骤 5 和 6。 3.验证(例如通过 SOAP 日志)Web 客户端错误是否已修正。 _(注意:使用“未包装的消息格式(unwrapped message format)”是解决 Web 客户端问题的常见解决方案 – 有关详细信息,请参见我们的文档中的“使用 SOAP 向导_”。)   **总结** 可以使用 DummyWebService 类将指定的 SOAP 响应(例如,从 SOAP 日志)发送到 Caché Web 客户端,以模拟 Web 服务的响应。
文章
姚 鑫 · 三月 5, 2021

第四章 SQL标识符

# 第四章 标识符 # 标识符 标识符是SQL实体的名称,例如表、视图、列(字段)、模式、表别名、列别名、索引、存储过程、触发器或其他SQL实体。 标识符名称在其上下文中必须是唯一的; 例如,同一模式中的两个表或同一表中的两个字段不能具有相同的名称。 但是,不同模式中的两个表或不同表中的两个字段可以具有相同的名称。 在大多数情况下,相同的标识符名称可以用于不同类型的SQL实体; 例如,一个模式、该模式中的表以及该表中的字段都可以具有相同的名称,而不会产生冲突。 但是,同一个模式中的表和视图不能具有相同的名称。 InterSystems IRIS®数据平台SQL标识符遵循一组命名约定,根据标识符的使用,这可能会受到进一步的限制。 标识符不区分大小写。 标识符可以是简单标识符,也可以是分隔符。 InterSystems SQL默认支持简单标识符和分隔标识符。 # 简单标识符 简单标识符有以下语法: ``` simple-identifier ::= identifier-start { identifier-part } identifier-start ::= letter | % | _ identifier-part ::= letter | number | _ | @ | # | $ ``` ## 命名约定 标识符`start`是SQL标识符的第一个字符。 它必须是下列之一: - 大写或小写字母。 字母定义为通过ObjectScript `$ZNAME`函数验证的任何字符; 默认情况下,这些字母是大写字母A到Z (ASCII 65-90),小写字母a到z (ASCII 97-122),以及带有重音标记的字母(ASCII 192-255,不包括ASCII 215和247)。 InterSystems IRIS可以在SQL标识符中使用任何有效的Unicode(16位)字母字符。 简单的标识符是不区分大小写的(不过,请参见下面的内容)。 按照惯例,它们用首字母大写来表示。 日语区域设置不支持标识符中的重音拉丁字母字符。 日语标识符可能包含(除了日语字符之外)拉丁字母字符A-Z和a-z(65-90和97-122),以及希腊大写字母字符(913-929和931-937)。 - 一个下划线(`_`)。 - 百分号(`%`)。InterSystems IRIS以%字符开头的名称(以`%Z`或`%z`开头的除外)保留为系统元素,不应用作标识符。 标识符部分是SQL标识符的任何后续字符。这些剩余字符可能由零个或多个字符组成: - 字母(包括Unicode字符)。 - 数字。数字被定义为数字0到9。 - 下划线(`_`)。 - At标志(`@`)。 - 井号(`#`)。 - 美元符号(`$`)。 一些符号字符也用作运算符。**在SQL中,`#`符号用作模运算符。在SQL中,下划线字符可以用来连接两个字符串;提供这种用法是为了与ObjectScript兼容,首选的SQL串联运算符是`||`。** 将符号解释为标识符字符总是优先于将其解释为运算符。任何关于符号字符作为运算符的正确解析的歧义都可以通过在运算符前后添加空格来解决。 简单标识符不能包含空格或非字母数字字符(上面指定的符号字符除外)。系统间SQL导入工具从导入的表名中删除空格。 注意:SQL游标名称不遵循标识符命名约定。 InterSystems SQL包含不能用作简单标识符的保留字。 有关这些保留词的列表, 要测试一个单词是否是保留单词,请使用`$SYSTEM.SQL.IsReservedWord()`方法。 但是,带分隔符的标识符可以与SQL保留字相同。 任何不遵循这些命名约定的标识符都必须在SQL语句中表示为带分隔符的标识符。 ## 字母 **默认情况下,InterSystems SQL标识符不区分大小写。 InterSystems SQL通过将标识符转换为所有大写字母后比较它们来实现这一点。** 这对名称的实际使用情况没有影响。 (注意,SQL的其他实现可能会以不同的方式处理标识符的大小写敏感性。 因此,建议避免使用基于案例的标识符。) **请注意,系统间SQL中的游标名称和密码是区分大小写的。** ## 测试有效标识符 InterSystems IRIS提供了`%SYSTEM.SQL`的`IsValidRegularIdentifier()`方法。它测试字符串是否是有效的标识符。它测试字符用法和保留字。它还执行200个字符的最大长度测试(这是用于避免错误输入的任意长度;这不是标识符验证)。以下对象脚本示例显示了此方法的使用: ```java /// d ##class(PHA.TEST.SQL).Identifiers() ClassMethod Identifiers() { WRITE !,$SYSTEM.SQL.IsValidRegularIdentifier("Fred") WRITE !,$SYSTEM.SQL.IsValidRegularIdentifier("%Fred#123") WRITE !,$SYSTEM.SQL.IsValidRegularIdentifier("%#$@_Fred") WRITE !,$SYSTEM.SQL.IsValidRegularIdentifier("_1Fred") WRITE !,$SYSTEM.SQL.IsValidRegularIdentifier("%#$") WRITE !,$SYSTEM.SQL.IsValidRegularIdentifier("1Fred") WRITE !,$SYSTEM.SQL.IsValidRegularIdentifier("Fr ed") WRITE !,$SYSTEM.SQL.IsValidRegularIdentifier("%sqlupper") } ``` ```java DHC-APP>d ##class(PHA.TEST.SQL).Identifiers() 1 1 1 1 1 0 0 0 ``` 前三个方法调用返回1,表示有效的标识符。第四个和第五个方法调用也返回1;这些是有效的标识符,尽管它们不能用作表名或字段名。最后三个方法调用返回0,表示标识符无效。其中两个是无效的,因为它们违反了字符规则——在这些情况下是以数字开头或包含空格。最后一次方法调用返回0,因为指定的字符串是保留字。请注意,这些规则测试是最低要求;它们不能证明标识符对所有的SQL使用都有效。 这个方法也可以作为存储过程从ODBC或JDBC调用:`%SYSTEM.SQL_IsValidRegularIdentifier("nnnn")`。 ## 名称空间的名字 命名空间名称(也称为数据库名称)遵循标识符命名约定,并对标点字符和最大长度有额外的限制。 命名空间名称可以作为带分隔符的标识符,并且可以与SQL保留字相同。 但是,相同的命名空间名称标点限制适用于简单标识符和分隔标识符。 ## 标识符和类实体名称 通过去除非字母数字字符,SQL表名、视图名、字段名、索引名、触发器名和过程名用于生成相应的持久类实体。 生成的类实体和全局变量的名称遵循这些规则。 注意:命名空间名称和SQL模式名称以及相应的包名称不遵循这些规则。 - 仅在包含标点字符方面不同的标识符是有效的。 因为类对象名称不能包含标点字符,InterSystems IRIS通过去掉所有标点字符来生成相应的唯一对象名称。 如果去掉标识符的标点字符会导致非唯一的类对象名称,InterSystems IRIS将最后一个字母数字字符替换为一个递增的字符后缀,从而创建一个唯一的名称。 对于表、视图、字段、触发器和过程类方法名,这是一个以0开头的整数后缀。 例如,`myname`和`my_name`生成`myname`和`mynam0`,添加我的`#name`生成`mynam1`。 如果生成的惟一名称的数量大于10 (`mynam9`),则通过替换以(`mynamA`)开头的大写字母后缀生成额外的名称。 因为表和视图共享相同的名称空间,所以表或视图的后缀计数器都是递增的。 对于索引名,这个后缀是一个大写字母,以`a`开头。例如,`myindex`和`my_index`生成`myindex`和`myindeA`。 如果定义了一个以后缀字符结束的名称(例如`my_name0`或`my_index`), InterSystems IRIS将通过递增到下一个未使用的后缀来处理惟一名称的生成。 - 第一个字符为标点字符,第二个字符为数字的标识符对于表名、视图名或过程名无效。 它们对字段名和索引名有效。 如果SQL字段名或索引名的第一个字符是标点字符(`%`或`_`),第二个字符是数字,InterSystems IRIS将追加小写的`“n”`作为相应属性名的第一个字符。 - 完全由标点字符组成的标识符,或以两个下划线字符(`__name`)开头的标识符,或包含两个井号(`nn##nn`)的标识符作为SQL实体名称通常是无效的,应该在所有上下文中避免使用。 可以将SQL标识符中的特定字符转换为相应对象标识符中的其他字符。 在允许的标识符字符规则不同的环境中,这有助于标识符的使用。 使用 `%SYSTEM.SQL`的`SetDDLIdentifierTranslations()`方法。 要确定当前设置,调用`$SYSTEM.SQL.CurrentSettings()`。 在DDL运行时将SQL标识符转换为对象标识符时,“From”字符串中的字符被转换为“to”字符串中的字符。 ### 在类定义中指定SQL名称 定义投射SQL实体的持久化类时,每个SQL实体的名称与其对应的持久化类定义元素的名称相同。 要使SQL表、字段或索引名称不同,可以使用`SqlTableName`、`SqlFieldName`或`SqlName`(对于索引)关键字在类定义中指定SQL名称。 例如: ``` Property LName As %String [SqlFieldName = "Family#Name"]; ``` ``` Index NameIdx As %String [SqlName = "FullNameIndex"]; ``` ## 标识符长度注意事项 **SQL标识符的最大长度为128个字符。当InterSystems IRIS将SQL标识符映射到相应的对象实体时,它会创建最多96个字符的相应属性、方法、查询或索引名称。如果前96个字符的两个SQL标识符相同,InterSystems IRIS会将相应对象名称的第96个字符替换为整数(从0开始)以创建唯一名称。** # 分隔标识符 分隔标识符的语法如下: ```java delimited-identifier ::= " delimited-identifier-part { delimited-identifier-part } " delimited-identifier-part ::= non-double-quote-character | double-quote-symbol double-quote-symbol ::= "" ``` 带分隔符的标识符是由分隔符字符括起来的唯一标识符。InterSystems SQL支持双引号(`“`)作为分隔符,分隔符一般用于避免简单标识符的命名限制。 请注意,InterSystems SQL使用单引号字符(`‘`)来分隔文字。因此,必须使用双引号字符(`“`)指定分隔标识符,必须使用单引号字符(`‘`)指定文字。例如,`’7‘`是数字文字`7`,但`”7“`是分隔标识符。当SQL语句用双引号括起来时(例如,在动态SQL中),该字符串中的双引号字符必须是双引号。 **SQL空字符串应始终指定为一对单引号字符`‘’`。启用分隔标识符支持时,一对双引号字符`“”`将被解析为无效的分隔标识符,并生成`SQLCODE-1`错误。** ## 分隔标识符有效名称 分隔的标识符必须是唯一的名称。带分隔符的标识符不区分大小写;按照惯例,标识符用首字母大写表示。 分隔标识符可以与SQL保留字相同。分隔标识符通常用于避免与SQL保留字的命名冲突。 分隔标识符几乎可以包含任何可打印字符,包括空格。大多数分隔的标识符名称不能包含以下字符:逗号(`,`)、句点(`.`)、插入符号(`^`)和两个字符的箭头序列(`->`);但是分隔的标识符角色名称和用户名可以包含这些字符。分隔的标识符类名可以包含句点(`.`)。任何分隔的标识符都不能以星号(`*`)开头。以下术语不能用作分隔标识符:`%vid`。违反这些命名约定会导致`SQLCODE-1`错误。 用作表、架构、列或索引名的分隔标识符必须能够转换为有效的类实体名称。因此,它必须至少包含一个字母数字字符。以数字(或标点符号后跟数字)开头的分隔标识符会生成带有字母`“n”`前缀的相应类实体名称。 以下示例显示了对列名和表名使用分隔标识符的查询: ```java SELECT "My Field" FROM "My Table" WHERE "My Field" LIKE 'A%' ``` 为表名指定分隔标识符时,必须分别分隔表名和架构名。因此,`“schema”`。`“tablename”`或`schema`。`“tablename”`是有效的标识符,但是`“schema.tablename”`不是有效的标识符。 ## 禁用分隔标识符支持 默认情况下,启用对定界标识符的支持。 禁用分隔标识符支持时,双引号内的字符将被视为字符串文字。 可以使用带有`SUPPORT_DELIMITED_IDENTIFIERS`关键字的`SET OPTION`命令在系统范围内设置分隔标识符支持。 可以使用`%SYSTEM.SQL`类的`SetDelimitedIdentifiers()`方法在系统范围内设置分隔标识符支持。 若要确定当前设置,请调用`$SYSTEM.SQL.CurrentSettings()`。 # SQL保留字 SQL包含一长串不能用作标识符的保留字。 实用性很高的文章,👍
文章
Jingwei Wang · 九月 22, 2021

IRIS 2021 技术文档 First Look 6 使用具有互操作性的Production连接系统

为什么要连接系统? 连接系统可以让一个系统处理来自非本系统的信息。例如,以下场景需要连接系统: 为了提高效率,最初设计为执行单一功能的系统需要集成。例如,您可以通过集成跟踪库存、订购材料、记录销售和控制运输的各个系统来提高效率。 系统合并后,在不同机构中执行相同功能的系统需要协同工作才能使统一的机构有效。 将系统连接在一起时,您可能会面临一些挑战,例如: 不同系统使用不同的通信协议:一个系统可能使用TCP,另一个系统使用SOAP,第三个系统使用REST。 不同系统使用不同格式或基于不同标准的不同消息。 需要保证消息成功传递到正确的系统,并能够检测和纠正故障。 必须监控传输消息的系统,如果一次消息过多,则为消息提供一个队列,并监控整体系统性能以确保没有任何障碍。 虽然可以编写自定义应用程序来连接系统,但开发一款InterSystems IRIS® 产品要容易得多,也快得多。 InterSystems IRIS 提供了一个框架,允许连接系统,并最大限度地减少或消除对自定义代码的需求。 Production介绍 InterSystems IRIS Production是一个集成框架,用于轻松连接系统和开发互操作性应用程序。产品Production提供包含各种消息格式和通信协议的内置连接。您可以轻松添加其他格式和协议,并通过编写代码或使用图形向导定义业务逻辑和消息转换。产品提供消息的持久存储,允许跟踪消息的路径并审核消息是否成功传递。一个Production由业务服务(BS)、业务流程(BP)和业务操作(BO)组成: 业务服务(BS)与外部系统连接并接收Production来自外部系统的消息。 业务流程(BP)允许您定义业务逻辑,包括路由和消息转换。 业务操作(BO)与外部系统连接并将消息发送给它们。 将系统连接在一起时,让所有系统互相理解它们的消息和文档是有挑战性的。例如,思考以下问题: 您有两个独立的系统:一个是从多个联网设备采集数据,另一个是跟踪损坏的设备和维修进程的工单系统。 当前程序依赖于人工干预来监控设备并启动维修进程。这导致了拖延情况且不可靠。 您的任务是将两个系统连接在一起:监控正在收集的数据并自动启动修复进程。您知道如何检测数据收集系统中的故障设备并知道如何启动维修,尽管两个系统所存储的数据代表同一项目,但是两个系统的存储数据格式并不兼容。 您还需要记录数据收集系统启动维修时的操作。 可以使用InterSystems IRIS 产品解决这个问题。它提供了一个定义接口的框架,该接口接收来自数据采集系统的消息,将消息转换为维修系统可以理解的消息,然后将消息发送到维修系统。它还存储消息路径。 下面以一个简单的Production作为示例 出于演示目的,本文档中的Production使用文件适配器(file adapter)并将外部系统表示为文件。由于处理外部系统的大部分工作是由InterSystems IRIS 提供的适配器完成的,因此开发一款可以连接到含有 REST、TCP、SOAP 或HTTP 的外部系统的Production的过程与使用文件适配器开发产品非常相似。 使用文件适配器(File Adaptor)创建Production 在本节中,您将使用入站文件适配器和出站文件适配器创建Production。可以使用 InterSystems IRIS 中内置的业务服务(BS)、业务流程(BP)和业务操作(BO),因此您无需下载任何代码。 尝试一下!使用文件适配器创建产品 想要尝试一下InterSystems IRIS 互操作性功能的在线视频演示吗?查看互操作行快速入门! 用前须知 要使用该程序,您需要一个正在运行的InterSystems IRIS 实例。您的选择包括多种类型的已授权的和免费的评估实例;该实例不需要由您正在工作的系统托管(尽管它们必须相互具有网络访问权限)。如果您还没有一个可以使用的实例,如何部署每种类型实例的有关信息,请参阅InterSystems IRIS Basics: Connecting an IDE中的部署 InterSystems IRIS。 关于如何用Visual Studio 连接到您的InterSystems IRIS 实例,请参考InterSystems IRIS 连接信息和.Net IDEs。 创建支持互操作的命名空间(Namespace) 为了创建一个production,必须有支持互操作的命名空间。如果您已经创建了启用互操作的命名空间, 则可以将其用于该production。要创建新的支持互操作的命名空间,请遵照以下流程(首次安装InterSystems IRIS 时 创建的命名空间不支持互操作): 在浏览器中为实例打开Management Portal (管理门户)。 选择系统管理 > 配置 > 系统配置 > 命名空间,进入命名空间页面。 在命名空间页面,选择新建命名空间 ;根据系统配置指南中“配置InterSystems IRIS”一章中,对于“Create/Modify a Namespace(创建/修改命名空间)”说明,确保选中 Enable namespace for interoperability productions(为互操作性产品启用命名空间)复选框。 点击靠近页面顶部的保存按键,然后在结果日志的结尾选择关闭。 创建含有业务服务 (BS)和业务操作(BO)的简单production 在这一步中,您将: 创建一个新的production。 在该production中添加一项业务服务(BS)和两项业务操作(BO)。 配置业务服务(BS)和业务操作(BO)。 现在,您应该创建在托管InterSystems IRIS实例的系统上运行此production所需的四个目录。具体处理方法取决于所用的实例类型,如下所示: 对于ICM 部署的实例,使用带有-machine 和-interactive 选项的 icmexec命令,打开正在运行该实例的容器的bash shell ,例如: icm exec -command bash -machine MYIRIS-AM-TEST-0004 -interactive 然后,您可以在容器文件系统上创建目录。 对于任何容器化实例,无论是授权版还是社区版,请使用 docker exec -it container_name bash 命令打开该容器的bash shell (社区版的容器名称是try-iris )。然后在容器文件系统上创建4个目录 对于InterSystems Learning Labs(学习实验室),在集成IDE中使用命令行终端,在共享文件夹下创建新文件夹;您可以在/home/project/shared 路径下的Management Portal(管理门户)中浏览这些文件夹。 对于已安装的实例,在本地文件系统上创建4个目录。 本文本假定以下是Windows 系统上已安装实例的目录路径;替换您创建的实际目录的路径。 c:\Practice\In c:\Practice\Out c:\Practice\PDFsOut c:\Practice\Work 在管理门户中,创建一个新的production: 选择Interoperability( 互操作性),如果出现提示,请选择一个支持互操作的命名空间。 选择Interoperability ( 互操作性)> 列表 > Production。 如果一个产品当前正在命名空间中运行,请打开它,然后选择停止。返回产品列表页面。 选择新建,创建一个新的产品。 指定包名称(例如 TEST)和production名称(例如 FileProd)。您将创建可用于任何目的的通用production。选择OK创建该产品。 向该产品添加一项业务服务(BS)和两项业务操作(BO): 选择服务旁边的加号符号以显示业务服务向导。 在服务类下拉菜单,选择EnsLib.File.PassthroughService 。 指定服务名FileService。 清空立即启用复选框。 选择确定。 对两项业务操作(BO)重复这些步骤。从选择操作旁边的 加号符号以显示业务操作向导开始。对这两项操作使用 EnsLib.File.Pa ssthroughOperation 类。将一项操作名称命名为WriteFileOp ,另一项命名为WritePDFsOp。 配置这项业务服务(BS)和两项业务操作(BO): 选择您在产品配置图中创建的业务服务(BS),并在设置选项卡: a. 选择启用复选框。 在文件路径字段,输入c:\Practice\In。 在存档路径字段,输入c:\Practice\Work。 在工作路径字段,输入c:\Practice\Work。 在接收消息的目标名称字段,选择WriteFileOp。 其他字段为默认值。 选择应用。 为两项业务操作(BO)中的每一项指定设置。选择产品图中的操作,然后: a. 选择启用复选框。 在文件路径字段,对于 WriteFileOp 操作输入c:\Practice\Out,对于 WritePDFsOp 操作输入 c:\Practice\PDFsOut。 其他字段为默认值。 选择应用。 启动Production & 跟踪消息 启动该production后,您将复制一个文件到 FileService 的导入目录。您能查看 WriteFileOp 的导出目录中的文件,并通过该production跟踪消息。请注意,运行这个production时不使用WritePDFsOp 操作。要启动production并跟踪消息: 通过选择开始启动产品。 将任一文件复制到c:\Practice\In 目录。如果该产品配置正确,应该会出现以下情况: 几秒钟后,文件从 c:\Practice\In 目录移动到 c:\Practice\Work 目录。文件名称规范将后附时间戳。例如, 如果原始文件是hello.txt,工作文件可能名称为hello.txt_2018-05-07_17.24.57.056 。 文件的新版本被写入c:\Practice\Out 目录。它还附加了一个时间戳。 产品图中的圆圈应保持绿色。如果圆圈变成红色,则表示产品中存在错误。遍历前面的步骤并确保这些目录存在。 在production配置页面选择FileService,选择消息选项卡。它列出了通过该产品的每条消息。选择转到消息查看器。 在消息查看器中选择一条消息,然后选择跟踪选项卡。它将显示从FileService 转到WriteFileOp 操作的消息。 选择正文选项卡,它将显示消息类型和消息中的字段: 请注意,消息类型是Ens.StreamContainer,其中一个字段是OriginalFilename。 将路由器添加到Production中 在本步骤中,将向产品添加路由业务流程和规则。然后,您将一个文件复制到导入目录,并查看显示消息通过路由器的跟踪。在Management Portal(管理门户)中: 选择Interoperability( 互操作性) >配置>Production进入Production 配置 页面,然后选择流程旁边的加号符号以显示业务流程向导。在向导中: 在业务流程类下拉菜单,选择EnsLib.MsgRouter.RoutingEngine。 选择自动创建规则复选框。 指定业务流程名称为FileRouter。 清空Enabled( 启用)复选框。 选择确定。 在对话框中选择OK以批准规则类名称 在Production配置页面选择FileRouter,然后在设置选项卡: a. 选择启用复选框。 选择应用。 选择业务规则名称右侧的放大镜。这将启动规则编辑器,并显示在您创建业务流程时自动生成的规则。 在规则编辑器中,您将创建一条规则,将PDF 文件发送到WritePDFsOp 操作,并将所有其他文件发送到WriteFileOp 操作。规则如下所示 要创建此规则: 双击规则中的 constraint (约束)值。 在 源 字段输入FileService。 在消息类字段输入Ens.StreamContainer。 选择OK。 在 规则辅助中选择rule( 规则) 然后选择when。 选择 when 条件值,并在规则图上方的文本框内输入Document.OriginalFilename Contains ".pdf",然后选择确定。 选择图中的 when 子句,然后在规则辅助选择 send(发送)。 双击 target 值并选择WritePDFsOp 配置项。 选择图中的 when 子句,然后在规则辅助 选择 otherwise。 选择图中的 otherwise 子句,然后在规则辅助选择 send( 发送)。 双击 send 子句的 target 值并选择WriteFileOp 配置项。 选择保存。 返回到Production配置页面,选择FileService 并在 Settings 选项卡: 选择FileRouter 为接收消息的目标名称。 清空WriteFileOp 复选框。 然后选择应用。 您的productioin现已完成。FileService 将所有消息发送到FileRouter 业务流程(BP)。FileRouter 将根据规则将消息发送到WritePDFsOp 或WriteFileOp 操作。 如果你将hello.pdf 复制到c:\Practice\In 目录,它将被发送到 c:\Practice\PDFsOut 目录,但是,如果您复制test.txt 到c c:\Practice\In 目录,它将被发送到c:\Practice\Out 目录。您还可以查看消息跟踪,消息跟踪可以显示通过文件路由器的消息路径。例如,hello.pdf 的跟踪可能如下: 了解有关互操作性产品的更多信息 有关产品的更多信息,请参阅: 介绍互操作性production 开发产品production 配置production 制定业务规则
文章
Jingwei Wang · 六月 6, 2022

Object Script基础知识(六)

Object Script(六) 变量的类型 ObjectScript中的变量是没有类型的,也就是说,它们没有一个指定的数据类型,可以接受任何数据值。 ObjectScript支持以下几种类型的变量: 1. 本地变量 :只有创建它的进程可以访问的变量,当该进程终止时,改变量将自动删除。一个本地变量可以从任何命名空间访问。 示例: SET str = "A string" 2. 进程私有的全局变量 : 只有创建它的进程可以访问的变量,并且在进程结束时不再存在。一个进程专用的全局变量可以从任何命名空间访问,因为它与命名空间无关。进程私有的全局变量对于临时存储大数据值特别有用。在许多情况下,它们可以替代Mgr/Temp目录的使用,在进程终止时提供自动清理。 示例: SET ^||flintstones(1)="Fred" SET ^||flintstones(2)="Wilma" 3. 全局变量 : 一个存储在InterSystems IRIS数据库中的持久性变量。一个全局变量可以从任何进程中访问,并且在创建它的进程终止后仍然存在。全局变量是针对个别命名空间的。 示例: SET ^myglobal = "This is a global stored in the current namespace" 4. i%property实例变量 当你创建任何类的实例时,系统会为该类的每个非计算属性创建一个实例变量。实例变量持有该属性的值。例如,如果一个类有Name和DOB属性,那么实例变量i%Name和i%DOB就可以在该类的任何实例方法中使用。实例变量有进程私有的。请注意,这些变量不在本地变量符号表中,不受Kill命令的影响。InterSystems IRIS也使用额外的实例变量,名称为r%PropName和m%PropName,但这些变量不支持直接使用。 5. 特殊变量(也称为系统变量) : 一组特殊的内置变量之一,用于某些应用程序使用的系统信息。所有的特殊变量都是由InterSystems IRIS提供的,并以"$"字符前缀命名。用户不能定义额外的特殊变量。特殊变量集被映射为可从所有命名空间访问。 示例: $HOROLOG
文章
姚 鑫 · 四月 12, 2021

第一章 SQL性能优化简介

# 第一章 SQL性能优化简介 InterSystems SQL支持几个特性来优化InterSystems IRIS®数据平台的SQL性能。 # 表定义优化 SQL性能从根本上取决于良好的数据架构。 将数据划分为多个表并在这些表之间建立关系对于高效的SQL是必不可少的。 描述了以下优化表定义的操作。 这些操作要求定义表,但不要求用数据填充表: - 数据存储策略:可以选择使用`%Storage.Persistent`、`%Storage.SQL`或自定义存储来存储数据。 - 全局变量命名策略:可以使用`USEEXTENTSET`参数为数据和索引查找操作指定更短、更高效的散列全局名称。 - 索引:可以为一个表字段或一组字段定义索引。可以定义几种不同类型的索引:标准索引、位图索引、位图索引和位图范围索引。SQL优化使用定义的索引而不是数据值本身来访问查询、更新或删除操作的特定记录。 # 表数据优化 根据对表中典型数据的分析,可以执行以下操作来优化表访问: - Tune Table:检查典型的表数据并生成`ExtentSize`(行数)、选择性(具有特定值的行的百分比)和`BlockCount`元数据。查询优化器使用此信息来确定最有效的查询执行计划。 - 选择性和异常值选择性:确定某个字段具有特定值的行的百分比,以及某个值是否为异常值,该值明显比该字段的其他值更常见。 # 查询优化 **在几乎所有情况下,用嵌入式SQL编写的查询的执行速度都比用动态SQL编写的查询快。还要注意,由于存在缓存查询,对于嵌入式SQL和动态SQL,重新执行查询的速度都比初始执行快得多。** 可以执行以下操作来优化特定查询的执行。这些查询优化使用现有的表定义和表数据优化: - 运行时统计:用于衡量系统上查询执行的性能。 - 显示计划显示查询的执行计划。 - 缓存查询和文字替换:维护最近动态查询的缓存,允许重新执行查询,而不会重复准备查询的开销。 - SQL语句和冻结计划允许保留查询执行计划,从而允许在不降低现有查询性能的情况下更改表。 - 索引配置和使用:用于指定如何使用现有索引。 - 索引优化提示:`%ALLINDEX`、`%IGNOREINDEX` - 联接优化提示:`%FIRSTTABLE`、`%FULL`、`%INORDER`、`%STARTTABLE` - 子查询优化提示:`%NOFLATTEN`、`%NOMERGE`、`%NOREDUCE`、`%NOSVSO` - 并行查询执行:`%Parallel` - 联合优化: `UNION %PARALLEL`, `UNION/OR` 还可以通过使用数据分片来提高对大型数据库表的查询性能。 # 配置优化 默认情况下,内存和启动设置默认为自动配置,每个进程的最大内存默认为262144 kb。要优化在生产系统上运行的SQL,应该将默认值更改为手动配置,并增加每进程的最大内存设置。 # 分片 分片是跨多个系统对数据及其关联缓存进行分区。分片集群跨多个InterSystems IRIS实例(称为碎片数据服务器)水平(即按行)对大型数据库表进行分区,同时允许应用程序通过单个实例(称为碎片主数据服务器)透明地访问这些表。 必须将表定义为分片。分片表只能在分片环境中使用;非分片表可以在分片或非分片环境中使用。并不是所有的表都适合进行分片。分片环境中的最佳性能通常是通过组合使用分片表(通常非常大的表)和非分片表来实现的 # 快速命令 InterSystems SQL支持快速选择、快速插入和快速截断表。“快速”意味着这些SQL命令的标准调用是使用高效的内部代码执行的。这些快速操作“就是工作”;没有使用特殊语法,也没有提供优化选项。 通过ODBC或JDBC的`SELECT`查询支持快速选择。JDBC上的插入操作支持快速插入。对于不涉及参照完整性的截断表操作,支持快速截断表。 并不是所有的表都支持快速操作,也不是所有的命令语法都可以使用快速执行来执行。InterSystems SQL在可能的情况下执行快速执行;如果无法执行快速执行,InterSystems SQL将执行指定命令的标准执行。
文章
Johnny Wang · 十一月 21, 2021

全球案例--灵活、快速且领先:关于加州大学戴维斯分校健康中心如何利用InterSystems 技术构建医疗数字领域的门户

当我和加州大学戴维斯分校健康中心的同事着手简化提供者对基因组数据报告的访问时,我们希望这些信息能帮助临床医生提供更好、更个性化的护理。 我们的基因组数据没有操作界面,既不可搜索,也不与患者图表相关联。 如果我们可以在 FHIR(快速医疗互操作性资源)连接器上利用SMART原则在平台之间实现单点登录,我们的护理团队就可以更早地获得数据,患者将能够更好地得到照顾,并在与癌症的斗争中取得积极成果。 而这也是正在实现的事情。 我们支持基因组数据报告的工作为临床医生带来了 50 个离散数据点,这意味着医生用于搜索报告的时间更少,也拥有了更多具有重要洞察力的离散数据,简化了对临床试验信息的访问,最终患者也得到了及时的护理。 但我们并没有停下脚步,这不过是迈向更广阔数字领域的第一步。在 InterSystems 的帮助下,我们拥有了规模越来越大、类型更多样的数据集。 回到本文的标题——什么是医疗数字领域的门户?它是某人(通常是患者)与您的医疗单位的每次虚拟来往的总和。根据研究公司 IDC 的数据,到 2023 年,65% 的患者都将会通过这样的门户和对应的医疗机构进行来往,但剩下的其他人呢?所以在加州大学戴维斯分校健康中心,我们决心建立一个欢迎所有人的数字门户——不仅是基因组数据供应商,还有患者、付款人和合作伙伴。 通过变得更加灵活和高效,我们不断推陈出新,提高整个健康中心的效率,并优化对患者的护理。 以下是我总结的为什么数字门户可以帮助每个医疗机构的观点: 1. 是时候加强互操作性工作了 在加州大学戴维斯分校健康中心,我们决定推动我们的数字门户战略,也因为我们不想被 FHIR 潮流所抛弃。随着苹果等公司的健康应用工具使用率的不断上升,基于SMART原则和FHIR构建的应用程序一直在不断提醒供应商们尽快去拿到多年来一直对第三方关闭的数据,而我们的数字门户成为了我们巧妙地驾驭 FHIR 潮流所需的工具和技术。 此外,很明显,《21世纪药物法案草案》将要求医疗系统支持更进一步的互操作性,以便患者访问其数据。 没有多少医疗机构为此制定了数字门户战略。 尽管我们花了数年时间从本土遗留系统和内部应用程序过渡到同类最佳技术,但互操作性描述了数据在内部移动,而不是外部移动。 我们本可以选择将付款人和合作伙伴直接连接到我们的 EHR,但这无法访问位于其他地方的数据。 对于我们的合作伙伴来说,这也可能意味着更高的成本和更大的难度,同时每个应用程序和合作伙伴连接都受制于各自的供应商。 现在,我们加州大学戴维斯分校健康中心使用首选的解决方案堆栈开发了自己的架构——InterSystems IRIS for Health™ 和 HealthShare® 处理了平台外存储的大量数据、连接的非 FHIR 应用程序,并使我们能够创建确保所有合作伙伴都能访问的规则。 在一年多一点的时间里,我们为 InterSystems API 管理器部署了一个开发端点,我们正在与几个合作伙伴合作开展试点项目,以将它们连接到我们的 API 库。 世界正在快速发展时,医疗行业也必须如此。 2. 你真的想用大量不同的技术去拼凑你的数字门户吗? 加州大学戴维斯分校健康中心的数字门户之所以能脱颖而出,是因为我们决心要打造围绕一个互操作性的先进中心。 大多数医疗系统采用联合模型,在一个桶中解决临床数据聚合以及与 FHIR、接口和研究相关的举措。 在加州大学戴维斯分校健康中心,我们有一个专门的团队和一个支持模型来推动整个组织内的数据交换。这意味着强大的灵活性。 例如,新冠病毒的来临颠覆了一切,许多医院不得不与三个甚至更多的供应商争吵,以适应对虚拟服务不断增长的需求。 而我们只用一个小组就快速完成了工作。 随着美国互操作性核心数据 (USCDI) 标准的实施,医疗系统必须能够访问电子健康信息,这些信息存在于医疗系统、数字生态系统的每个角落和缝隙中。 共享存在于 EHR 中的临床数据是不够的。宽阔的数字门户——通过一个入口点就可以进入——是我们最好的选择。 3. 走在时代的前沿 我知道并非所有医疗系统都拥有相同的资源,但任何人都可以适应的技术才是真正的创新。 医疗机构需要根据 USCDI 标准为患者数据的访问去开发解决方案。 如果您具备了这样的开发能力,为什么不多做一步——授权患者、付款人和合作伙伴都能够使用这种资源呢? 如果您这样做了,您会发现您已准备好应对围绕基因组学、远程患者监测以及未来的任何其他事物所带来的创新。 关于作者:Michael Marchant Michael Marchant 在过去 25 年多的时间里一直在和复杂的技术打交道,他一直致力于整合数据,以引领医疗机构的发展。Michael 一直与应用程序供应商、提供商组织以及政府密切合作,领导团队并提供所需的解决方案、技术、工作流程,致力于内部以及当地乃至全国的互操作性推动。 Michael 目前担任加州大学戴维斯分校健康中心的健康信息交换和系统集成总监,他和他的团队为他的组织和社区解决了大量复杂的技术难题和互操作性层面的挑战。 Michael 热衷于推动将患者和患者的健康信息联系起来的技术,并帮助患者能够控制何人、何时以及何地可以访问这些信息。 点击查看原文 2021年12月8日——全球领导力峰会,立刻注册! InterSystems 可以帮助您实现互操作性和数据集成目标。立刻联系我们!
文章
姚 鑫 · 三月 13, 2021

第九章 SQL查询数据库(二)

# 第九章 SQL查询数据库(二) # 调用用户定义函数的查询 InterSystems SQL允许您在SQL查询中调用类方法。这为扩展SQL语法提供了强大的机制。 若要创建用户定义的函数,请在持久性InterSystems IRIS类中定义一个类方法。该方法必须具有文字(非对象)返回值。这必须是一个类方法,因为在SQL查询中将没有对象实例可以在其上调用实例方法。还必须将其定义为SQL存储过程。 例如,我们可以在`MyApp.Person`类中定义一个`Cube()`方法: ```java Class MyApp.Person Extends %Persistent [DdlAllowed] { /// Find the Cube of a number ClassMethod Cube(val As %Integer) As %Integer [SqlProc] { RETURN val * val * val } } ``` 可以使用`CREATE FUNCTION`,`CREATE METHOD`或`CREATE PROCEDURE`语句创建SQL函数。 要调用SQL函数,请指定SQL过程的名称。可以在可能指定标量表达式的任何地方以SQL代码调用SQL函数。函数名称可以使用其架构名称进行限定,也可以不限定。不合格的函数名称采用用户提供的模式搜索路径或系统范围内的默认模式名称。函数名称可以是定界标识符。 SQL函数必须具有用括号括起来的参数列表。参数列表可以为空,但括号是强制性的。所有指定的参数均充当输入参数。不支持输出参数。 SQL函数必须返回一个值。 例如,以下SQL查询将用户定义的SQL函数作为方法调用,就像它是内置SQL函数一样: ```sql SELECT %ID, Age, Sample.Person_Cube(Age) FROM Sample.Person ``` ![image](/sites/default/files/inline/images/1_25.png) 对于`Age`的每个值,此查询将调用`Cube()`方法并将其返回值放入结果中。 SQL函数可能是嵌套的。 如果找不到指定的功能,则InterSystems IRIS会发出`SQLCODE -359`错误。如果指定的函数名称不明确,则InterSystems IRIS会发出`SQLCODE -358`错误。 # 查询串行对象属性 使用默认存储(`%Storage.Persistent`)从类中映射为SQL的子表的串行对象属性也将在该类映射表中的单个列中映射。该列的值是串行对象属性的序列化值。该单列属性被映射为SQL `%List`字段。 例如,`Sample.Person`中的`Home`列定义为`Property Home As Sample.Address;`。它将映射到类`Sample.Address`扩展(`%SerialObject`),其中包含属性`Street`,`City`,`State`和`PostalCode`。 以下示例从各个串行对象列返回值: ```sql SELECT TOP 4 Name,Home_Street,Home_City,Home_State,Home_PostalCode FROM Sample.Person ``` 以下示例将所有串行对象列的值(按顺序)作为单个%List格式字符串返回,并将每一列的值作为%List的元素: ```sql SELECT TOP 4 Name,$LISTTOSTRING(Home,'^'),$length(Name) FROM Sample.Person ``` ![image](/sites/default/files/inline/images/2_14.png) 默认情况下,此“主页”列是隐藏的,并且不映射为`Sample.Person`的列。 # 查询集合 可以从SQL `WHERE`子句引用集合,如下所示: ```sql WHERE FOR SOME %ELEMENT(collectionRef) [AS label] (predicate) ``` `FOR SOME%ELEMENT`子句可用于指定`STORAGEDEFAULT =“ list`”的列表集合和数组。谓词可以包含对伪列`%KEY`,`%VALUE`或两者的引用。一些示例应有助于阐明如何使用`FOR SOME%ELEMENT`子句。以下返回其最喜欢的颜色包括`“红色”`的每个人的名字和最喜欢的颜色的列表。 ```sql SELECT Name,FavoriteColors FROM Sample.Person WHERE FOR SOME %ELEMENT(FavoriteColors) (%Value = 'Red') ``` ![image](/sites/default/files/inline/images/3_12.png) 任何SQL谓词都可能出现在`%Value`(或`%Key`)之后,因此例如以下也是合法语法: ```sql SELECT Name,FavoriteColors FROM Sample.Person WHERE FOR SOME %ELEMENT(Sample.Person.FavoriteColors) (%Value IN ('Red', 'Blue', 'Green')) ``` ![image](/sites/default/files/inline/images/4_8.png) 列表集合被认为是具有连续数字键1、2等的数组集合的特例。数组集合可以具有任意的非空键: ```sql FOR SOME (children) (%Key = 'betty' AND %Value > 5) ``` 除了内置列表和数组集合类型之外,还可以通过为任何属性提供`BuildValueArray()`类方法来创建通用集合。 `BuildValueArray()`类方法将属性的值转换为本地数组,其中数组的每个下标是一个`%KEY`,该值是对应的`%VALUE`。 除了可以在`%KEY`或`%VALUE`上进行简单选择之外,还可以在逻辑上连接两个集合,如以下示例所示: ```sql FOR SOME %ELEMENT(flavors) AS f (f.%VALUE IN ('Chocolate', 'Vanilla') AND FOR SOME %ELEMENT(toppings) AS t (t.%VALUE = 'Butterscotch' AND f.%KEY = t.%KEY)) ``` 此示例有两个集合:`Favors`和`TOPING`,这两个集合通过键在位置上相关。该查询限定了将`巧克力`或`香草`指定为`口味元素`的行,并且还将`奶油糖果`列为相应的`配料`,其中通过`%key`建立对应关系。 可以使用`$SYSTEM.SQL`配置方法`GetCollectionProjection()`和`SetCollectionProjection()`来确定如果将集合映射为子表,则是否将集合映射为列。在编译或重新编译该类时,对该系统范围的设置所做的更改将对每个类生效。 ## 使用说明和限制 - **`FOR SOME%ELEMENT`只能出现在`WHERE`子句中。** - **`%KEY`和`/`或`%VALUE`只能出现在`FOR`谓词中。** - **任何特定的`%KE`Y或`%VALUE`只能被引用一次。** - **`%KEY`和`%VALUE`可能不会出现在外部联接中。** - **`%KEY`和`%VALUE`可能不会出现在值表达式中(仅在谓词中)。** # 调用文本搜索的查询 InterSystems IRIS支持所谓的`“自由文本搜索”`,包括支持: - 通配符 - 填充物 - 多词搜索(也称为n-gram) - 自动分类 - 词典管理 此功能使SQL能够支持全文索引,还使SQL能够索引和引用集合的单个元素,而无需将集合属性映射为子表。虽然支持集合索引和全文索引的底层机制密切相关,但文本检索具有许多特殊属性,因此为文本检索提供了特殊的类和SQL功能。 # 伪字段 InterSystems SQL查询支持以下伪字段值: - **`%ID` —返回`RowID`字段值,而不管`RowID`字段的实际名称是什么。** - `%TABLENAME` —返回在`FROM`子句中指定的现有表的限定名称。定义表时,使用限定的字母大小写返回合格的表名,而不是`FROM`子句中指定的字母大小写。如果`FROM`子句指定了不合格的表名,则`%TABLENAME`将返回合格的表名(`schema.table`),以及从用户提供的模式搜索路径或系统范围内的默认模式名称提供的模式名称。例如,如果`FROM`子句指定`mytable`,则`%TABLENAME`变量可能返回`SQLUser.MyTable`。 - `%CLASSNAME` —返回与`FROM`子句中指定的现有表相对应的合格类名称(`package.class`)。例如,如果`FROM`子句指定了`SQLUser.mytable`,则`%CLASSNAME`变量可能返回`User.MyTable`。 注意:请勿将`%CLASSNAME`伪字段值与`%ClassName()`实例方法混淆。它们返回不同的值。 伪字段变量只能为包含数据的表返回。 如果在`FROM`子句中指定了多个表,则必须使用表别名,如以下嵌入式SQL示例所示: ```java /// d ##class(PHA.TEST.SQL).Query3() ClassMethod Query3(val As %Integer) As %Integer [ SqlProc ] { &sql(SELECT P.Name,P.%ID,P.%TABLENAME,E.%TABLENAME INTO :name,:rid,:ptname,:etname FROM Sample.Person AS P,Sample.Employee AS E) IF SQLCODEd ##class(PHA.TEST.SQL).Query3() Sample.PersonPerson table Name is: Adams,Diane F. Sample.PersonPerson table RowId is: 95 P alias TableName is: Sample.Person E alias TableName is: Sample.Employee ``` 为`%TABLE NAME`和`%CLASS NAME`列分配了默认的列名称`Literal N`,其中`n`是`SELECT`语句中伪字段变量的`select-item`位置。 # 查询元数据 可以使用Dynamic SQL返回有关查询的元数据,例如查询中指定的列数,查询中指定的列的名称(或别名)以及查询中指定的列的数据类型。 下面的ObjectScript Dynamic SQL示例为`Sample.Person`中的所有列返回列名和该列的ODBC数据类型的整数代码: ```java /// d ##class(PHA.TEST.SQL).Query4() ClassMethod Query4() { SET myquery="SELECT * FROM Sample.Person" SET rset = ##class(%SQL.Statement).%New() SET qStatus = rset.%Prepare(myquery) IF qStatus'=1 { WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT } SET x=rset.%Metadata.columns.Count() WHILE x>0 { SET column=rset.%Metadata.columns.GetAt(x) WRITE !,x," ",column.colName," ",column.ODBCType SET x=x-1 } WRITE !,"end of columns" } ``` ```java DHC-APP>d ##class(PHA.TEST.SQL).Query4() 15 Office_Zip 12 14 Office_Street 12 13 Office_State 12 12 Office_City 12 11 Home_Zip 12 10 Home_Street 12 9 Home_State 12 8 Home_City 12 7 Spouse 4 6 SSN 12 5 Name 12 4 FavoriteColors 12 3 DOB 9 2 Age 4 1 ID 4 end of columns ``` 在此示例中,列以反向列顺序列出。请注意,包含列表结构化数据的`FavoriteColors`列返回的数据类型为`12(VARCHAR)`,因为ODBC将InterSystems IRIS列表数据类型值表示为以逗号分隔的值的字符串。 # 快速查询 InterSystems IRIS支持快速选择,这是一种内部优化,用于通过ODBC和JDBC快速执行查询。此优化将InterSystems全局变量映射到Java对象。它将全局节点(数据记录)的内容作为Java对象传递。收到这些Java对象后,它将从它们中提取所需的列值并生成结果集。 InterSystems IRIS会尽可能自动应用此优化。这种优化是自动的,用户看不见。当准备好查询时,InterSystems IRIS会将查询标记为使用快速选择机制执行还是使用标准查询机制执行。 如果查询仅引用字段,常量或引用字段和`/`或常量的表达式,则快速选择将应用于`%PARALLEL`查询和针对分片表的查询。 服务器和客户端都必须支持快速选择。要在客户端中启用或禁用“快速选择”,请在类实例的定义中使用“属性”,如下所示: ```java Properties p = new Properties(); p.setProperty("FeatureOption","3"); / 1 is fast Select, 2 is fast Insert, 3 is both ``` 由于性能上的差异,对于用户来说重要的是要知道什么情况限制了快速选择的应用。 表限制:无法使用快速选择来查询以下类型的表: - 链接表 - 一个表,其主/数据映射具有多个节点 - 具有映射到同一数据位置的多个字段的表(仅可使用`%Storage.SQL`来实现) 字段限制:如果选择项列表中包含以下列,则无法使用“快速选择”执行查询。这些类型的列可以在表中定义,但是查询无法选择它们: - 流字段(数据类型`%Stream.GlobalCharacter`或`%Stream.GlobalBinary`) - 查询时计算的字段(计算的`COMPUTECODE`或瞬态) - 是列表集合的字段(具有`LogicalToOdbc`转换) - 一个执行`LogicalToOdbc`转换并且不是数据类型`%Date`,`%Time`或%PosixTime`的字段 - 覆盖了`LogicalToOdbc`转换代码的字段 - 执行`LogicalToStorage`转换的字段 - 地图数据输入使用检索码的字段 - 一个其地图数据条目具有定界符的字段(不是`%List`存储) - 映射到一块嵌套存储的字段 索引限制:如果选择项目列表仅由`%ID`字段和`/`或均映射到同一索引的字段组成,则不使用快速选择。 如果使用“快速选择”执行查询,则在启用了`%System `/`%SQL` / `XDBCStatement`的情况下,在审计数据库的SELECT审计事件中会标记此事实。 ## 查询和企业缓存协议Enterprise Cache Protocol (ECP) 使用企业缓存协议(ECP)的InterSystems IRIS实现(例如分布式缓存群集)可以同步查询结果。 ECP是一种分布式数据缓存体系结构,用于管理服务器系统的异构网络之间的数据分布和锁定。 如果ECP同步处于活动状态,则每次执行`SELECT`语句时,InterSystems IRIS都会将所有未决的ECP请求强制发送到数据服务器。完成后,这可以确保客户端缓存是同步的。此同步发生在查询的“打开”逻辑中。如果这是游标查询,则在`OPEN`游标执行中。 要激活ECP同步,请使用`%SYSTEM.SQL`类的`SetECPSync()`方法。若要确定当前设置,请调用`$SYSTEM.SQL.CurrentSettings()`。
文章
姚 鑫 · 四月 8, 2021

第二十章 用户、角色和权限

# 第二十章 用户、角色和权限 InterSystems IRIS®具有系统级安全性,以及一组与sql相关的额外安全性特性。 在数据库级保护之外,InterSystems SQL安全性提供了额外级别的安全功能。 SQL和系统级安全性之间的一些关键区别是: - SQL保护比系统级保护更细粒度。可以为表、视图和存储过程定义特权。 - SQL权限既可以授予用户,也可以授予角色。 系统级权限只分配给角色。 - 持有SQL特权会隐式授予执行SQL操作所需的任何相关系统特权。 (相反,系统级特权并不意味着表级特权。) InterSystems SQL在InterSystems IRIS数据平台上对ODBC、JDBC、Dynamic SQL和SQL Shell接口进行权限检查。 嵌入式SQL语句不执行特权检查; 假定使用嵌入式SQL的应用程序在使用嵌入式SQL语句之前会检查特权。 # SQL权限和系统权限 要通过特定于SQL的机制操作表或其他SQL实体,用户必须具有适当的SQL权限。 系统级权限不足。 用户可以直接被授予SQL权限,也可以属于具有SQL权限的角色。 注意:角色是由SQL和系统级安全共享的:单个角色可以包括系统和SQ权限。 下面的例子,以Windows机器上的InterSystems IRIS为例: - 在用户名称空间中有一个名为`User.MyPerson`的持久化类。 这个类被投影到SQL中作为`SQLUser.MyPerson`表。 - 有一个名为`Test`的用户,他不属于任何角色(因此没有系统权限),并且拥有`SQLUser.MyPerson`表的所有权限(没有其他SQL权限)。 - 还有第二个用户,名为`test2`。此用户被分配给以下角色:`%DB_USER`(因此可以读取或写入用户数据库上的数据);`%SQL`(因此可以通过`%Service_BINDINGS`服务访问SQL);并且通过自定义角色具有使用控制台和`%Development`的权限。 如果测试用户尝试通过任何特定于SQL的机制(如使用ODBC的机制)在`SQLUser.MyPerson`表中读取或写入数据,则尝试将成功。这是因为InterSystems IRIS使测试用户成为`%SQL`角色(包括`%SERVICE_SQL:USE`权限)和`%DB_USER`角色的成员,因此该用户具有建立连接所需的权限;这在连接生成的审核事件(如`%SYSTEM/%Login/Login event`)中可见。(如果测试用户尝试使用终端对象机制,则这些尝试将失败,因为用户对这些机制没有足够的权限。) 如果`Test2`用户尝试通过任何特定于SQL的机制(如使用ODBC的机制)在`SQLUser.MyPerson`表中读取或写入数据,则该尝试将失败,因为该用户没有足够的权限访问该表。(如果`Test2`用户尝试使用对象机制查看终端中的相同数据,则尝试成功-因为该用户有足够的权限进行这种类型的连接。) # 用户 InterSystems SQL用户与为InterSystems安全性定义的用户相同。可以使用SQL命令或管理门户定义用户。 - 在SQL中,可以使用`CREATE USER`语句创建用户。这只会创建一个用户名和用户密码。新创建的用户没有角色。必须使用`GRANT`语句为用户分配权限和角色。可以使用`ALTER USER`和`DROP USER`语句修改现有用户定义。 - 在管理门户中选择System Administration(系统管理),选择Security(安全性),然后选择Users(用户)。单击页面顶部的Create New User(创建新用户)按钮。这会将带到编辑用户页,可以在其中指定用户名、用户口令和其他参数。创建用户后,其他选项卡即可用,可以在其中指定用户拥有哪些角色、用户拥有哪些常规SQL权限、用户拥有哪些表级权限、哪些视图可用以及可以执行哪些存储过程。 如果用户具有SQL表权限或一般SQL权限,则在用户的角色选项卡上授予或撤消的角色不会影响用户通过基于SQL的服务(如ODBC)对表的访问。这是因为,在基于SQL的服务中,基于表的权限优先于基于资源的权限。 ![image](/sites/default/files/inline/images/1_32.png) 可以使用`%Library.SQLCatalogPriv`类查询列出: - 所有用户`SQLUsers()` - 授予指定用户`SQLUserPrivs(“username”)`的所有权限 - 授予指定用户`SQLUserSysPrivs(“username”)`的所有系统权限 - 授予指定用户`SQLUserRole(“username”)`的所有角色 以下示例列出了授予当前用户的权限: ```java /// d ##class(PHA.TEST.SQL).Sqluser2() ClassMethod Sqluser2() { SET statemt=##class(%SQL.Statement).%New() SET cqStatus=statemt.%PrepareClassQuery("%Library.SQLCatalogPriv","SQLUserPrivs") IF cqStatus'=1 {WRITE "%PrepareClassQuery failed:" DO $System.Status.DisplayError(cqStatus) QUIT} SET rset=statemt.%Execute($USERNAME) WRITE "Privileges for ",$USERNAME DO rset.%Display() } ``` ## 架构形式的用户名 在某些情况下,用户名可以隐式用作SQL模式名称。如果用户名包含SQL标识符中禁止的字符,这可能会带来问题。例如,在多域配置中,用户名包含“@”字符。 根据分隔标识符配置参数的设置,InterSystems IRIS会以不同的方式处理此情况: - 如果启用了分隔标识符的使用,则不会进行特殊处理。 - 如果禁用分隔标识符的使用,则会从用户名中删除所有禁用字符,以形成架构名称。例如,用户名`“Documentation@intersystems.com”`将成为模式名称`“Documentationintersystemscom”`。 这不会影响`SQL CURRENT_USER`函数返回的值。它始终与`$USERNAME`相同。 # 角色 将SQL权限分配给用户或角色。角色使能够为多个用户设置相同的权限。角色由SQL和系统级安全性共享:单个角色可以同时包括系统权限和SQL权限。 管理门户、系统管理、安全性、角色页提供了InterSystems IRIS实例的角色定义列表。要查看或更改特定角色的详细信息,请选择该角色的名称链接。在出现的编辑角色页面上,有关于角色权限以及哪些用户或角色拥有该权限的信息。 常规选项卡列出角色对系统间安全资源的权限。如果角色仅拥有SQL权限,则一般信息选项卡的资源表会将该角色的权限列为“未定义”。 SQL权限选项卡列出了角色对InterSystems SQL资源的权限,其中命名空间的下拉列表允许查看每个命名空间的资源。因为权限是按名称空间列出的,所以在特定名称空间中没有权限的角色的列表显示为`“None”`。 注:应该使用角色定义权限,并将特定用户与这些角色相关联。这有两个原因: 1. 与检查单个用户条目相比,SQL引擎通过检查相对较小的角色数据库来确定权限级别的效率要高得多。 2. 与具有多个单独用户设置的系统相比,使用少量角色集管理系统要容易得多。 例如,可以定义具有特定访问权限的名为`“ACCOUNTING”`的角色。随着 `Accounting Department`的发展,可以定义新用户并将其与会计角色相关联。如果需要修改`Accounting`权限,只需修改一次,系统会自动覆盖`Accounting Department`的所有成员。 一个角色可以担任其他角色。例如,会计角色可以拥有`BILLINGCLERK`角色。被授予会计角色的用户将同时拥有会计角色和`BILLINGCLERK`角色的权限。 还可以使用以下SQL命令定义用户和角色:`CREATE USER`、`CREATE ROLE`、`ALTER USER`、`GRANT`、`DROP USER`和`DROP ROLE`。 可以使用`%Library.SQLCatalogPriv`类查询列出: - 所有角色`SQLRoles()` - 授予指定角色`SQLRolePrivileges(“Rolename”)`的所有权限 - 授予指定角色`SQLRoleUser(“Rolename”)`的所有角色或用户 - 授予指定用户`SQLUserRole(“username”)`的所有角色 # SQL权限 将SQL权限分配给用户或角色。角色使能够为多个用户设置相同的权限。 InterSystems SQL支持两种类型的权限:管理权限和对象权限。 - 管理权限是特定于命名空间的。 管理权限包括创建、更改和删除对象类型,例如创建表所需的`%CREATE_TABLE`权限。不仅需要`%ALTER_TABLE`特权来更改表,还需要`%ALTER_TABLE`特权来创建或删除索引、创建或删除触发器以及运行`TUNE TABLE`。 管理权限还包括`%NOCHECK`、`%NOINDEX`、`%NOLOCK`和`%NOTRIGGER`,它们确定用户在执行`INSERT`、`UPDATE`、`INSERT`或`UPDATE`或`DELETE`时是否可以应用相应的关键字限制。用户需要分配`%NOTRIGGER`管理权限才能执行`TRUNCATE TABLE`。 - 对象权限特定于表、视图或存储过程。它们指定对特定命名SQL对象的访问类型(在SQL意义上:表、视图、列或存储过程)。如果用户是SQL对象的所有者(创建者),则会自动向该用户授予该对象的所有权限。 表级对象权限提供对表或视图的所有列中的数据的访问(`%ALTER`、`DELETE`、`SELECT`、`INSERT`、`UPDATE`、`EXECUTE`、`REFERENCES`),包括当前存在的列和任何后续添加的列。 列级对象权限仅提供对表或视图的指定列中的数据的访问权。不需要为具有系统定义的值(如`RowID`和`Identity`)的列分配列级权限。 存储过程对象权限允许将过程的`EXECUTE`权限分配给指定的用户或角色。 ## 授予SQL权限 可以通过以下方式授予权限: - 使用管理门户。从系统管理中选择安全性,然后选择用户或角色。选择所需的用户或角色,然后选择相应的选项卡:管理权限的SQL权限、对象权限的SQL表、SQL视图或SQL过程。 - 在SQL中,使用`GRANT`命令向指定用户或角色(或用户或角色列表)授予特定管理权限或对象权限。可以使用`REVOKE`命令删除权限。 - 在ObjectScript中,使用`$SYSTEM.SQL.Security.GrantPrivileve()`方法将特定对象权限授予指定用户(或用户列表)。 ## 列出SQL权限 - 使用管理门户。从系统管理中选择安全性,然后选择用户或角色。选择所需的用户或角色,然后选择相应的选项卡:管理权限的SQL权限、对象权限的SQL表、SQL视图或SQL过程。 - 在SQL中,使用`%CHECKPRIV`命令确定当前用户是否具有特定的管理或对象权限。 - 在ObjectScript中,使用`$SYSTEM.SQL.Security.CheckPrivileve()`方法确定指定用户是否具有特定的对象权限。 ## 审核权限错误 当InterSystems IRIS进程调用用户没有特权的SQL语句时,操作将失败,并生成`SQLCODE-99`错误。启用审核事件`%SYSTEM/%SQL/PrivilegeFailure`时,将在`Audit`数据库中为遇到的每个`SQLCODE-99`错误放置一条记录。默认情况下,此审核数据库选项处于禁用状态。 怎么使用sql查询用户的权限,包括表权限,视图权限
文章
Claire Zheng · 五月 21, 2023

【视频文字版】对话:“数据二十条”与FHIR标准

视频文字版。点击查看视频。 CHIMA主任委员:王才有 老卢,你好。疫情三年我们没见,中国发生了很大的变化,你回来会感觉到。特别是在信息化和数字化方面,确实中国的这三年可以说是政策和制度设计上都有了很大的一些调整和进步,特别是去年政府发布了关于数据基本制度的设计方案,我们管它叫“数据二十条”。 这个制度呢,实际上是避开了数据的所有权的问题,如果说我们在数据的所有权和使用权上长期去争论的话,它的价值就很难发挥。所以说中国这次首次提出了一个“三权”,数据“三权分立”的新的战略设计,不再强调数据是谁的,我们强调数据的控制权——就是数据现在在谁手里;数据的开发权——他这些数据可以用来干什么;数据的受益权——他把这数据再分享给别人,再创造二次价值,或者再创造三次价值,这样数据的资源就得到充分的利用。 所以说一方面要对这种数据基本制度的建立,为今后数据资源市场化是开了一道新的大门。中国是一个数据资源的大国,那这些资源怎么利用好,怎么用在生产,怎么用在服务,怎么用在改善我们医院的管理,给我们患者服务,给这个居民服务,这项我想是一个很大的一个制度上的创新。 当然这个制度的创新也给我们提出了很多新的要求:数据安全的要求,个人信息保护的要求,数据标准的要求…… 我国基础制度的形成,将促进数据合规高效流通使用。今后,医疗健康数据将在更大空间交换和共享,这就需要新一代标准体系了,例如FHIR。 我想这方面你也许知道了,在这方面有什么体会呢?咱们可以做做交流。 InterSystems 亚太区总经理卢侠亮(Luciano Brustia): 好的,谢谢。 您所说的这些让我感到很兴奋,谢谢您的发言。因为我同意,当我们在谈论标准、谈论专业术语的时候,每个人都会立即想到FHIR标准。在这方面,InterSystems在全球绝对是领先的。 你可能知道,在过去的这些年里,我们做了许多工作,我们的IRIS数据平台,在全球范围内得到了大范围部署,同时,我们在中国持续地进行本地化创新,构建了中国版的互联互通平台(内嵌FHIR资源仓库),我们称之为“互联互通套件”,用来实现基于FHIR标准的互联互通 。 当谈到专业术语(统一语义)是我们的目标时,FHIR绝对可以作为一个最佳标准选择,我们已经帮助150多家医院通过了国内互联互通标准化成熟度等级评测,其中有近30家医院通过了最高级别的认证(五级乙等),值此(“数据二十条”颁布的)重要时机,我们肯定还会继续加大投入,在这些方面(打通互联互通和FHIR两大生态)开展更多活动。我们现在已经发布了互联互通套件的第三版,目前正在计划进行更多升级。 CHIMA主任委员王才有: 卢总,您刚才讲的系联在中国的一些做法,我很认可。因为系联公司(InterSystems)在中国已经多年,特别是在推进互联互通,推进信息标准的应用方面发挥了很重要的作用。 对这个FHIR来讲,它是针对的移动互联网出现之后,这信息在更大的范围里面交换共享和随时的调用的时候,随机调用的时候,它只有利用这个标准,它才可能实现信息的动态的、语义互操作的这种交换。 而HL7 2.X它面对的是语法层面的交换,语义层面的这个能力呢,它是比较弱的。所以说如果要做得更好,信息在互联网和移动互联网时代,特别是数字,我们说的数字时代,你在更大的空间里面交换和共享信息的时候,同时保持信息理解上的一致性,那我们只有选用FHIR才可能实现得会更好一些。这一方面是技术上的进步,一方面是应用上的需求。 那当然这种技术上的提供和应用上的需求是必须要依赖于工具,依赖于产品。那系联公司这方面的平台支撑和工具支撑上,我想对于促进FHIR在中国的应用还是发挥了很好的作用的。 系联过去确实做得不错,但是我们看到了FHIR的应用还不是特别地普及,原因是多方面的,可能也有一些新的制约和一些新的挑战。我想系联公司在这方面也会进一步地做出努力,推进FHIR在中国的应用。 这方面,卢总下一步你有什么打算呢? InterSystems 亚太区总经理卢侠亮(Luciano Brustia): 是的,当然有。我们已经将FHIR作为我们所有开发部署的核心,包括我们所有医疗平台。首先,我很高兴在今年CHIMA大会上(HL7中国)将发布《FHIR白皮书》 ,明确界定HL7、CDA和FHIR之间的区别。因为医院采用CDA标准,他们拥有一个庞大的临床数据中心,但我们还需要一个额外的步骤来实现FHIR。 为了让大家更容易理解,我经常举这样一个例子:我总是把FHIR的重要性比作普通话的重要性,因为普通话可以作为人们互相交流的一种共同语言。我也总是喜欢这样说,我看到了一张图片,上面是一匹带着黑色条纹的白马,大家都明白它是什么。你也可以说,你看到了一张图片,上面是一匹带着白色条纹的黑马,大家也都明白它是什么。FHIR不会告诉你这是一匹白马还是一匹黑马,而是会说这是一匹“斑马”——只用一个词,就确切指出了图片内容的唯一标识,以及我们在谈论的是什么。这是深层次的主要区别。 我很高兴《FHIR白皮书》即将在CHIMA上发布,这将有助于理解这一点。InterSystems作为FHIR标准在全球范围的推广者,已经在美国和亚太地区拥有众多成功案例,并且帮助越来越多的国家部署并遵循这种标准,为当地居民提供更多价值,我们很高兴能在中国做同样的事情。 CHIMA主任委员王才有: 刚才没想到您作为一个总裁,对技术细节了解得这么清楚。确实我们要把技术细节搞清楚,把关键的概念搞清楚,这样才能使我们的行动走到正确的轨道上来。对FHIR,它到底是适用于什么场景,什么场景下应该用哪些标准解决什么问题,这我觉得是一个非常重要的一个考虑。任何一个企业、任何一个用户都应该考虑你选用标准的适宜性,我们不能说哪个标准好,哪个标准不好。所以说我们CHIMA,刚才老卢也提到了,我们要在下一次CHIMA大会上发一个白皮书,而这个白皮书实际上就是我们对这些标准的基本概念,它的用途,在什么场景下应用,我们要做一个比较清晰的这种引导,让大家在选择标准和使用标准上,使标准能真正解决自己互联互通上的问题。 那我们CHIMA跟系联一样,也是在推进标准的应用和标准的采纳,实现我们互联互通的目标。前年,我们也组织了专家,在中国的医院编了一个中国医院里边的关于FHIR的应用的一些案例的分享,我们是请的北京友谊医院的专家来共同承担这个课题,也非常感谢系联的专家对这个项目给予了很好的支持。 卢总,我们系联今后在这个信息互联互通和促进,我们叫数字时代的健康场景下,我们公司还有什么好的想法和建议? InterSystems 亚太区总经理卢侠亮(Luciano Brustia):谢谢。我认为此时来到中国,这是一个非常令人兴奋的时机,因为我们能够带来许多在世界各地获得的经验。我们在日本群马大学建立了日本首个FHIR数据库;我们正在与印度尼西亚的一家超大型医疗集团合作,该医疗集团拥有40多家医院,(借助InterSystems技术)采用FHIR标准,将他们的数据汇聚起来,并在此基础上进行分析。毫无疑问,InterSystems一直都在采用、推广FHIR标准,在FHIR成为互操作性标准之前就是如此,而且我们将带来更多的创新,以确保中国始终与国际最前沿的标准接轨,因为最终真正重要的是,我们这样做是为了确保所有中国居民的利益,而且我认为这对像你我这样从事IT行业,特别是从事医疗IT领域的从业者来说,才是最重要的。我们不仅仅是在做生意,更多的是在提供价值。在人口不断增长的情况下助力全民健康水平提升,中国居民的寿命越来越长,这是一件非常好的事情。但也带来了很多问题,特别是人口老龄化的问题,建设高质量的数据库,采用先进的标准,可以有效地预防更多的慢性疾病发生,我认为这是非常有价值的,也让我们所做的事情更有意义,以上是我的看法,非常感谢。CHIMA主任委员王才有:非常高兴看您为中国医疗信息化做出的贡献。系联公司把国际上的一些标准引用到中国,我们也看到中国自身医疗信息化发展也是非常地快,特别是中国具有一个独特的优势——就是数据资源丰富、应用场景非常之多,所以中国的经验呢,我想也在逐渐地积累和形成。所以说我认为系联公司将来的更重要的任务,把中国的经验引向世界,为全球的人民的健康共同做出贡献。InterSystems 亚太区总经理卢侠亮(Luciano Brustia):是的,当然。我的意思是,就像我一直在说的,我很荣幸来到中国,这已经是我在中国的第15个年头了,而系联来到中国已经不止25年了,我们打算再呆上另一个20年、25年……如果我还能再活二十年,(我会)继续留在这里,继续为各位和所有聪明睿智的中国居民服务。毫无疑问,InterSystems一直致力于把我们的先进技术带到中国,助力中国本土企业做大做强,当然,我们也会将在中国获得的经验,作为一种资源共享给世界其他地方。所以我真的很高兴再次回到中国,我认为这是最好的时候,非常感谢大家!
问题
water huang · 四月 24, 2021

RSAEncrypt加密 只能用证书吗

最近尝试使用 Set Ciphertext=##class(%SYSTEM.Encryption).RSAEncrypt(Plaintext,PublicKeyStr)来加密数据,但是加密失败,参考了以下资料https://community.intersystems.com/post/format-public-key-when-using-rsaencrypt-method-systemencryption-or-systemencryptionrsaencrypt https://blog.ndpar.com/2017/04/17/p1-p8/ 生成的公钥为 -----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvl8YRMOJMUOyK5NzWo+8FD8dGR3DuPwn7M13If+rwYp18TEL58NneFdCL+Jjytx4axq+uhPuup5HtmEm22+PQTzFlXuAhXf3oUm4LQl4zgSb14D6gfqac9DqbVhm+aUjDfItFapM35/DH2cvc+rbBhu4Q5Y6kJwcUK0UbRv3swQIDAQAB-----END PUBLIC KEY----- 转换为pkcs1后的内容为 -----BEGIN RSA PUBLIC KEY-----MIGJAoGBANHPwS9+rVB1TJZM1UGLCBan3CY8TIDPkDAftkI504l68vdUWdPlmcN1YZzCGDK4+LvtzdqLXb/XSA3SxsUrA5toWSh45K7/jDzXRcb0AYiUTWGfpeMrHdcGNL07gVT11FM8M+0Jc5Sw6dvMKVXE9wzAxwgaJo0d8zW8Crbx6iI3AgMBAAE=-----END RSA PUBLIC KEY----- 文件保存为utf-8和ansi格式都不行。错误信息为 error:0906D06C:PEM routines:PEM_read_bio:no start line; 2016之后的版本,RSAEncrypt可以接收X.509证书或RSA公钥,而2016中RSAEncrypt接收证书参数。Ensemble2016上使用RSAEncrypt,如果拿不到证书,仅用公钥,请联系InterSystems 销售工程师。 好的,谢谢
问题
Michael Lei · 二月 14, 2023

有没有办法导出与Production相关的所有内容?

您好,有没有一种简单的方法可以导出与Production相关的所有内容并在另一个实例中导入? 例如导出Production保存的 db、ns、映射、webapp 相关、资源、角色等 您可以使用InterSystems Package Manager(IPM)列出生产的所有成员,并通过IPM注册表或使用zpmhub将其分发到另一台机器(例如您的客户端)。 例如,您可以将多个EnsDemo产品安装为一个包: 用户>zpm“安装irishealth-ensdemo” 或者最近我发布了一个非常简单的CSV数据转换生产示例,您可以将其安装为一行: USER>zpm "install esh-i14y-csv" 下面是如何在module.xml中描述生产的所有模块。
文章
Weiwei Gu · 八月 7, 2023

如何自定义 Web 网关错误消息

InterSystems 常见问题解答标题 您可以为以下 Web Gateway 错误消息/系统响应设置单独的错误页面: 服务器错误 服务器繁忙 服务器无法使用 服务器超时 连接关闭 在 Web Gateway 管理界面上进行设置([Management Portal] > [System Administration] > [Configuration] > [Web Gateway Management] > [Configuration] > [Default Parameters])。 在“默认参数”(Default Parameters )菜单的“错误页面”部分中,设置要显示的 html 页面的文件名或发生错误时要重定向到的 URL。 ※Web网关管理界面也可以从以下URL访问。 http://<web server address>:<port>/csp/bin/Systems/Module.cxw 详细信息请参考以下文档自定义错误页面 [IRIS]
文章
Claire Zheng · 八月 17, 2021

【视频】FHIR标准和国际基于FHIR的互联互通实践

当前医院面临更多互联互通需求,如预约挂号与分级诊疗、检验结果共享、医联体信息化、监管数据上报、临床辅助决策支持等,都需要对多源数据进行集成与整合。医疗机构内部和跨机构数据交换与共享,对互联互通提出新的要求。HL7 FHIR是国际上医疗行业实现数据交换和信息共享的标准之一,正在快速得到医疗行业广泛关注。InterSystems中国技术总监乔鹏在视频中分享了FHIR标准与国际互联互通的一些实践经验。
公告
Michael Lei · 十月 24, 2023

官宣对 CentOS 的支持终止

终止对 CentOS 的支持 自 InterSystems IRIS 2023.3 发布起,CentOS 将不再是受支持的开发平台。 CentOS 一直是一个受支持的开发平台,为开发人员提供了相当于 Red Hat Enterprise Linux (RHEL) 的免费版本,用于 IRIS 开发。您可能知道,Red Hat 对 CentOS 进行了重大更改,CentOS 已成为 RHEL 的“上游”。这意味着它具有 RHEL 中尚未包含的错误和功能,这可能会给在该平台上构建的开发人员带来问题。 我们鼓励使用 CentOS 的开发人员利用 Red Hat 的免费开发人员计划来获得 RHEL 的免费开发许可证。 CentOS 继续支持 IRIS 2023.2(及更早版本)。