$INCREMENT (ObjectScript)
構文
$INCREMENT(variable,num)
$I(variable,num)
引数
引数 | 説明 |
---|---|
variable | 値がインクリメントされる変数。添え字付きあるいは添え字なしのローカル変数、プロセス・プライベート・グローバル、またはグローバル変数を指定できます。変数を定義する必要はありません。変数が定義されない、または NULL 文字列 ("") に設定されている場合、$INCREMENT は初期値をゼロとして扱い、状況に応じてインクリメントします。ここではリテラル値を指定できません。単純なオブジェクト・プロパティ参照を variable として指定することはできません。構文 obj.property を使用すると、多次元プロパティ参照を variable として指定できます。 |
num |
オプション — variable に加算したいインクリメント数値。値は、数 (整数または整数以外の数、正の数または負の数)、数を含む文字列、または数に評価される式のいずれかにできます。先頭、および末尾の空白や複数の記号が評価されます。文字列は、最初の非数値文字に遭遇するまで評価されます。NULL 文字列 ("") は 0 として評価されます。 2 番目の引数に num を指定しない場合、InterSystems IRIS は既定で variable を 1 つインクリメントします。 |
概要
$INCREMENT と $SEQUENCE はどちらも、ローカル変数、グローバル変数、またはプロセス・プライベート・グローバルをインクリメントします。$SEQUENCE は一般的に、グローバルで使用されます。
$INCREMENT は、変数の既存の値に指定されたインクリメントを追加し、インクリメントされた値を返すことによって、変数の値をリセットします。詳細は、以下の例を参照してください。
SET a=7
SET result=$INCREMENT(a)
WRITE !,result /* result is 8 (a+1) */
WRITE !,a /* variable a is also now 8 */
$INCREMENT はアトミック処理として実行されます (そのため、LOCK コマンドの使用を必要としません)。
複数のプロセスが $INCREMENT を介して同じグローバルを同時にインクリメントするとき、各プロセスは一意の増加数 (num が負のときは、減少数) を受け取ります。状況によっては、タイミングの問題のために数がスキップされることもあります。グローバル変数での $INCREMENT の使用に関する詳細は、"多次元ストレージの使用法 (グローバル)" を参照してください。
ロールバックされたトランザクションに $INCREMENT がある場合、InterSystems IRIS はインクリメントされていない元の値をリストアしません。
引数
variable
データ値がインクリメントされる変数。これは変数にする必要があります。リテラルにすることはできません。この変数は定義されている必要はありません。$INCREMENT は未定義の変数を定義し、その値を num (既定では 1) に設定します。
variable 引数は、ローカル変数、プロセス・プライベート・グローバル、またはグローバル変数のいずれかになります。添え字付きでも添え字なしでもかまいません。グローバル変数の場合は、拡張グローバル参照を含めることができます。添え字付きグローバル変数の場合は、ネイキッド・グローバル参照を使用して指定できます。
variable 引数は、多次元プロパティ参照でもかまいません。例えば、$INCREMENT(..Count) のように指定します。 非多次元オブジェクト・プロパティとすることはできません。非多次元オブジェクト・プロパティをインクリメントしようとすると、<OBJECT DISPATCH> エラーが発生します。
$INCREMENT は、特殊変数をインクリメントできません。これは、SET を使用して変更できるものでも同じです。特殊変数をインクリメントしようとすると、<SYNTAX> エラーが発生します。
num
インクリメント (またはデクリメント) する分量。num 引数は、variable の値をインクリメントする正の数、または variable の値をデクリメントする負の数のいずれかにできます。整数または小数を指定できます。num はゼロでもかまいません (インクリメントなし)。数値文字列は数値として扱われます。空文字列 ("") または非数値文字列は、インクリメント・ゼロとして扱われます。インクリメントを指定しない場合、InterSystems IRIS は既定のインクリメント (1) を使用します。
$INCREMENT または $SEQUENCE
$SEQUENCE と $INCREMENT は、代替として使用したり、互いに組み合わせて使用したりできます。$SEQUENCE は、特に複数の同時プロセスが関わる整数インクリメント処理の用途で使用されます。$INCREMENT は、より汎用的なインクリメント/デクリメント関数です。
-
$SEQUENCE は、グローバル変数をインクリメントします。$INCREMENT は、ローカル変数、グローバル変数、またはプロセス・プライベート・グローバルをインクリメントします。
-
$SEQUENCE は、数値を 1 だけインクリメントします。$INCREMENT は、任意の数値を任意の指定値単位でインクリメントまたはデクリメントします。
-
$SEQUENCE は、プロセスにインクリメントの範囲を割り当てることができます。$INCREMENT は、1 つのインクリメントのみを割り当てます。
-
SET $SEQUENCE は、グローバルの変更または未定義化 (削除) の用途で使用できます。$INCREMENT は、SET コマンドの左側で使用することはできません。
$INCREMENT とグローバル変数
グローバル変数、またはグローバル変数の添え字ノードで $INCREMENT を使用することができます。拡張グローバル参照を使用して、他のネームスペースにマップされたグローバル変数にアクセスすることができます。添え字付きグローバル変数の場合は、ネイキッド・グローバル参照になります。
InterSystems IRIS は、左から右の順に引数を評価します。num (インクリメントする数量) が添え字付きグローバルの場合、InterSystems IRIS はこのグローバル参照を使用してネイキッド・インジケータを設定するので、後続のすべてのネイキッド・グローバル参照に影響が及びます。
DO $INCREMENT
$INCREMENT は、DO コマンドの引数として実行できます。DO $INCREMENT は、$INCREMENT を関数として呼び出す場合と以下の 2 つの点で異なります。
-
DO は関数からの返り値を無視します。このため、DO $INCREMENT(variable,num) は variable をインクリメントしますが、インクリメントした値を返すことはありません。
-
DO $INCREMENT(variable,num) が <MAXINCREMENT> エラーを発行することはありません。$INCREMENT がインクリメントに失敗した場合、DO コマンドはエラーを発行せずに完了し、variable はインクリメントされません。
DO $INCREMENT に、引数の後置条件式を追加できます。例えば、DO $INCREMENT(myvar):x は、x=0 の場合、myvar をインクリメントしません。後置条件式によって実行は阻止されますが、引数の評価は阻止されません。このため、DO $INCREMENT(myvar($INCREMENT(subvar))):x は、x=0 の場合、myvar をインクリメントしませんが、subvar はインクリメントします。
文字列のインクリメント
$INCREMENT は、通常、数値を含む変数をインクリメントするために使用します。しかし、文字列を含む variable も受け入れます。文字列で $INCREMENT を使用するときには、以下の規則が適用されます。
-
NULL 文字列 ("") は、値がゼロであるものとして扱います。
-
NULL 文字列 ("123" または "+0012.30") は、数値を持つものとして扱います。文字列は、先頭と末尾のゼロやプラス記号が削除され、キャノニック形式に変換されます。
-
数値/非数値の混合文字列 ("12AB" または "1,000") は、最初の非数値文字まで数値として扱われ、その時点で切り捨てられます (コンマは非数値文字であることに注意してください)。結果として得られる数値部分文字列は、先頭と末尾のゼロやプラス記号が削除され、キャノニック形式に変換されます。
-
非数値文字列 ("ABC" または "$12") は、値がゼロであるものとして扱われます。
-
科学的記数法変換が実行されます。例えば、strvar が "3E2" の場合、$INCREMENT は、それを値が 300 であるものとして扱います。大文字の “E” は標準の指数演算子です。小文字の “e” は、%SYSTEM.Process.ScientificNotation()Opens in a new tab メソッドを使用して構成できる指数演算子です。
-
算術演算が実行されません。例えば、strvar が "3+7" の場合、$INCREMENT はプラス記号 (非数値文字として扱われる) で文字列を切り捨てて、strvar を 4 にインクリメントします。
-
1 つの $INCREMENT 文で文字列変数を複数使用することは、回避するべきです。例えば、文字列変数を変数 strvar_$INCREMENT(strvar) のインクリメントに連結することは避けてください。予測できない結果が発生します。
インクリメントの失敗
$INCREMENT が variable をインクリメントできない場合、<MAXINCREMENT> エラーが発行されます。これは、num インクリメント値が非常に小さい場合、および/または variable 値が非常に大きい場合にのみ発生します。
インクリメント・ゼロ (num=0) では、サイズに関係なく常に元の数字が返されます。<MAXINCREMENT> エラーは発行されません。
<MAXINCREMENT> は引数の数値型が異なる場合に発生し、結果として生じる型変換および丸めではインクリメントは行われません。非常に大きな数値に対して $INCREMENT を使用する場合、既定のインクリメント 1 (または、num のその他の小さな正や負の値) は小さすぎて意味がありません。同様に、非常に小さい小数の num 値を指定した場合も、値が小さすぎて意味がありません。$INCREMENT は、元の variable の数値をインクリメントせずに返すのではなく、<MAXINCREMENT> エラーを生成します。
以下の例では、1.2E18 は、1 つずつインクリメントまたはデクリメントできる数字であり、1.2E20 は、大きすぎて 1 つずつインクリメントまたはデクリメントできない数字です。最初の 3 つの $INCREMENT 関数は、数字 1.2E18 を正常にインクリメントまたはデクリメントします。4 つ目と 5 つ目の $INCREMENT 関数では、インクリメントはゼロです。そのため、この関数は、元の数字のサイズに関係なく、常に元の数字を変更しないで返します。6 つ目と 7 つ目の $INCREMENT 関数では、num のインクリメントは十分に大きいので、数字 1.2E20 は正常にインクリメントまたはデクリメントされます。8 つ目の $INCREMENT 関数は、1.2E20 を 1 つずつインクリメントしようとし、その結果 <MAXINCREMENT> エラーを生成します。
SET x=1.2E18
WRITE "E18 :",x,!
WRITE "E18+1 :",$INCREMENT(x),!
WRITE "E18+4 :",$INCREMENT(x,4),!
WRITE "E18-6 :",$INCREMENT(x,-6),!
WRITE "E18+0 :",$INCREMENT(x,0),!
SET y=1.2E20
WRITE "E20 :",y,!
WRITE "E20+0 :",$INCREMENT(y,0),!
WRITE "E20-10000:",$INCREMENT(y,-10000),!
WRITE "E20+10000:",$INCREMENT(y,10000),!
WRITE "E20+1 :",$INCREMENT(y),!
<MAXINCREMENT> は、$INCREMENT が関数として呼び出された場合にのみ発行されます。DO $INCREMENT は、<MAXINCREMENT> エラーを発行しません。
$INCREMENT とトランザクション処理
$INCREMENT は通常、新しいエントリをデータベースに追加する前に、カウンタをインクリメントするために使用します。$INCREMENT を使用すると、LOCK コマンドの使用をしなくても、この操作を迅速に行うことができます。
このカウンタは、トランザクション中の 1 プロセスによってインクリメントされます。トランザクションの処理中に、並列トランザクション中の別のプロセスによってでもインクリメントできます。
いずれかのトランザクション (あるいは $INCREMENT を使用する他のトランザクション) を (TROLLBACK コマンドで) ロールバックする必要があるとき、カウンタのインクリメントは無視されます。結果のカウンタ値が有効であるかどうかが明確ではないため、カウンタ変数はデクリメントされません。このようなロールバックを行った場合、他のトランザクションに多大な損害が及ぶ可能性が大きくなります。
分散データベース環境での $INCREMENT の使用に関する詳細は、"$Increment 関数とアプリケーション・カウンタ" を参照してください。
例
以下の例は、myvar の値が n 分インクリメントされます。myvar は、事前に定義された変数である必要はないことに注意してください。
SET n=4
KILL myvar
SET VAL=$INCREMENT(myvar,n) ; returns 4
WRITE !,myvar
SET VAL=$INCREMENT(myvar,n) ; returns 8
WRITE !,myvar
SET VAL=$INCREMENT(myvar,n) ; returns 12
WRITE !,myvar
以下の例は、$INCREMENT を使用して、インクリメント値をプロセス・プライベート・グローバル ^||xyz に追加します。$INCREMENT の 1 つの引数の形式は、1 をインクリメントします。 $INCREMENT の 2 つの引数の形式は、2 番目の引数で指定された値をインクリメントします。この場合、2 番目の引数は整数以外の値です。
KILL ^||xyz
WRITE !,$INCREMENT(^||xyz) ; returns 1
WRITE !,$INCREMENT(^||xyz) ; returns 2
WRITE !,$INCREMENT(^||xyz) ; returns 3
WRITE !,$INCREMENT(^||xyz,3.14) ; returns 6.14
以下の例は、0 をインクリメントする結果と、負の数をインクリメントする結果を示しています。
KILL xyz
WRITE !,$INCREMENT(xyz,0) ; initialized as zero
WRITE !,$INCREMENT(xyz,0) ; still zero
WRITE !,$INCREMENT(xyz) ; increments by 1 (default)
WRITE !,$INCREMENT(xyz) ; increments by 1 (=2)
WRITE !,$INCREMENT(xyz,-1) ; decrements by -1 (=1)
WRITE !,$INCREMENT(xyz,-1) ; decrements by -1 (=0)
WRITE !,$INCREMENT(xyz,-1) ; decrements by -1 (=-1)
以下の例は、混合 (数値と非数値) num 文字列と NULL 文字列を使用してインクリメントする結果を示しています。
KILL xyz
WRITE !,$INCREMENT(xyz,"")
; null string initializes to 0
WRITE !,$INCREMENT(xyz,2)
; increments by 2
WRITE !,$INCREMENT(xyz,"")
; null string increments by 0 (xyz=2)
WRITE !,$INCREMENT(xyz,"3A4")
; increments by 3 (rest of string ignored)
WRITE !,$INCREMENT(xyz,"A4")
; nonnumeric string evaluates as zero (xyz=5)
WRITE !,$INCREMENT(xyz,"1E2")
; increments by 100 (scientific notation)