Toshihiko Minamoto · 5月 14, 2025 記事へ

Yamamotoさん
こんにちは。
セッション変数のSTAGEに3を代入したにも関わらず、STAGE=3の処理が動作せず、元の状態に戻ってしまうということでしょうか。
であれば、利用されているブラウザーのCookieを受け付けないようになっている可能性があるかと思います。
Edgeでしたら、以下の点を確認いただければと思います。

右上の「...」メニューの「設定」をクリック

左にある「Cookieとサイトのアクセス許可」をクリック

「Cookieデータの保存と読み取りをサイトに許可する(推奨)」がONになっているかを確認
 

Toshihiko Minamoto · 2月 27, 2025 記事へ

@Kazuma Watanabe 
Watanabeさん
おはようございます。
DynamicObjectの件、うっかりしておりました。
DynamicObjectでは数値の精度を設定することはできませんので、OutputToDynamicObject()では従来のフォーマットで出力するようにしました。
 

Toshihiko Minamoto · 2月 21, 2025 記事へ

@Kazuma Watanabe 
Watanabeさん
こんにちは。
%DynamicObjectをJSON形式で出力するのに%ToJSON()を使っていたのですが、%JSON.Formatterクラスでも出力できましたので、そのクラスを継承して、SCALEを指定しているデータのダブルクオートを出力しないようにしました。
同様にDEVブランチにPushしておきましたので、ご確認いただければと思います。
よろしくお願いします。

Toshihiko Minamoto · 2月 20, 2025 記事へ

@Kazuma Watanabe 
Watanabeさん
こんにちは。
JSONTemplateは%DynamicObjectを使用してまして、その制限によってダブルクオートがついてしまうのですが、数値のプロパティで指定されたSCALEパラメータの精度に合わせるようにしました。
JSONTemplateリポジトリのdevブランチにアップロードしています。
https://github.com/Intersystems-jp/JSONTemplate/tree/dev/src/JSONTemplate
もしよろしければ、お試しいただければと思います。
よろしくお願いします。

Toshihiko Minamoto · 2月 19, 2025 記事へ

watanabeさん
こんにちは。
ご連絡ありがとうございます。
数値の場合、+をつけて数値化しておりましたが、SCALEパラメータを見て精度を合わせるようにしたいと思います。少しお待ちいただければと思います。

Toshihiko Minamoto · 7月 21, 2024 記事へ

imaさん
投稿ありがとうございます!
ソースコードをコピーさせていただいて、私の環境でも試してみます。

Toshihiko Minamoto · 11月 1, 2023 記事へ

zpmをロードするメソッドが間違っていましたので、修正しました。
$SYSTEM.OBJ.Import(...  ⇒  $SYSTEM.OBJ.Load(...

Toshihiko Minamoto · 8月 21, 2023 記事へ

こんにちは。

あるお客さんからステップ6のNewStorage1:Map1というタイトルのダイアログをどのようにして表示させるのかわからないとご指摘を受けましたので、補足します。

まず、ステップ6のnew storage wizardを表示させるStorageアイコンは  で、スタジオのメニューの下にあります。
つぎに NewStorage1:Map1というタイトルのダイアログは、スタジオの右にあるインスペクタを表示させ、ステップ6で作成した新規ストーレージを選択すると表示される「SQL storage map」欄をクリックしてその右にある「...」ボタンをクリックします。
 

以上です。
本文中にも補足として追加しておりますので、ご覧ください。

Toshihiko Minamoto · 8月 14, 2023 記事へ

中橋さん、ありがとうございます!
​​​​​​settings.jsonということは、各プロジェクトのフォルダにある.vscodeフォルダのsettings.jsonを変えるとプロジェクトごとに変えられますね😀
こんな感じに...

色のセンスはいまいちですが...

Toshihiko Minamoto · 7月 31, 2023 記事へ

橋本さん、
ありがとうございます!

このプログラムは、どこかのサイトからダウンロードしてインストールできるのでしょうか?
ぜひ、使わせていただきたいです😊
よろしくお願いします。

Toshihiko Minamoto · 6月 2, 2023 記事へ

Ohataさん
こんにちは。
デフォルト値を変えるよりも、EXACTの照合が必要なプロパティが限定的なのであれば、
Propertyのデータ型にCOLLATIONパラメータを設定し、それらのプロパティだけ変更
された方が良いかと思います。

Property P1 as %String(COLLATION="Exact")

よろしくお願いします。

Toshihiko Minamoto · 6月 1, 2023 記事へ

Ohataさん、こんにちは。

SQLでデータが一致するかどうかの判定は照合(collation)によります。
IRISやCacheのデフォルトの照合は%SQLUPPERとなっています。
これは大文字小文字を区別せず、かつ後続の空白は無視されます。
そのため、'bbb△'と'bbb'は同じ文字列と識別され、ヒットします。
照合についてはマニュアルの以下のURLを参照いただければと思います。
https://docs.intersystems.com/iris20221/csp/docbookj/DocBook.UI.Page.cls?KEY=GSQL_COLLATION
 

よろしくお願いします。

Toshihiko Minamoto · 1月 11, 2023 記事へ

Ohataさん、おはようございます。
ちなみに、私はモジュール単位で独立して起動時や終了時の処理を実行できるようにしたかったので、%ZSTARTや%ZSTOPルーチンは管理クラスから生成するようにしています。
プログラムはこんな感じです。

/// ZSTARTルーチンの生成
/// 起動時やログイン時、プロセス起動時に実行するプログラムを登録し、
/// %ZSTARTルーチンを生成させる
///         systemcode ... システム起動時に実行するコード
///         logincode ... ログイン時に実行するコード
///         jobcode ... プロセス起動時に実行するコード
///
///  ※複数行にわたるときはCRLFを挿入する
///  モジュール名は%ZLOADERでファイル名から生成されたモジュール名%moduleの値を使用する
ClassMethod GenerateZSTART(systemcode As %String = "", logincode As %String = "", jobcode As %String = "") As %Status
{
    if $get(%module)="" {
        quit $$$ERROR(5001,"モジュール名%moduleが定義されていません")
    }
    kill ^%ZModule.Code("ZSTART","SYSTEM",%module)
    kill ^%ZModule.Code("ZSTART","LOGIN",%module)
    kill ^%ZModule.Code("ZSTART","JOB",%module)

    set:systemcode'="" ^%ZModule.Code("ZSTART","SYSTEM",%module)=systemcode
    set:logincode'="" ^%ZModule.Code("ZSTART","LOGIN",%module)=logincode
    set:jobcode'="" ^%ZModule.Code("ZSTART","JOB",%module)=jobcode

    set rtn=##class(%Routine).%New()
    set rtn.RoutineName="%ZSTART.MAC"
    set sec="" for {
        set sec=$order(^%ZModule.Code("ZSTART",sec))
        quit:sec=""
        do rtn.WriteLine(sec_"() public {")
        set mod="" for {
            set mod=$order(^%ZModule.Code("ZSTART",sec,mod),1,code)
            quit:mod=""
            do:code'="" rtn.WriteLine(code)
        }
        do rtn.WriteLine("}")
    }
    quit rtn.Compile()
}

便宜上、モジュール名は%付き変数で渡していたり、グローバルを使っていたりしますが、
モジュール名と起動、停止コマンドを入れるテーブルを作成し、トリガーで項目が更新される度にルーチンを生成するメソッドを実行しても良いかと思います。

ご参考まで。

Toshihiko Minamoto · 1月 10, 2023 記事へ

Ohataさん、こんにちは。
監視機能の中でMirroringの起動時に実行されるメソッドはないかと思います。
ただ、GetSensors()メソッドはデフォルトで30秒ごとに呼ばれますので、$SYSTEM.Mirror.IsPrimary()メソッドの戻り値が0から1になった時点でメソッドを実行することは可能です。
メソッドが呼ばれるタイミングは切り替わった時点よりも遅くなりますが。。。

/// 起動処理サンプル
Class MonTest.Test Extends %SYS.Monitor.AbstractSensor
{ 
Property Primary As %Boolean; 

Method Start() As %Status
{
  // todo: ここに処理内容を記述します
  do ##class(%SYS.System).WriteToConsoleLog("startup test sensor in "_$namespace) 

  // ミラーの状態を保存
  set ..Primary=$SYSTEM.Mirror.IsPrimary() 
  Q $$$OK
} 
Method GetSensors() As %Status
{
  set ret=$$$OK
  set status=$SYSTEM.Mirror.IsPrimary()
  // 状態が変更されたとき
  if ..Primary'=status {
      set ..Primary=status
      if status {
          // Primaryに変更されたとき
          set ret=..BecomePrimary()
      }
  }
  Quit ret
} 
Method BecomePrimary() As %Status
{
  Quit $$$OK
} 
}
Toshihiko Minamoto · 1月 4, 2023 記事へ

Ohataさん
あけましておめでとうございます。本年もよろしくお願いします。

インスタンス起動時に実行されるメソッドですが、モニタークラスを作成し、Startメソッドに必要な処理を記載するのはいかがでしょうか?

1.プロダクションを設定されているネームスペースにて、以下のような%SYS.Monitor.AbstractSensorを継承したクラスを作成し、Start()メソッドに起動時の処理を記述します。

/// 起動処理サンプル
Class MonTest.Test Extends %SYS.Monitor.AbstractSensor
{
  Method Start() As %Status
  {
    // todo: ここに処理内容を記述します
    do ##class(%SYS.System).WriteToConsoleLog("startup test sensor in "_$namespace)
    Q $$$OK
  }
  Method GetSensors() As %Status
  {
    Quit $$$OK
  }
}

2.ターミナルを起動し、プロダクションを設定しているネームスペースに移動、システムモニター管理(^%SYSMONMGR)を起動します。

USER> zn "PROD"
PROD> do ^%SYSMONMGR

メニューにて 3 (Configure System Monitor Classes) を選択します。

さらに、1 (Configure System Monitor Components) を選択します。

2 (Add Class)を選択し、「Class?」に対してモニタークラス(この例ではMonTest.Test)を入力します。

Enterキーを何度か押し、システムモニター管理を終了します。

3.ターミナルにて%SYSネームスペースに移動し、システムモニター管理を再度起動します。

PROD> zn "%SYS"
%SYS> do ^%SYSMONMGR

メニューにて 3 (Configure System Monitor Classes) を選択します。

さらに、2 (Configure Startup Namespaces) を選択します。

2 (Add Namespace)を選択し、「Namespace?」に対してプロダクションを設定しているネームスペースを入力します。

Namespace? PROD

何度かEnterキーを押して、システムモニター管理を終了します。

4.IRISを再起動します。
 

以上で、起動時にMonTest.TestクラスのStart()メソッドが実行されるかと思います。


注意点としましてはプロダクションを起動するプロセスとは別のプロセスで実行されますので、プロダクションの自動起動は設定せずに、Startメソッドからプロダクションを起動(Ens.DirectorクラスのStartProductionメソッド)したほうが良いかと思います。
 

Toshihiko Minamoto · 12月 15, 2022 記事へ

Ohataさん、こんにちは。
Ubuntu環境のPythonバージョンですが、以下のマニュアルを見ますと、パッケージマネージャーによりOSで推奨されるバージョンで良いようです。
https://docs.intersystems.com/irisforhealth20221/csp/docbookj/DocBook.UI.Page.cls?KEY=AEPYTHON#AEPYTHON_prereqs

インストール後、%Service_CallInサービスを有効にする必要があります。
忘れると、IRIS_ACCESSDENIED(-15)というエラーが発生します。
これはシステム管理ポータルの「システム管理」「セキュリティ」「サービス」をクリックし「%Service_CallIn」をクリック、「サービス有効」をチェックし「保存」ボタンをクリックします。

また、pythonを起動する前(irisライブラリをインポートする前)に以下のように環境変数を登録する必要があります。

  • export IRISUSERNAME = IRISにログインするユーザ名
  • export IRISPASSWORD = IRISユーザのパスワード
  • export IRISNAMESPACE = 接続するネームスペース
Toshihiko Minamoto · 10月 27, 2022 記事へ

Ohataさん、情報ありがとうございます!
NOT NULL制約のカラムはNULLが入らない前提になっているので、
NULLが入っていると、ヒットしてしまうのですね。

Toshihiko Minamoto · 10月 26, 2022 記事へ

Ohataさん、こんにちは。
②について、カラム値がNULLかどうかを判定するには、IS NULL、IS NOT NULL を使用いただく必要があります。
https://zenn.dev/indigo13love/articles/b3604502149b2f
ただ、記載いただいた結果ですと逆になっているようですが、こちらのIRIS 2022.1で試すと
IS NULL では指定したカラム値がNULLのレコードがヒットしますが、= NULLではヒットしませんでした。

Toshihiko Minamoto · 9月 14, 2022 記事へ

Ohataさん
こんばんは。
カラムデータを取得する際にカラム名ではなく、カラム番号で取得するのは難しいでしょうか?
例えば
    select A,B,C FROM Table
としたときに、Cの値を取りたければ
   set var = rset.%Get("C")
の代わりに
   set var = rset.%GetData(3)
といった感じです。
もし可能でしたら、カラム名からカラム番号に変換するという余分な処理をしなくても済むので
早くなるのではないかと思います。
 

Toshihiko Minamoto · 8月 16, 2022 記事へ

Kobataさん、こんにちは。
すみません、知見があるわけではないのですが、Ubuntu 22.04はIRIS 2022.2からサポートされる予定ですので、
2022.2 プレビュー版をdocker上で動作させるか、2022.2の製品版が出てからUbuntu上にインストールいただいた方が無難かと思います。
ただ、2022.2はCDリリースですのでadhocを出すことができませんので、adhocが必要なケースが想定されるのであれば、Ubuntu 20.04 LTSを利用された方が良いかと思います。 
よろしくお願いします。

Toshihiko Minamoto · 6月 17, 2022 記事へ

Ohataさん
こんにちは。
残念ながら、ミラーリングですと、%NOJOURNキーワードは無視されるようです。
その他の方法を探してみたところ、ObjectScriptから実行することになりますが、
$SYSTEM.Process.TransactionsSuspended()でトランザクションを一時停止すると、その間の更新はバックアップサーバに値は転送されますし、ロールバックしても戻らなくなりました。

まず、JRNTEST.Testテーブルに2行追加します。
USER>s r=##class(%SQL.Statement).%ExecDirect(,"insert jrntest.test set p1=1")
USER>s r=##class(%SQL.Statement).%ExecDirect(,"insert jrntest.test set p1=1")
トランザクションを開始します
USER>s r=##class(%SQL.Statement).%ExecDirect(,"start transaction")
トランザクションを一時停止します。
TL1:USER>d $SYSTEM.Process.TransactionSuspended(1)
ID=1のレコードのカラムP1の値をインクリメントします。
TL1:USER>s r=##class(%SQL.Statement).%ExecDirect(,"update jrntest.test set p1=p1+1 where id=1")
トランザクションを再開します
TL1:USER>d $SYSTEM.Process.TransactionSuspended(0)
ID=2のレコードのカラムP1の値をインクリメントします。
TL1:USER>s r=##class(%SQL.Statement).%ExecDirect(,"update jrntest.test set p1=p1+1 where id=2")
現在値を確認します。
TL1:USER>do ##class(%SQL.Statement).%ExecDirect(,"select * from jrntest.test").%Display()
ID      p1
1       2
2       2

2 Row(2) Affected
ロールバックします
TL1:USER>s r=##class(%SQL.Statement).%ExecDirect(,"rollback")
現在値を確認します。
USER>do ##class(%SQL.Statement).%ExecDirect(,"select * from jrntest.test").%Display()
ID p1
1 2
2 1

2 Row(s) Affected

よろしくお願いします。

Toshihiko Minamoto · 6月 14, 2022 記事へ

Ohataさん、
こんにちは。
ちょっと調べてみたのですが、
UPDATE文に%NOJOURNというオプションがありますので
    UPDATE  %NOJOURN table SET counter = counter + 1 WHERE name='xxx'
のように記述いただくと、その更新はロールバックを無視します。
よろしくお願いします。

Toshihiko Minamoto · 5月 29, 2022 記事へ

Ohataさん、こんにちは。

既に解決されているかもしれませんが、記述されていた通り、スタンドアロン環境ではパッケージをインストールできませんので、以下の手順でインストールする必要があるかと思います。

1. インターネット環境にて必要なパッケージ(.gzファイル)をダウンロードする  

irispip download -d c:\intersystems\iris\mgr\python --no-binary :all: <パッケージ名>

c:\InterSystems\IRIS\mgr\pyhtonフォルダにパッケージ(tar.gz形式)のファイルが作成されます。

2. スタンドアロン環境にパッケージをコピー

3. スタンドアロン環境にてパッケージをインストール

irispip install c:\intersystems\iris\mgr\python\<パッケージファイル名>

以下のサイトを参考にしました。

https://qiita.com/analytics-hiro/items/2565adbb2c900e6738cd

Toshihiko Minamoto · 3月 8, 2022 記事へ

Ohataさん
こんにちは。
もしかすると、自己解決されているかもしれませんが、
ビジネスサービスの「設定」タブの「追加の設定」にあるスケジュールに、
作成されたスケジュール仕様を選択すれば、その時間帯だけ稼働するかと
思います。

Toshihiko Minamoto · 3月 2, 2022 記事へ

Hiroseさん

こんにちは。

Ohataさんが紹介されている記事にあるDjango-irisを使ってDjangoからIRISのDBを使うことができました。
(Pythonコンテスト1位でしたね!)

手順はこんな感じです。

1. IRISインストール

記事の中にあるように、IRIS 2022.1のプレビュー版が必要ですので、ダウンロードし、インストールします。  

2. Pythonインストール

Python 3.10.2 amd64をインストールしました。インストール時に add Python 3.10 to Pathをチェックしてインストールしています。  

3. Djangoインストール

コマンドプロンプトより、python -m pip install Django  

4. Django-irisのダウンロード

https://openexchange.intersystems.com/package/django-iris よりdjango-iris-0.1.x.zipをダウンロードし、c:\に展開  

5. Python DB-APIのインストール

コマンドプロンプトで4で展開されたディレクトリに移動し、whlファイルをインストールします。 pip3 install intersystems_irispython-3.2.0-py3-none-any.whl  

6. Django-irisのインストール

コマンドプロンプトより、以下のコマンドでインストールします。 pip install django-iris  

7. Djangoアプリの作成

Djangoの公式ページにあるチュートリアルに従ってアプリを作ってみました。 https://docs.djangoproject.com/ja/4.0/intro/tutorial01/ ただし、Databaseの設定部分で設定ファイル(settings.py)のDATABASESの部分を以下のように修正しています。

DATABASES = {
     'default': {
         'ENGINE': 'django_iris',
         'NAME': 'USER',
         'HOST': 'localhost',
         'PORT': 1972,
         'USER': '_SYSTEM',
         'PASSWORD': 'password',
     }
 }
Toshihiko Minamoto · 2月 15, 2022 記事へ

Hashimotoさん
こんにちは。
IRISスタジオだと「他の表示」で表示されたINTコード上で、エラーの行にカーソルを持っていき、
再度「他の表示」をクリックすると対応するソースコードに移るのでなんらかの方法はあるかと
思い、調べてみました。(%SYS.MONLBLで... cheeky)
Internalクラスなので、インターシステムズのサポートは無く、将来的に変わる可能性はありますが、以下の方法で求められそうです。

まず以下のメソッドでエラーのロケーション形式( label+offset^routine )から、INTルーチンの先頭からのoffsetを求めます。

set sc=##class(%Studio.Debugger).INTLine("ClassName.1.INT","zNewMethod",32,.intname,.intline)

で、sc=1の場合、intnameにはINTルーチン名、intlineには先頭からのオフセットが入ります。

次に、以下のメソッドでソースコードのロケーションを求めます。

set sc=##class(%Studio.Debugger).SourceLine(intname,intline,1,99999,1,"USER",.map)

sc=1の場合、変数mapは以下の形式で返ります。

map("CLS",1)=$lb(クラス名,メソッド名,メソッドからの行数,1,ネームスペース)

ちなみに、SourceLine()メソッドの第2~5引数は

startLine, startPos, endLine, endPos

となっており、どうもエディタ上で選択した範囲を入力すると、それに対応するソースコードの範囲を計算してくれるようです。

その場合、変数mapはこんな感じになります。

map("CLS",1)=$lb(クラス名,StartLineのメソッド名,StartLineのメソッドからの行数,startPos,ネームスペース)
map("CLS",2)=$lb(クラス名,EndLineのメソッド名,EndLineのメソッドからの行数,endPos,ネームスペース)
Toshihiko Minamoto · 1月 27, 2022 記事へ

Ohataさん
こんばんは。
Ens.Util.LogテーブルのTimeLoggedカラムを見ると、Ens.DataType.UTCとなっていました。これはUTCで保管されているのですが、表示するときにLogicalToDisplay()などでローカル時刻に変換しています。
従いまして、①については、実体としてUTCで保管されています。
②についてはEns.DataType.UTCは表示するときにローカル時刻に変換されますが、キャストしたものは型が異なるので変換されずに表示されるからだと思います。
③についても、WHERE句の条件はUTCで計算されますので、記載されたようにDATEADDで変換するしかなさそうです。
ただTimeLoggedカラムに変換をかけるよりも、指定したパラメータをUTCに変換する方が、DBのインデックスも使用できるので効率が良いかと思います。
  WHERE timelogged >= DATEADD('hh',-9,'2022-01-26')​​

Toshihiko Minamoto · 12月 16, 2021 記事へ

12/16現在、各製品の調査状況は以下の通りです。詳細はこちらをご確認ください。

以下の製品につきましては、Log4j2による脆弱性があることが確認されました。

Data Platforms Add-ons 
 • InterSystems Reports Server
 • InterSystems Reports Designer 

TrakCare
 • TrakCare Core 

以下の製品はLog4j2を使用していますが、信頼できないソースからのデータ処理には使用されていません。

Data Platforms Add-ons
 • InterSystems Cloud Manager

HealthShare 
 • HealthShare Clinical Viewer (2019.2 ~ 2021.2) 

以下の製品につきましてはLog4j2による脆弱性が無いことが確認されています。

Data Platforms
• InterSystems IRIS
• Caché
• InterSystems IRIS for Health
• Ensemble

Data Platforms Add-ons
• Atelier Integration
• CSP Gateway for CE
• IRIS Studio
• InterSystems API Manager
• InterSystems Kubernetes Operator (IKO)
• ISC Agent
• Legacy .Net bindings
• Legacy node JS binding
• ODBC Driver
• System Alerting and Monitoring (SAM)
• VS Code Integration
• Web Gateway for IRIS
• Zen Mojo

HealthShare
• HealthShare Clinical Viewer (2019.1以前 )
• Unified Care Record
• Care Community
• Personal Community
• Provider Directoryi
• Health Insight
• Patient Index
• Health Connect