# CHAPTER 2: | # パーシステントストアードモジュール

## 2.1 はじめに

Empressの重要な１つの機能として、データベースに ユーザーが定義した関数やオペレータ、ストアードプロシージャおよびトリガーを スキーマのオブジェクトとして格納することをユーザーに提供します。 これらのオブジェクトは、 SQL 文およびアプリケーションプログラムから実行されることができます。

ストアードプロシージャは、どのようなクライアントからでも実行することができる 手続き上のデータベースオブジェクトです。

トリガーは、イベントが発生した場合や条件を満たす場合に自動的に実行される ストアードプロシージャの特別なタイプです。 一般的にトリガーは、追加、更新、削除のようなデータベースのイベントと 関連付けられます。

PSMが Empress RDBMSにとって非常に有益な改良である理由は以下になります。

1. アプリケーションプログラムのための構造的なデバイスととして使用することができ、 パフォーマンスを向上することができます。

   多くのアプリケーションプログラムの場合、結果を得るために ある回数、データベースアクセスの実行を行います。 このプログラムが、クライアント・サーバー環境上で繰り返し実行を要求した場合、 ネットワークのオーバーヘッドによって時間を浪費することになります。 このプログラムをサーバー側で実行することで、より効果的になります。 これを行う1つの方法として、プロシージャのプログラムを記述し、 スキーマ定義の一部としてデータベース内に格納します。 この方法は、パフォーマンスが向上するだけでなく、 アプリケーションプログラムがより構造化されます。

2. ユーザーの特別な要求に合わせるために RDBMS の機能を拡張する強力なツールです。

   Empressは、 標準のディストリビューションに含まれる 多くの関数およびオペレータを提供しています。 (詳しくはEmpress SQL: リファレンスマニュアルの 関数を参照してください。) しかし、データを操作するための追加の機能が必要な場合、 ユーザーの特別な要求を満足させるために ユーザー定義関数機能によってEmpressの機能を 拡張することができます。 パーシステントストアードモジュールは、 EmpressRDBMS へ簡単にユーザー定義関数を組み込むための インターフェイスを提供します。

## 2.2 パーシステントストアードモジュールの作成方法

このセクションでは、 ダイナミックローダブルライブラリおよびスタテックライブラリとして、 パーシステントストアードモジュールにユーザー定義関数(UDF)を 組み込む方法を記述します。

### 2.2.1 ダイナミックローディングのパーシステントストアードモジュール

ここでは、ダイナミックローダブルライブラリとして、 パーシステントストアードモジュールにユーザー定義関数(UDF)を 組み込む方法を記述します。

1. Ｃプログラムファイルを作成します。

   例えば`/usr/joe`ディレクトリに Ｃプログラムファイル`fact.c`が置かれていると仮定します。 このファイルには、1つのパラメータを受け取り、その階乗の計算を実行し、 結果を返す`factorial`関数が含まれます。

          long  factorial(long num)
          {
             int   i;
             long  res=1;

             for (i=1; i<=num; i++)
                res *= i;

             return (res);
          }

2. `emppsmcc`を使って、 ソースファイルをコンパイルし、シェアードオブジェクトファイルを作成します。

   `fact.c`のコンパイルと`fact.dll`のシェアードオブジェクトの作成は 以下になります。

          emppsmcc -o fact.dll fact.c

   ソースファイルに Empress データベースをアクセスするための Empress のルーチンが含まれている場合（例えばmrルーチンのような） 同じコマンドを使用することができます。

3. Empress RDBMS へ UDF を組み込むために `CREATE MODULE`と`UPDATE MODULE`コマンドを使用します。

   以下のステップは、 PSM としてデータベースへ 外部関数`fact`を格納する方法です。 一度、これが完了すれば、 `fact`は、そのデータベースのEmpressの関数となり、 `DROP MODULE`コマンドが発行されるまでキーワードは有効です。

   オペレーティングシステムのプロンプトから Empress 対話型 SQLセッションを呼び出します。

          empsql db_name

   対話型 SQLセッション内で、以下のSQL コマンドを発行します。

          CREATE MODULE module_fact
             FUNCTION fact (GENERIC INTEGER) RETURNS GENERIC INTEGER
             EXTERNAL NAME factorial;
          END MODULE;

          UPDATE MODULE module_fact
             FROM "/usr/joe/fact.dll"

これでSQL 文から`fact`関数を使用することができます。 例えば、

       SELECT attr1, attr2, fact(attr2) FROM table_name;

       SELECT fact(attr1) - fact<attr2) PRINT "Differences"
          FROM table_name;

ユーザー定義関数は、また`WHERE`句の条件式中でも使用することができます。

       SELECT * FROM table_name
          WHERE attr1 * 1000 > fact(attr3);

`attr1`および`attr2`、`attr3`は `table_name`テーブルの数値アトリビュートです。

Empressは、いくつかの場所でユーザー定義関数を使用することができます。

1. Empress SQL内の以下の箇所で使用することができます。

- `SELECT`文のアイテムリスト
- `WHERE`句の条件式
- `INSERT`, `DELETE`および`UPDATE`文のアトリビュート値

これらの用法は、Empressのビルトイン関数と同じです。

2. Empress 4GL内の以下の箇所で使用できます。

- `SELECT`文のアイテムリスト(バージョン4.6 の次から）
- `WHERE`句の条件式
- `INSERT`, `DELETE`および`UPDATE`文のアトリビュート値
- `CALL`文
- 関数のコール

用法は、Empressのビルトイン関数および4GLプロシージャ と同じです。

3. Empress Report Writer内の以下の箇所で使用できます。

- `SELECT`文のアイテムリスト
- `WHERE`句の条件式
- `INSERT`, `DELETE`および`UPDATE`文のアトリビュート値

これらの用法は、Empressのビルトイン関数と同じです。

4. Empress Hypermedia(Internet Application Toolkit) 内の以下の箇所で使用できます。

- `SELECT`文のアイテムリスト
- `WHERE`句の条件式
- `INSERT`, `DELETE`および`UPDATE`文のアトリビュート値

これらの用法は、Empressのビルトイン関数と同じです。

ユーザー定義関数はまたmrの expression ルーチンによる式の構築を通して C プログラムからも使用することができます。 (詳しくは Empress ホスト言語: C カーネルレベルインターフェイス mr ルーチンを参照してください。)

### 2.2.2 スタテックリンクのパーシステントストアードモジュール

動的なシェアードライブラリのロードが有効ではないプラットフォームの 場合（例えばQNX)、ユーザーはユーザー定義関数の呼び出しおよび定義 するために静的にPSMをリンクすることができます。

> 動的なシェアードライブラリのロードが有効なプラットフォームの場合、 静的なパーシステントストアードモジュールのリンクは動作しません。 現在のところ、２，３のプラットフォームのみが 静的なパーシステントストアードモジュールのリンクを使用することが必要です。

ここでは、静的なリンク環境上で パーシステントストアードモジュールに ユーザー定義関数(UDF)を 組み込む手順を示します。

1. システムエディタを使用してＣプログラムソースファイルを作成します。

   サンプルの関数として、階乗計算を実行する関数を `/usr/joe`というディレクトリに `fact.c`ファイルに記述します。 この関数は、1つのinteger の引数を取り、long integer の値を返します。

          long  factorial(long num)
          {
             int   i;
             long  res=1;

             for (i=1; i<=num; i++)
                res *= i;

             return (res);
          }

2. `emppsmcc`を使って、 ソースファイルをコンパイルし、ライブラリファイルを作成します。

   `fact.c`をコンパイルし、`fact.a`ライブラリを作成は、 以下のように行います。

          emppsmcc -o fact.a fact.c

3. Empress RDBMS へ UDF を組み込むために `CREATE MODULE`と`UPDATE MODULE`コマンドを使用します。

以下の手順は、 PSM としてデータベースへ 外部関数`fact`を格納する方法です。 一度、登録すれば、 `fact`は、そのデータベースのEmpressの関数となり、 `DROP MODULE`コマンドが発行されるまでキーワードは有効です。

対話型 SQLセッション内で、以下のSQL コマンドを発行します。

       CREATE MODULE module_fact
          FUNCTION fact (GENERIC INTEGER) RETURNS GENERIC INTEGER
          EXTERNAL NAME factorial;
       END MODULE;

       UPDATE MODULE module_fact
          FROM "/usr/joe/fact.a"

動的なローディングの PSM と異なっている点は、 この関数は、実行形式のファイル中に明示的にリンクされるまで 有効ではありません。

4. 実行形式のファイルを作成します。

   Empressシステム管理者から、以下の操作をすることで すべてのユーザーに対して、この関数を有効にすることができます。

   最初にライブラリを再構築します。

          cd $EMPRESSPATH/rdbms/custom/src/usrfns
          ./mklib db_name

   次に実行形式のファイルを作成します。 例えば、`empsql`コマンドに対して`fact`を有効にする ためには、以下のように行います。

          cd $EMPRESSPATH/rdbms/conf_bin
          ./mkexec empsql

   `$EMPRESSPATH/rdbms/custom/src/usrfns/mklib`コマンドは、 システムライブラリを修正するために使用することに注意してください。 （このコマンドの発行はEmpressシステム管理者であることが必要です。） このコマンドは以下の構文になります。

          mklib [db_name ... ]

   システムライブラリに追加するモジュールが含まれる データベース名のリストを引数にとります。

5. これで`empsql`内で関数`fact`を使用することができます。

   オペレーティングシステムから以下のようにEmpress 対話型 SQLセッションを起動します。

          empsql db_name

   対話型 SQLセッション内で、以下の SQL コマンドが実行できます。

          SELECT attr1, attr2, fact(attr2) FROM table_name;

          SELECT fact(attr1) - fact<attr2) PRINT "Differences"
             FROM table_name;

   また、`WHERE`句内では以下のように使用します。

          SELECT * FROM table_name
             WHERE attr1 * 1000 > fact(attr3);

   `attr1`および`attr2`、`attr3`は `table_name`テーブルのアトリビュートです。

## 2.3 パーシステントストアードモジュール SQL コマンド

以下はパーシステントストアードモジュール SQL の一覧です。

表 2-1 SQL/PSM コマンド

コマンド | 説明
`CREATE MODULE` | このコマンドは、データ辞書へモジュール定義を格納するために使用されます。 これは、ユーザー定義の関数、オペレーション、プロシージャ、または集計関数の ためのエントリポイントを作成します。 また、モジュール定義をロード可能なシェアードライブラリモジュールとリンクするために `UPDATE MODULE`コマンドは必要です。
`UPDATE MODULE` | このコマンドは、 モジュール定義をロード可能なシェアードライブラリモジュールとリンクするために 使用されます。
`DROP MODULE` | このコマンドは、データベースのデータ辞書からモジュール定義を削除します。 モジュールとして定義されていた、関数、およびプロシージャ、オペレータは Empressから認識されなくなります。
`DISPLAY MODULE` | このコマンドは、データベースのデータ辞書からモジュール定義を取得し、表示します。
`CREATE TRIGGER` | このコマンドは、データ辞書にトリガー定義を登録するために使用されます。 定義行うとトリガーは自動的に有効になります。 `ALTER TABLE` コマンドは、トリガーを一時的に無効化するために使用することが できます。（必要なときに有効にすることができます。）
`DROP TRIGGER` | このコマンドは、データ辞書からトリガーの定義を削除するために使用されます。
`ALTER TABLE` | このコマンドは、トリガーの動作を有効にするかあるいは無効にするかを指定するために 使用します。また、トリガーの優先順位を変更にも使用されます。
`CREATE COMMENT` | このコマンドは、モジュールおよびトリガーのコメントを付けるために使用されます。
`DROP COMMENT` | このコマンドは、モジュールおよびトリガーのコメントを削除するために使用します。

これらのコマンドの詳細は A4: SQL リファレンスマニュアルを参照してください。

## 2.4 パラメータスタイル

`CREATE MODULE`コマンドでユーザー定義関数を宣言する場合、 その関数のパラメータのリストと戻り値のタイプを指定します。 例えば、

       DECLARE FUNCTION funct1 (integer, IN float)
          RETURNS INTEGER
          EXTERNAL NAME func2
          PARAMETER STYLE GENERAL;

パラメータリストは、`PARAMETER STYLE GENERAL`および `PARAMETER STYLE SQL`の2つのスタイルのうち1つを指定することができます。 これらは以下に定義されます。

- PARAMETER STYLE GENERAL

  ユーザー定義関数に渡すこのパラメータのスタイルは、 有効なパラメータタイプのリストが、 明示的に述べられたことと同じ意味になります。 ヌル値は、`IN` または `INOUT` モードの パラメータタイプで制限されます。

- PARAMETER STYLE SQL

  ユーザー定義関数に渡すこのパラメータのスタイルは、 有効なパラメータタイプのリストが、以下のように定義されたことを 意味します。

  - 最初のnのパラメータは、nの明示的な定義になります。 パラメータモードは、定義したものです。

  - ルーチンが、関数、オペレータ、および集計関数である場合のみ、 次のパラメータは、返される結果と対応する出力パラメータになります。 パラメータモードは`OUT`です。

  - 次のnパラメータが（n+1、ルーチンが関数、オペレータか集計関数である場合） 最初のn (またはn+1)のパラメータを伴う 1 : 1 で対応する ヌル指示子パラメータです。 パラメータモードは、最初のnパラメータに定義された値になります。

  - 次のパラメータは`INOUT`パラメータです。 ルーチンの成功、または失敗を示します。 そのデータタイプは、長さ５文字の文字タイプです。

  - 次は`IN`パラメータです。 これは、実行するための外部ルーチン名を渡すために使用されます。

  - 次のパラメータは、パラメータモード`IN`で、 実行するための特別な外部ルーチン名を渡すために使用されます。

  - 最後のパラメータは、パラメータモード`INOUT`で、 診断エリアに配置するためのメッセージテキストです。

`PARAMETER STYLE GENERAL` パラメータスタイルは、 名前によって指示されるため、より一般的で使用することが簡単ですが、 ヌル値を扱えないため、融通性はよくありません。 `PARAMETER STYLE SQL`は、ユーザーに多くの制御を提供します。

## 2.5 データタイプの対応

Empressは、パラメータタイプと戻り値のための 以下の３つのグループのデータタイプを認めます。

- 汎用データタイプ
- Empress SQL (MS) データタイプ
- C データタイプ

汎用データタイプは、パラメータによってバインドされないデータを表します。

MS データタイプは、パラメータによってバインドされるデータを表します。 例えば、`CHAR`データタイプは、lengthとtypeのパラメータを 受け取ります MS データタイプは、特別な汎用データタイプと関連付けらています。 例えば、MS データタイプ`DATE`, `TIME` および `MICROTIMESTAMP`は、 以下の C の構造体定義された汎用データ`gen_date`に基づいています。

       typedef  struct
       {
               long    gen_year;      /* actual year. e.g. 1999, 2000, etc */
               long    gen_month;     /* 1 to 12. 1 = January, ... */
               long    gen_day;       /* 1 to 31 */
               long    gen_hour;      /* 0 10 23 */
               long    gen_minute;    /* 0 to 59 */
               long    gen_second;    /* 0 to 59 */
               long    gen_microsec;  /* 0 to 999999 */
       } gen_date;

この関連付けは、それが基づいている汎用データタイプとして、 同じ処理ルーチンを使用するためにMS データタイプを含む処理を することを認めます。

`gen_binary`は、以下の C 構造体で定義されています。

       struct  gen_binary_segment
       {
               long    data_len;       /* length of binary data in segment */
               msbyte* data;           /* binary data */
               long    reserved[6];
       };

       typedef struct  gen_binary_segment      gen_binary_segment;

       struct  gen_binary
       {
               long    total_data_len; /* total length of binary data */
               int     flags;          /* bit arrray of flags */
               int     num_segments;   /* number of segments, typically 1 */

               gen_binary_segment segment [1 /* actually: num_segments */];
       };

       typedef struct  gen_binary              gen_binary;

       #define  GEN_BINARY_SEGMENTS_ALLOCATED  (1 << 0)

この構造体は、`$EMPRESSPATH/include/usrfns/generic.h`ファイルに 定義されています。

注意

1. `total_data_len` は、 それぞれの`gen_binary_segment`の`data_len`の合計にする 必要があります。

2. `GEN_BINARY_SEGMENTS_ALLOCATED`にフラグ設定されている場合、 セグメントデータは、個別のバッファにアロケートされていることを 意味します。設定されていない場合は、セグメントデータは、解放されない スタテックなバッファを意味します。

C プログラムデータタイプ構成(`$EMPRESSPATH/include/usrfns.h`ファイルに 定義されています。）とEmpress ユーザー定義関数 への対応は、以下になります。

表 2-2 汎用データタイプとUDF C プログラムデータタイプの対応

汎用データタイプ | UDF C Program Data Type (戻り値/パラメータモード `IN`) | UDF C Program Data Type (パラメータモード `OUT`/`INOUT`)
`GENERIC CHAR` | `char *` | `char **`
`GENERIC INTEGER` | `long` | `long *`
`GENERIC DECIMAL` | `gen_dec` | `gen_dec *`
`GENERIC FLOAT` | `double` | `double *`
`GENERIC DATE` | `gen_date` | `gen_date *`
`GENERIC BOOLEAN` | `int` | `int *`
`GENERIC EXTERNAL` | `char *` | `char **`
`GENERIC INTERVAL` | `gen_date` | `gen_date *`
`GENERIC BINARY` | `gen_binary *` | `gen_binary **`

Table 2-3 MS データタイプとUDF C プログラムデータタイプの対応

MS データタイプ | UDF C プログラムデータタイプ
`CHAR` `CHARACTER` | `char *`
`SHORTINTEGER` `SMALLINT` | `short *`
`INTEGER` `INT` | `long *`
`LONGINTEGER` | `long *`
`DATE` | `gen_date *`
`DOLLAR` | `gen_dec *`
`REAL` | `float *`
`LONGFLOAT` `DOUBLE PRECISION` | `double *`
`FLOAT` | If decimal places <= 6: `float *` If decimal places > 6: `double *`
`TEXT` | `char **`
`BULK` | `gen_binary **`
`DECIMAL` `DEC` | `gen_dec *`
`TIME` | `gen_date *`
`NLSCHAR` `NLSCHARACTER` | `char *`
`NLSTEXT` | `char **`
`WON` | `gen_dec *`
`MICROTIMESTAMP` | `gen_date *`

表 2-4 C データタイプ と UDF C プログラムデータタイプ

C データタイプ | UDF C プログラムデータタイプ (戻り値/パラメータモード`IN`) | UDF C プログラムデータタイプ (パラメータモード `OUT`/`INOUT`)
`"C char"` | `char` | `char *`
`"C schar"` | `signed char` | `signed char *`
`"C uchar"` | `unsigned char` | `unsigned char *`
`"C short"` | `short` | `short *`
`"C ushort"` | `unsigned short` | `unsigned short *`
`"C int"` | `int` | `int *`
`"C uint"` | `unsigned int` | `unsigned int *`
`"C long"` | `long` | `long *`
`"C ulong"` | `unsigned long` | `unsigned long *`
`"C float"` | `float` | `float *`
`"C double"` | `double` | `double *`
`"C string"` | `char *` | `char **`
`"C string_static"` | `char *` | `char **`

注意: いくつかのコンパイラでは、 パラメータモード`IN`の`"C float"`は、 機能しないことがあります。 この場合、パラメータモード`IN`の`"C float"`の使用を 避けるようにしてください。

## 2.6 エラーメッセージ

このセクションでは、PSMの構文とユーザーエラーメッセージのリストと 簡単な説明を示します。

### 2.6.1 構文エラーメッセージ

`モジュール指定が必要です。`

  `CREATE MODULE`コマンドを発行した際にモジュール名が指定されていません。

`モジュール名が必要です。`

  `DROP MODULE`コマンドを発行した際にモジュール名が指定されていません。

`言語指定が必要です。`

  `CREATE MODULE` コマンドの`LANGUAGE`オプションを発行した際に言語が指定されていません。

`言語パラメータが必要です。`

  `CREATE MODULE`コマンドの`LANGUAGE`オプションを発行した際に 括弧の後に言語パラメータが指定されていません。

`システム指定が必要です。`

  `UPDATE MODULE`コマンドの`FOR system_name`オプションを発行した際に システム名が指定されていません。

`DLL ファイル指定が必要です。`

  `UPDATE MODULE`コマンドを発行した際に DLL ファイル名が指定されていません。

`SQL での起動ルーチン名が必要です。`

  `CREATE MODULE`コマンドでのSQL起動ルーチンの宣言で、 正しいルーチン名が指定されていません。

`オペレータクラスが必要です。`

  `CREATE MODULE`コマンドの`OPERATOR`の宣言で、 オペレータのためのオペレータクラスが指定されていません。 (例えば`PREFIX`, `POSTFIX` など)

`パラメータ指示が必要です。`

  `CREATE MODULE`コマンドのSQL起動ルーチンの宣言で、 パラメータリストが正しく指定されていません。

`返り値のデータタイプが必要です。`

  `CREATE MODULE`コマンドの `FUNCTION`、`OPERATOR`および `AGGREGATE FUNCTION`の宣言で、`RETURNS`キーワードの後の 返り値のデータタイプが指定されていません。

`返り値指定が必要です。`

  `CREATE MODULE`コマンドの `FUNCTION`、`OPERATOR`および `AGGREGATE FUNCTION`の宣言で、返り値のデータタイプが指定されていません。

`external指定が必要です。`

  `CREATE MODULE`コマンドのSQL起動ルーチンの宣言で、 external指定が見つかりません。（すなわちキーワード`EXTERNAL`)

`外部ファンクション名が必要です。`

  `CREATE MODULE`コマンドのSQL起動ルーチンの宣言で、 `EXTERNAL`キーワードの後の指定が正しくありません。

`パラメータスタイルの指示が必要です。`

  `CREATE MODULE`コマンドのSQL起動ルーチンの宣言で、 パラメータスタイル指定が正しくありません。 (`PARAMETER STYLE SQL` または `PARAMETER STYLE GENERAL`のいずれか)

`ワークスペースの指示が必要です。`

  `CREATE MODULE`コマンドの`ALLOCATE WORKSPACE`オプションで ワークスペースのサイズなしで指定されています。

`'begin expression' または 'begin group' 指定が必要です。`

  `CREATE MODULE`コマンドのSQL起動ルーチンの宣言で、 正しくない外部名を伴った`BEGIN EXPRESSION`が指定されています。

`'begin group' 指定が必要です。`

  `CREATE MODULE`コマンドの`AGGREGATE FUNCTION`の宣言で、 `BEGIN GROUP`の指定がされていません。

`'body' 指定が必要です。`

  `CREATE MODULE`コマンドの`AGGREGATE FUNCTION`の宣言で、 `BODY` の指定がされていません。

`'end group' 指定が必要です。`

  `CREATE MODULE`コマンドの`AGGREGATE FUNCTION`の宣言で、 `END GROUP`の指定がされていません。

`トリガーの指示が必要です。`

  トリガーの指定がなしに `CREATE TRIGGER`コマンドの発行されました。

`トリガー名が必要です。`

  トリガー名の指定がなしに トリガーのプロパティを変更するための`ALTER TABLE`コマンドの発行されました。

`起動条件指示が必要です。`

  トリガーイベントの`BEFORE`または`AFTER`の指定なしに `CREATE TRIGGER`コマンドが発行されました。

`event 指定が必要です。`

  トリガーイベントの指定なしに `CREATE TRIGGER`コマンドが発行されました。 (`DELETE`, `INSERT` または `UPDATE`)

`プロシージャの指示が必要です。`

  トリガープロシージャ名の指定なしに `CREATE TRIGGER`コマンドが発行されました。 (`EXECUTE trigger_procedure_name`).

`execute 指定が必要です。`

  `EXECUTE`指定なしに `CREATE TRIGGER`コマンドが発行されました。

`トリガーのプライオリティが必要です。`

  プライオリティ指定なしに`ALTER TABLE`コマンドの `PRIORITY`オプションが指定されています。

`トリガーのプライオリティ指示が必要です。`

  トリガーのプライオリティを変更するための `ALTER TABLE`コマンドの発行されましたが、 `PRIORITY`キーワードが見つかりません。

`セミコロンまたは外部指示エラー`

  `CREATE MODULE`コマンドの発行で、 `EXTERNAL`指定が間違っています。

`キーワード 'MODULE' が必要です。`

  `CREATE MODULE`コマンドの発行で、 `END MODULE`のキーワード`MODULE`が 見つかりません。

`キーワード 'FUNCTION' が必要です。`

  `CREATE MODULE`コマンドの`AGGREGATE FUNCTION`の宣言で、 `AGGREGATE`の後のキーワード`FUNCTION`が見つかりません。

`キーワード 'WORKSPACE' が必要です。`

  `CREATE MODULE`の`ALLOCATE WORKSPACE`オプションの指定で、 `ALLOCATE`の後のキーワード`WORKSPACE`が見つかりません。

`キーワード 'EACH' が必要です。`

  `CREATE TRIGGER`の`FOR EACH ROW`オプションの指定で、 `FOR`の後のキーワード`EACH`が見つかりません。

`キーワード 'ROW' が必要です。`

  `CREATE TRIGGER`の`FOR EACH ROW`オプションの指定で、 `EACH`の後のキーワード`ROW`が見つかりません。

`キーワード 'TRIGGERS' が必要です。`

  `ENABLE` または `DISABLE` `ALL TRIGGERS` の`ALTER TABLE`コマンドの発行で、 `ALL`の後のキーワード`TRIGGERS`が見つかりません。

`データモード 'OUT' が違います。`

  `CREATE MODULE`モジュールコマンドの `FUNCTION`, `OPERATOR`および`AGGREGATE FUNCTION` にパラメータモード`OUT`を伴い宣言されましたが、 このモードは`PROCEDURE`のみ有効です。

`データモード 'INOUT' が違います。`

  `CREATE MODULE`モジュールコマンドの `FUNCTION`, `OPERATOR`および`AGGREGATE FUNCTION` にパラメータモード`INOUT`を伴い宣言されましたが、 このモードは`PROCEDURE`のみ有効です。

`優先順位が範囲が超えています。(1..6)`

  `CREATE MODULE`コマンドの数値パラメータを伴った infix オペレータ(`OPERATOR INFIX precedence`)の宣言で、 優先順位が範囲以外(1..6)です。

`優先順位が範囲が超えています。(1..2)`

  boolean パラメータを伴った infix オペレータ(`OPERATOR INFIX precedence`)の宣言で、 優先順位が範囲以外(1..2)です。

`SQL起動ルーティン指示、または言語オプションエラー`

  SQL起動ルーチンまたは言語指定なしで `CREATE MODULE`コマンドの発行されました。

### 2.6.2 ユーザーエラーメッセージ

`オペレータoperatorは１つのパラメータを必要とします。`

  prefix および postfix オペレータは、1つのパラメータだけが許されます。

`オペレータoperatorは２つのパラメータを必要とします。`

  infix(挿入辞)、comparison(比較)、equality (等価) のオペレータは、 2つのパラメータのみ許されます。

`外部名 nameは既に存在します。`

  同じモジュール内の他のルーチンとして、 同じ外部名を伴った SQL 起動ルーチンが宣言されました。

`ファイル file は存在しません。`

  存在しないファイルの使用を試みました。

`パラメータ parameter は一致しません。`

  不適切なパラメータが指定されました。

`モジュール名 module が不正です。`

  不正なモジュール名が指定されました。

`SQL呼び出しルーチン名 routine が不正です。`

  不適切なルーチン名が指定されました。

`パラメータ名 parameter が不正です。`

  不適切なパラメータが指定されました。

`パラメータ番号 number は不正です。`

  不適切なパラメータ番号が指定されました。

`外部ファンクション名 name は不正です。`

  SQL起動ルーチンに無効な外部名が指定されました。

`トリガー名 trigger は、不正です。`

  不正なトリガー名が指定されました。

`モジュール名 module は既に存在します。`

  存在しているモジュールと重複した名前のモジュールを作成しようとしました。

`モジュール module は存在しません。`

  存在しないモジュールを使用しようとしました。

`パラメータ parameter は既に存在します。`

  同じルーチン内の他のパラメータとして、 同じ名前を持つパラメータを指定しました。

`パラメータ parameter は存在しません。`

  存在しないパラメータを使用しようとしました。

`パラメータのデータタイプはオペレータ operator では、generic booleanです。`

  このパラメータデータタイプは boolean でなければなりません。

`パラメータのデータタイプは、オペレータ operator では、パラメトリックデータタイプです。`

  パラメータデータは、数値データでなければなりません。

`返り値のデータタイプは、オペレータ operator では、generic booleanです。`

  返り値のデータタイプは、booleanでなければなりません。

`返り値のデータタイプは、オペレータoperatorでは数値データです。`

  返り値のデータタイプは、数値データでなければなりません。

`返り値のデータタイプは、集合ファンクション function では、数値データタイプです。`

  boolean データタイプを返す集計関数が宣言されました。

`SQLから呼ばれるルーティン名 routine が重複しています`

  異なるルーチンクラスで同じ名前の重複したルーチンが宣言されました。

`オペレータ operator のパラメータが多すぎます。`

  オペレータのパラメータが非常に多く指定されました。

`トリガー名 trigger は、既に存在します。`

  既に存在しているトリガーと同じ名前のトリガーを作成しようとしました。

`トリガー名 trigger は、既に存在しません。`

  存在しないトリガーを使用しようとしました。

`SQLから呼び出されたルーティン routineは存在します。`

  存在しているルーチンと同じ名前のルーチンの宣言をしようとしました。

`SQLから呼び出されたルーティン routineは存在しません。`

  存在しないルーチンを使用しようとしました。

`SQLから呼び出されたルーティンは不正か、パラメータが一致しません。`

  mrefunc()関数を呼び出したとき、 無効なルーチンあるいは不適切なパラメータが見つかりました。