これは InterSystems FAQ サイトの記事です。
8192文字を超える文字列をODBC経由で取得した場合に特定のODBCクライアントとの組み合わせにおいて文字列が途切れて取得されるケースが報告されています。
このような状況が発生した場合、該当するODBCデータソースの設定画面でUnicode SQLタイプをチェックすることで問題が解消されることがわかっています。
これは InterSystems FAQ サイトの記事です。
8192文字を超える文字列をODBC経由で取得した場合に特定のODBCクライアントとの組み合わせにおいて文字列が途切れて取得されるケースが報告されています。
このような状況が発生した場合、該当するODBCデータソースの設定画面でUnicode SQLタイプをチェックすることで問題が解消されることがわかっています。
これは InterSystems FAQ サイトの記事です。
大量のレコードが含まれるテーブルに対して、select count(*) from テーブル名の応答が遅い、または応答がタイムアウトする場合には、ビットマップ・エクステント・インデックスを追加することで問題を解消することができます。
ビットマップ・エクステント・インデックスを追加する方法は、以下をご参照ください。
クラス定義に以下のような定義を行うことで、ビットマップ・エクステント・インデックスを追加することもできます。
Index IndexName [ Extent, Type = bitmap ];これは InterSystems FAQ サイトの記事です。
ObjectScriptの%Netパッケージのライブラリクラスを利用して、ファイルを他のサーバーにアップロードすることができます。
以下のCurl コマンドと同じことを ObjectScript で実現する方法を紹介します。
curl -X POST "http://localhost/api/upload/csv?a=123&b=999""C:/temp/a.csv"クライアントのObjectScriptコードを以下の様に作成します。
これは InterSystems FAQ サイトの記事です。
計算プロパティを定義する際に利用可能なキーワードが複数あります。
詳細は、以下をご参照ください。
実際のこれらのキーワードの関連性は、少々複雑ですので具体的なコードを作成して動作を確認してみます。
以下のようなクラス定義を作成します。(プロパティとインデックス定義のみ表示します)
完全なクラス定義は以下より、ダウンロードできます。
ClassExtends%Persistentこれは InterSystems FAQ サイトの記事です。
IRISには、データ項目の値を実体として持たずに、何らかの演算処理の結果として提供する機能があります。
これを計算プロパティまたは計算フィールドといいます。
計算プロパティを定義するためには、最低限以下の手順を実行します。
プロパティ定義にSqlComputedキーワードを含めます。
プロパティ定義にSqlComputedCodeを含めて、値を算出するための処理ロジックとして含めます。
または、SqlComputedCodeを含めずに、代わりに<プロパティ名>Computationという名前のクラスメソッドを記述します。
以下は、Age(年齢)プロパティを計算プロパティとして定義した例になります。
ClassExtends%PersistentAs 計算フィールドの詳細は、以下を参照してください。
計算プロパティの定義
これは InterSystems FAQ サイトの記事です。
以下の様なCurl コマンドで送信したファイルを受け取るRESTサービスを作成する方法を紹介します。
curl -X POST "http://localhost/api/upload/csv?a=123&b=999""C:/temp/a.csv"クライアントからPOSTされたファイルを受け取ってサーバーに保存するRESTサービスは以下の様に作成します。
(このサンプルでは、1000文字以下の小さいサイズおよび文字コードはutf-8のファイルを想定しています。)
"POST"このRESTサービスをクライアントから呼び出すために、以下の様な設定を行います。
管理ポータル>システム管理>セキュリティ>アプリケーション>ウェブ・アプリケーション>新しいウェブ・アプリケーションを作成の所で上で作成したRESTディスパッチクラスを登録します。
名前: /api/upload
ネームスペース: そのクラスを保存したネームスペース
RESTを有効にして、ディスパッチクラスにUser.MyRESTを設定する
この設定はAPIを呼び出して実行することもできます。
これは InterSystems FAQ サイトの記事です。
インターオペラビリティ機能を使用してビジネスホストのビジネスロジックを実装する際に、デバッグ等の目的でログ出力を行うための専用マクロが用意されているので、ご紹介します。
以下のマクロが用意されています。
$$$LOGINFO"これはログです。"$$$LOGERRORビジネスオペレーション等のコードに上記のコードを書くことにより、インターオペラビリティのイベントログにその内容が表示されます。
以下の様に表示されます。
これは InterSystems FAQ サイトの記事です。
SQLでのストリームフィールドの取得についてはこちらのドキュメントに記載されております。
例: キャラクターストリームデータの50文字取得する
select substring(field1,150%SQL.Statement を使用したクエリでそのストリームオブジェクトのOREF値を取得して、ストリームデータにアクセスすることもできます。
埋め込みSQLを使用する場合は、そのストリームオブジェクトのOREFではなくストリームIDが返ってくるので、以下のようにストリームをオープンする処理を追加する必要があります。
&sql(selectintofromこれは InterSystems FAQ サイトの記事です。
何らかの理由でサーバー移行が必要になった際に、移行前の環境から移行後の環境に設定情報をコピーすることで設定作業を軽減できます。
以下の設定情報を移行できます。
注1 パスワードを設定している場合には、パスワードのみ手動で再設定が必要です。
注2 ^%ZSTART, ^ZMIRRORルーチンなど 優先接続サーバー設定に関しても、物理的には移行可能ですが、Windowsのレジストリー情報をコピーする必要があります。
レジストリー情報をコピーして他システムに移行する方法は通常推奨される方法ではありません。
各設定のエクスポート/インポート方法は、以下のリンクをご確認ください。
また、以下のドキュメントもあわせてご覧ください。
これは InterSystems FAQ サイトの記事です。
Question:
使用中のプログラムをコンパイルして保存すると、現在そのプログラムを実行中のプロセスに影響しますか?
Answer:
実行中のルーチンはその旧バージョンをメモリー上に保持しているため、コンパイルして新しいルーチンが保存されても影響なく実行を継続できます。
クラスのメソッドについても同様です。 再度そのルーチンが呼び出された時点でコンパイルされた新しいルーチンが使用されるようになります。
Mac版IRISでは、現状Pythonのバージョンが固定(3.11)なのですが、これに付随する他製品との相性問題に遭遇しましたので報告します。
今までEmbedded Pythonは調子よく動作していたのですが、ある時から急に動作しなくなりました。
原因を調べてみると、Python3.13がインストールされ、それがデフォルトとして上書きされたため、irispythonコマンドを発行すると、それが内部で3.13を呼ぶ様になってしまったためでした。
ちなみにiris session でログインし、そこからEmbedded Pythonを実行する場合は、問題ありません。
あくまでもirispythonコマンドで直接.pyファイルを実行する場合に発生する問題です。
そしてとりあえずの対処法は、python3をpython3.11で置き換える方法です。
以下のような感じです。(どのMacでもbrewコマンドでインストールした場合、ディレクトリ構造は同じだと思いますが、違う可能性もゼロではありません)
cp /opt/homebrew/bin/python3.11 /opt/homebrew/bin/python3
さて、ところで何で3.13がインストールされていたのかというと、
IRIS SQLのLOADコマンドを動作させるためには、JDKまたはJREが必要なのでそれをインストールしました。
日本でMacユーザーのIRIS使いがどの程度いるのかわかりませんが、圧倒的少数派なのは確かでしょう。
そのせいもあってか、Mac版のインストーラは、Windows版ほどきめ細かい対応をしてくれていません。
Windows版はインストーラが勝手に日本語のロケールを設定してくれているのですが、Mac版(おそらくLinux版も)は英語ロケールのままです。
それでも、通常の使用ではさほど問題がないといえないこともないのですが、ファイルを読んだりする場合や他にも何かと不都合があります。(何かあったような気がしますが、忘れました。)
ですので、Macユーザーは面倒ですが、管理ポータルで日本語ロケールjpuwのインストールをする必要があります。
またはターミナルでコマンド一発でもOKです。
Do##class"jpuw"ちなみにこのロケールjpuwは説明を読むとUNIX用と書いていますが、WindowsでもファイルI/OなどのデフォルトエンコーディグをSJISではなくUTF8にしたい場合にも使えます。
昨今は、WindowsといえどもUTF8でファイル作成するケースが増えていますので、今更SJISいらないという人は、思い切ってこのロケールに切り替えるというのもありです。
Caché技術ガイドのいくつかをIRIS版に書き換えた文書を作成しましたので公開します。
IRISファーストステップガイド
IRISBasicTechnologyGuide
- ObjectScript操作ガイド
- オブジェクト操作ガイド
- 多次元データエンジンの概念およびアーキテクチャー
IRIS SQLガイド
REST/JSONを使ってデータを交換することが増えてきていると思いますが、POSTでIRISにデータを渡す場合に日本語が含まれる場合に皆さんどう処理していますか?
わざわざ自分でコード変換する処理を追加していませんか?
実は、あまり知られていないのですが、自動で変換する方法がありますので、紹介します。
CSPのメカニズムを使ってクライアントからデータをPOSTすると、それはCSPのRequestオブジェクトのContentプロパティに渡されます。
ContentプロパティのTypeは%CSP.Streamになっていて、このTypeのクラスリファレンスを読むと、Content-TypeがText/のときには、CharSetに基づいてコード変換が行われると示唆されています。
つまりContent-TypeがJSONの場合には、自動的な変換がされないということになります。
本当は、Content-TypeがJSONの時も変換してくれるのが一番良い(わかりやすい)のですが、残念ながらそうなっていません。
その代わりにパラメータが用意されています。
RESTのディスパッチクラスの定義に以下のパラメータを追加することで、自動コード変換を行なってくれます。
Parameter CONVERTINPUTSTREAM = 1;
Embedded Pythonの導入に伴い、1つ嬉しいことは、直接エクセルファイルの読み書きができるようになったことです。
それでこの機能を使って、ミニ業務改革をちょこちょこ行なっているのですが、そこでちょっとハマったことを共有します。
実際この内容は実はIRISとは全く関係ないのですが、このDCコミュニティの皆さんが同じことでハマった場合に少しでも早く問題解決できるように情報共有します。
エクセルの計算式の入ったセルの値を読み取るときには、そのファイルのオープンの際にdata_only=Trueというフラグをつけないといけないのですが、そのファイルがopenpyxlで読み書きしたファイルの場合に、その計算式のセルの値(Noneとなる)がうまく読めないことがあります。
その場合には、そのファイルをエクセルで開いて再保存することで、正しく読むことができます。
以下にそのあたりの内容を説明したページがあります。
これは、InterSystems FAQサイトの記事です。
これは、MS-ACCESSの制限事項です。
MS-ACCESSは、インデックスが32個より多いテーブルにはリンクできません。
この問題を回避する方法として、直接テーブル(クラス)をリンクするのではなく、VIEWを使用する方法があります。
これは InterSystems FAQ サイトの記事です。
ロックテーブルの1エントリは管理領域の固定512 bytesとロック文字列情報などの可変領域から構成されます。
可変領域はロック対象のグローバルノード名に関連する情報に必要な長さ(bytes)になります。
1つのLockコマンドにつき、上記で示した長さのデータが必要です。
そしてその可変領域に必要なデータ長は、ロック対象のグローバルノード名(^xxx(xxx,xxx)) の長さに見合う16,32,64,128,256,…bytesのバケットの長さになります。
例えばロック対象のグローバルノード名が^xxx(123,"data")とすると、 ^xxx(123,"data")にデータのロケーション等のデータが付加されたものがその可変領域となり、32byteまたは64bytes(データロケーションが相応に長い場合)のバケットを使用しますので、
このロックで使用するデータサイズが、64byteのバケットを使用すると仮定すると、
512(固定領域)+ 64 (可変領域)= 576 bytes
となります。
これは InterSystems FAQ サイトの記事です。
IRIS2023.1から導入されたgmheapとlocksizの新しいデフォルト値について紹介します。
gmheap=0は、特別な設定の必要性がないほとんどのシステム(実運用システムを含む)に適切なように設計された新しいデフォルト値です。
0に設定することで、システムがシステム全体のサイズを推測し、妥当な値を算出してくれます。
gmheap=0 に設定した場合、システムは、グローバルバッファ用に設定されたメモリの合計に3%を乗じた値を基準に、300MBの下限と2GBの上限の範囲内でgmheap値を設定します。
0以外の値はそれをそのまま使用し、2GBよりはるかに大きく、あるいは300MBよりはるかに小さく設定することができます。
(ただし、小さな値を設定した場合、メモリを必要とする機能の利用が失敗する可能性があります。 同様に極端に大きな値を設定することでシステムに悪影響を与える可能性があります)
さらにこの変更以前は、.cpfファイルのgmheap設定に加えて、CPUスレッド数 に2MBを掛けた値をシステムが内部的に追加していました。
このため、異なるシステムに構成を移動するときや、物理メモリの使用量を理解しようとするときに混乱を招くことがありました。
これは InterSystems FAQ サイトの記事です。
PythonからObjectScriptのルーチンを直接呼び出すことはできませんが、クラスメソッドを経由して間接的に呼び出すことができます。
しかし、Pythonの変数とObjectScriptのローカル変数は内部構造が異なるため、情報の交換には少し工夫が必要です。
簡単なサンプルでその方法について説明します。
まず、2つの変数を足し算する簡単なルーチン ^testを作ります。
TEST ;set次にこの^testを呼び出すPythonのメソッドを含んだUser.testというクラスを作ります。
そしてpyという名前のPythonのメソッドを作成します。
先述の通りPythonからObjectScriptのルーチンを直接呼び出すことはできないので、ルーチンを間接的に呼び出すObjectScriptのメソッドを作成する必要があり、そのメソッドをPythonメソッドから呼び出すようにします。
渡したいデータが複数個ある場合、その数分引数を用意するのは面倒なため、Pythonの場合、情報をまとめて交換する際にdictionary(辞書)やlistという構造を使用することができます。
ここでは、dictionaryを使用する例を紹介します。
ClassMethod py() [ Language = python ]
{
これは InterSystems FAQ サイトの記事です。
messages.logまたはcconsole.log内に記録されるCSPGatewayLatencyのメッセージは、サーバが、パフォーマンス測定のため定期的に「CSPゲートウェイにリクエストを送信して応答をもらう」ことを行っており、応答を受け取るまで一定時間以上かかったときに出る警告(応答時間の閾値)です。
その既定値は1000ミリ秒です。
WebGateway(CSPGateway)が稼働する Web サーバの負荷が高い場合に出力する場合がありますが、実際のCSPアプリケーションやREST APIの動作や応答速度に影響が見られなければ、特に問題はありません。
またこのメッセージの出力頻度を下げるためにこの閾値を変更する方法もあります。
変更方法は以下を参照ください
これは InterSystems FAQ サイトの記事です。
404エラーが返される場合に、以下の対応でエラーが解消されることがわかっています。
(1) binの接続を許可
/cspの構成エディタ>セクションで以下選択
system.webServer > security > requestFiltering
> hiddenSegmets 選択 > (コレクション)の右欄(Count=xx)の右端 [...] クリック
> segment欄に binの行があったので、選択して削除
> 画面戻って、右上の [適用] クリック
または、IISの構成ファイルを直接編集することでも対応可能です。
C:\Windows\System32\inetsrv\config\applicationHost.config
これは InterSystems FAQ サイトの記事です。
以下のようなベンチマーク関連の情報が公開されています。
Intel社と共同で実施したパフォーマンス(レイテンシー)とスケーラビリティ(スループット)を計測するベンチマーク結果
ESG社によるIRISと他社データベースとの性能比較に関するレポート
ウルシステムズ社が実施したAWS AuroraとIRISの性能評価結果
オープンソースのベンチマークプログラム
WinterCorp社のベンチマークレポート
様々なハードウェア上で実施したベンチマーク結果を公表
開発生産性の評価に関連するレポート
これは InterSystems FAQ サイトの記事です。
インスタンスの開始が失敗し、コンソールログに"There exists a MISMATCH.WIJ file"が記録されている場合、何らかのシステム障害の影響でデータベースの整合性に関して問題が生じていることを示しています。
このような状況が発生した際にインスタンスの開始ができるようにするためには、以下の手順を実施します。
(1) a. インスタンスをNOSTUモードで起動 注1:
(2) b. データベースの整合性チェック
◆(2)の整合性チェックでエラーを検出しなかった場合、
(3) d. MISMATCH.WIJ ファイルのリネーム
(4) e. インスタンスの再起動
を実施します。
◆(2)の整合性チェックでエラーが検出された場合は、
(3) c. MISMATCH.WIJファイルの適用
(4) b. データベースの整合性チェック
(5) d. MISMATCH.WIJファイルのリネーム
(6) e. インスタンスの再起動
を実施します。
以下に各手順の詳細を説明します。
a. インスタンスをNOSTUモードで起動します。
以下に記載の手順の内、1)および2)の手順まで実行します。
3)以降は実施する必要はありません。
これは InterSystems FAQ サイトの記事です。
まず以下のようなREST APIを定義したクラスを作成します。
ClassExtends"/req1"次にこのREST APIを呼び出すHTMLファイル(test.html)を作成します。
htmlng-app
function($scope, $http)functionこれは InterSystems FAQ サイトの記事です。
Embedded Pythonでトランザクションを実装するために、以下のようなAPIが用意されています。
import詳細はドキュメントをご覧ください。
これは InterSystems FAQ サイトの記事です。
以下は、EXCELのシートから指定したセルのデータを取得してその値を返すメソッドの例です。
Class User.test
{
ClassMethod getSheetValue(n, m) As %String [ Language = python ]
{
# n行目 m列 のデータを戻す'c:/temp/a.xlsx'これは InterSystems FAQ サイトの記事です。
$ZF(-100)で外部コマンドを実行する場合、その外部コマンドの子プロセスからの応答が返らない限り、$ZF(100)コマンドを発行したIRISプロセスはその応答を待って残り続けます。
従ってIRISプロセスを終了させるためにはその応答がない子プロセスを強制終了させる必要があります。
InterSystems IRISのSQLの性能を評価する簡単なベンチマークテストを公開します。
また、このベンチマークプログラムで測定した過去の様々なハードウェアでのベンチマーク結果も公開します。
ハードウェアの進歩、インターシステムズの新しいテクノロジーの追加や性能改善によって、性能が劇的に変化しています。
現在のハードウェアの性能を考慮すると、少し物足りない感じが否めないですが、過去との結果の公正な比較という意味であえて、データの規模に関しては過去と同一条件でベンチマーク実施した結果となっています。
データの規模に関してはデータ件数を増やすことで変更できるようになっています。(現時点では500万件)
またこのベンチマークプログラムはインターシステムズ製品用に実装されていますが、使用しているテーブル構造は比較的シンプルなもので、また使用しているSQL文も標準的なものなので、他データベースシステムでも同じベンチマークを実施することはそんなに困難ではありません。
最後にCSP機能の中でReactでうまく置き換えできなかった処理について紹介します。
該当する処理は、サーバー上の商品データに含まれるその商品の画像データ(GIF形式)を取得して、ブラウザにイメージとして描画させるものです。
CSPにはStreamServer.clsというサーバー側で動作する機能が用意されています。
この機能を使ってデータベース上に格納されているストリームデータをHTML IMGタグで処理できる形式に変換してくれます。
Reactで同様の機能を実現する方法が見つからなかったため(そもそもReactはサーバーサイドではなくクライアント上の技術なので)、データベース内に格納されているイメージを取得するのではなく、静的なイメージファイルをウェブサーバーが参照可能な場所に置くことで解決しました。