記事
· 4 hr 前 4m read

計算プロパティの使用方法2

これは InterSystems FAQ サイトの記事です。
 

計算プロパティを定義する際に利用可能なキーワードが複数あります。

詳細は、以下をご参照ください。

計算プロパティの定義

実際のこれらのキーワードの関連性は、少々複雑ですので具体的なコードを作成して動作を確認してみます。 

以下のようなクラス定義を作成します。(プロパティとインデックス定義のみ表示します)

完全なクラス定義は以下より、ダウンロードできます。

サンプルクラス定義

Class Sample.Person Extends %Persistent [ ClassType = persistent, ProcedureBlock ]

{

Property FirstName As %String;
Property LastName As %String;
Property DOB As %Date;
Property Age1 As %Integer [ Calculated, SqlComputed, Transient ];
Property Age2 As %Integer [ Calculated, Transient ];
Property Age3 As %Integer [ Calculated, SqlComputed ];
Property Age4 As %Integer [ Calculated ];
Property Age5 As %Integer [ SqlComputed, Transient ];
Property Age6 As %Integer [ Transient ];
Property Age7 As %Integer [ SqlComputed ];
Property Age8 As %Integer [ SqlComputed, SqlComputeOnChange = DOB ];
// インデックスは、Trancient = true の時には作れない
// Index IndexAge1 on Age1;
// Index IndexAge2 on Age2;
// Index IndexAge5 on Age5;
// Index IndexAge6 on Age6;
Index IndexAge3 On Age3;
// インデックスは、SqlComputed = false の時には作れない
// Index IndexAge4 On Age4;
Index IndexAge7 On Age7;
Index IndexAge8 On Age8;
}

計算プロパティとしてAge(年齢)というプロパティを作ります。

年齢は、今日の日付から誕生日(DOB)を引き算して経過日数を求め、閏年を考慮しつつ年の日数で割り算することで求められます。

以下にキーワードの組み合わせによる違いについて表にまとめています。

 

同じような年齢プロパティがこれらのキーワードの組み合わせに基づき、8個定義されています。

計算プロパティは、このキーワードの組み合わせによりインデックスを設定できる場合があります。

そして上のコードのコメントに書いてあるとおり Trancient = trueおよびSqlComputed = falseが設定されているとインデックスを作ることができません。 従ってこのサンプルでは、Age3, Age7, Age8のみがインデックス作成可能です。

またAge1とAge2はインデックスが作成できない点で共通で、違いはSqlComputedの指定だけですが、結果がどのように計算されるかについて大きな違いがあります。

それではその計算がどの様にどのタイミングで行われるかを示すサンプルコードを実行してみます。

上のコードに予め含めておいたクラスメソッドを実行することで動作を確かめてみます。

USER>do ##class(Sample.Person).CalculatedPropertyTest()

^Sample.PersonD=1
^Sample.PersonD(1)=$lb("","Kaoru","Shinuchi",60000,18,18)

^Sample.PersonI("IndexAge3",18,1)=""
^Sample.PersonI("IndexAge7",18,1)=""
^Sample.PersonI("IndexAge8",18,1)=""
ID Age1 Age3 Age5 Age7 Age8 DOB FirstName LastName

1 18 18 18 18 18 60000 Kaoru Shinuchi

1 Rows(s) Affected^Sample.PersonD=1
^Sample.PersonD(1)=$lb("","Kaoru","Shinuchi",50000,18,46)

^Sample.PersonI("IndexAge3",46,1)=""
^Sample.PersonI("IndexAge7",18,1)=""
^Sample.PersonI("IndexAge8",46,1)=""
ID Age1 Age3 Age5 Age7 Age8 DOB FirstName LastName

1 46 46 46 18 46 50000 Kaoru Shinuchi

1 Rows(s) Affected

Age1の場合、このキーワードの組み合わせでは、プロパティの計算タイプは常に計算になります。

そしてTrancientなのでデータの実体は持ちません

Age2の場合、プロパティの計算タイプは、計算されないになります。そしてTrancientなのでデータの実体は持ちません。

さらにsqlComputedがFalseなのでSQLのフィールドとしても認識されません。

(但し、このサンプルコードでは示していませんが、クラスインスタンスの計算プロパティとしてはデータ取得可能です。)

Age3の場合、プロパティの計算タイプは、常に計算になります。

データの実体は持たず、その計算結果に基づきインデックスを生成します。

そしてデータが更新された場合にもその更新内容に基づきインデックスも更新されます。

Age4, 6はAge2と同様です。

Age5は、Age1と同じです。 

Age7の場合、プロパティの計算タイプは、トリガーによって計算になります。

しかし、SqlComputeOnChangeが定義されていないので、DOBが変更されてもその変更が検知できずに初回に設定された値をずっと保持したままです。

Age8の場合、プロパティの計算タイプは、トリガーによって計算になります。

ここでは、SqlComputeOnChangeが定義されているので、DOBが変更されるとその変更に基づきAgeが再計算されます。

ディスカッション (0)1
続けるにはログインするか新規登録を行ってください