IBM Support

[Db2] C ルーチンのデプロイ方法と置き換え方法

Question & Answer


Question

C ルーチンをデプロイする際の手順と、ルーチンのライブラリーを置き換える際の手順を教えてください。

Answer

C ルーチンは、C 言語でロジックを実装したプロシージャーやユーザー定義関数です。
SQL によりルーチンが呼び出されると、関連付けられたプログラム・コード上の関数が呼び出されます。

FENCED として定義されると、ルーチンは Fenced モード・プロセス (db2fmp) 内で、Fenced ユーザーの権限により実行されます。
NOT FENCED として定義されると、ルーチンは Db2 システム・コントローラー・プロセス (db2sysc/db2syscs.exe) 内で (※)、Db2 インスタンス・オーナーの権限により実行されます。
また、THREADSAFE として定義されると、ルーチンはプロセス内の各スレッドで実行されます。
(※) V9.1 までの Unix/Linux 版は Db2 エージェント・プロセス (db2agent) 内

デプロイ方法
  1. ルーチンのコンパイル
    作成した SQC ファイルをプリコンパイルして、バインド・ファイルとプリコンパイルされた C ファイルを作成します。バインド・ファイルは、配置先のデータベースへバインドします。C ファイルは、C コンパイラーを使ってコンパイルします。
    以下は AIX 環境でサンプルとして用意されたルーチンをコンパイルする際の実行例です。
    $ db2 connect to SAMPLE
    $ db2 "PREP spserver.sqc BINDFILE"
    $ db2 "BIND spserver.bnd"
    $ xlc_r -q64 -I$HOME/sqllib/include -c spserver.c
    $ xlc_r -q64 -qmkshrobj -o spserver spserver.o -ldb2 -L$HOME/sqllib/lib64
  2. ライブラリーの配置
    外部ルーチンを含むライブラリー・ファイルを function ディレクトリーにコピーします。
    UNIX/Linux の場合、fenced ルーチンの function ディレクトリーは $INSTHOME/sqllib/function となり、unfenced ルーチンの function ディレクトリーは $INSTHOME/sqllib/function/unfenced となります。$INSTHOME はインスタンス・オーナーのホーム・ディレクトリーを指します。
    Windows の場合、LIBPATH または PATH 環境変数に指定されたディレクトリー・パスが function ディレクトリーとなります。
    $ cp ./spserver $HOME/sqllib/function
  3. データベースへルーチン定義の登録
    CREATE PROCEDURE もしくは CREATE FUNCTION ステートメントで、ルーチンの定義を作成します。EXTERNAL NAME には、コピーしたライブラリー・ファイルのパス (function ディレクトリーからの相対パス) とルーチンとして呼び出す関数名を指定します。
    ルーチンがコンパイラーにより C++ としてコンパイルされた場合、関数名はマングル (修飾) されています。その場合は、EXTERNAL NAME にはマングルされた関数名を指定するか、もしくは関数を C 言語として解釈するよう extern "C" を加えてコンパイルし、マングルされないようにしてください。
    $ db2 "CREATE PROCEDURE OUT_LANGUAGE (OUT language CHAR(8)) LANGUAGE C READS SQL DATA EXTERNAL NAME 'spserver!OutLanguage' PARAMETER STYLE SQL"
  4. ルーチンの挙動の確認
    デプロイしたルーチンを実行して正常に動作することを確認します。
    $ db2 "CALL OUT_LANGUAGE(?)"
    
      出力パラメーターの値
      --------------------------
      パラメーター名: LANGUAGE
      パラメーター値: C
    
      リターン状況 = 0
置き換え方法

データベース・マネージャー構成キーワード KEEPFENCED が NO であり、スレッド・セーフではない FENCED ルーチンの場合、function ディレクトリーのライブラリー・ファイルを置き換えることで、ロードされるライブラリーを変更することができます。
この条件に当てはまらない場合、ロードされたライブラリーがキャッシュされるため、既存のライブラリー・ファイルを置き換えて新しいライブラリーをロードさせるためにはインスタンスの再起動が必要です。
ライブラリー・ファイルの置き換えは、必ずインスタンスの停止中に行ってください。

インスタンスの再起動をせずにルーチンが利用するライブラリーを変更するためには、以下のように別名で作成された新しいライブラリー・ファイルを参照するようルーチン定義を更新する必要があります。
 
  1. ルーチンのコンパイル
    デプロイ時と同様、ルーチンをコンパイルします。
    既存のパッケージとは別パッケージとしてバインドするよう、バインド・ファイルの名前を変更してプリコンパイルします。
    以下は AIX 環境でルーチンをコンパイルする際の実行例です。
    $ db2 connect to SAMPLE
    $ db2 "PREP spserver.sqc BINDFILE USING spserver2.bnd"
    $ db2 "BIND spserver2.bnd"
    $ xlc_r -q64 -I$HOME/sqllib/include -c spserver.c
    $ xlc_r -q64 -qmkshrobj -o spserver spserver.o -ldb2 -L$HOME/sqllib/lib64
  2. ライブラリーの配置
    新しく作成したライブラリー・ファイルを、別名で function ディレクトリーにコピーします。
    $ cp ./spserver $HOME/sqllib/function/spserver2
  3. ルーチン定義の更新
    ALTER PROCEDURE もしくは ALTER FUNCTION ステートメントで、EXTERNAL NAME に別名でコピーしたライブラリー・ファイルを指定し、ルーチン定義を更新します。
    $ db2 "ALTER PROCEDURE OUT_LANGUAGE (CHAR(8)) EXTERNAL NAME 'spserver2!OutLanguage'"

運用上の考慮点
  • 手順では Db2 のサンプル・プログラムとして提供されるファイル (sqllib/samples/c/spserver.sqc) を利用しています。
  • fenced ルーチンまたは unfenced ルーチンであるかは、SYSCAT.ROUTINES カタログ・ビュー FENCED 列の Y (YES) または N (NO) から判断可能です。スレッド・セーフであるかは、SYSCAT.ROUTINES カタログ・ビュー THREADSAFE 列の Y (YES) または N (NO) から判断可能です。
    $ db2 "SELECT FENCED,THREADSAFE FROM SYSCAT.ROUTINES WHERE ROUTINESCHEMA='V97FP3' AND ROUTINENAME='OUT_LANGUAGE'"
    
    FENCED THREADSAFE
    ------ ----------
    Y      N
    
      1 レコードが選択されました。
関連情報
外部ルーチンのライブラリーおよびクラスの管理
外部ルーチン・ライブラリーおよびクラスのデプロイメント
外部ルーチンのライブラリーおよびクラス・ファイルに対する変更
Db2 ルーチンの共用ライブラリーの再構築
C++ のタイプ修飾
SYSCAT.ROUTINES カタログ・ビュー
 
お問合せ先
技術的な内容に関して、パスポート・アドバンテージの契約のもと Db2 テクニカル・サポートへお問い合わせください。
Db2 テクニカル・サポート

[{"Type":"MASTER","Line of Business":{"code":"LOB10","label":"Data and AI"},"Business Unit":{"code":"BU058","label":"IBM Infrastructure w\/TPS"},"Product":{"code":"SSEPGG","label":"Db2 for Linux, UNIX and Windows"},"ARM Category":[{"code":"a8m500000008PmjAAE","label":"Routines - Stored Procedures and UDF-\u003EJava\/Non-SQL Routines"}],"ARM Case Number":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"All Versions"}]

Document Information

Modified date:
25 August 2023

UID

swg21574461