文章
· 十月 6, 2023 阅读大约需 3 分钟

进程表

iris 是数据平台,更是一种数据库。对于熟悉SQL语句的人来说,会认为“既然是数据库,数据应该就能使用sql语句来查询”。这是对的,但是因为有global这个概念,保存的数据可能在global里面,而没有对应的表,也可能保存在类的参数定义里面。这些数据,不能使用sql直接查询。要查询iris数据库的数据,通常有几种方式:1.直接查询表的数据。2.查询视图。3.调用存储过程(call 命令)。其中要查询“只存于global里面或者类参数里定义的数据”,只有使用存储过程。但是存储过程有个问题,就是程序如果迁移到低版本的cache数据库后,数据类型的定义会有问题,且不再支持使用select的方式,只能使用call。这对于第三方熟悉sql的人员来说很不友好。因此结合global和表的关系,介绍一种我称为“进程表”的表。进程表,指数据只存于该进程中,global的样式为"^||global名“。通常按照默认存储新加一个持久类(对应会生成一个表),然后手动的把global改成进程global,也就是加上”||“。然后写个方法,把需要查询出来的数据写入进程global。这样就能查询出来 了。调用形式为 SELECT * FROM People WHERE People_GLB()=1。

示例如下:

Class User.People Extends %Persistent
{ /// 姓名
Property Name As %String; /// 出生日期
Property DOB As %Date; /// 性别
Property Sex As %String; ClassMethod GLB(P...) As %Status [ Language = objectscript, SqlProc ]
{
$zt="Err"
^||User.PeopleD,^||User.PeopleI
i=1:1:100 d
.Sex=$r(2)+1
.Name=##class(%PopulateUtils).Name(Sex)
.DOB=##class(%PopulateUtils).Date(+$h-2000,+$h-10)
.Sex=$s(Sex=1:"Male",Sex=2:"Female",1:"Male")
.^||User.PeopleD($i(^||User.PeopleD))=$lb("",Name,DOB,Sex)
$$$OK
Err
$zt=""
^||User.PeopleD($i(^||User.PeopleD))=$lb("",$ze)
$$$OK
} Storage Default
{
<Data name="PeopleDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>Name</Value>
</Value>
<Value name="3">
<Value>DOB</Value>
</Value>
<Value name="4">
<Value>Sex</Value>
</Value>
</Data>
<DataLocation>^||User.PeopleD</DataLocation>
<DefaultData>PeopleDefaultData</DefaultData>
<IdLocation>^||User.PeopleD</IdLocation>
<IndexLocation>^||User.PeopleI</IndexLocation>
<StreamLocation>^||User.PeopleS</StreamLocation>
<Type>%Storage.Persistent</Type>
} }
 

这段代码很简单,但是能说明如何运用进程表。有几个点需要注意:1."SELECT * FROM People WHERE People_GLB()=1" 中where后面的条件就是类里面的函数,可以传入参数,示例中,参数是可变参数。where后面的条件样式是固定写法,也就是"xxx()=1" 是固定写法。2.示例中的函数只是用于生成需要的数据,实际情况中,代码逻辑自行编写。所写的函数里面需要加上异常捕获,这样,即使代码报错,sql也能正常执行,但是错误信息应该写入任意是字符串的列。3.如果用于导出大量数据,需要给iris配置足够的内存。4.进程表只是提供了一种代码转为 sql查询结果的可选方案。具体需求中是否适合,还需要具体问题具体分析。

讨论 (2)3
登录或注册以继续