...

Informix SQL ガイド: チュートリアル(日本語版) (PDF:3MB)

by user

on
Category: Documents
240

views

Report

Comments

Transcript

Informix SQL ガイド: チュートリアル(日本語版) (PDF:3MB)
DB2 IBM Informix
®
򔻐򗗠򙳰
バージョン 10.0/8.5
IBM Informix SQL ガイド: チュートリアル
GB88-8673-00
(英文原典:G251-2285-00)
DB2 IBM Informix
®
򔻐򗗠򙳰
バージョン 10.0/8.5
IBM Informix SQL ガイド: チュートリアル
GB88-8673-00
(英文原典:G251-2285-00)
お願い
本書および本書で紹介する製品をご使用になる前に、 417 ページの『特記事項』に記載されている情報をお読み
ください。
本書には、IBM の専有情報が含まれています。その情報は、使用許諾条件に基づき提供され、著作権により保護されて
います。本書に記載される情報には、いかなる製品の保証も含まれていません。また、本書で提供されるいかなる記述
も、製品保証として解釈すべきではありません。
IBM は、お客様が提供するいかなる情報も、お客様に対してなんら義務も負うことのない、自ら適切と信ずる方法で、
使用もしくは配布することができるものとします。
本マニュアルに関するご意見やご感想は、次の URL からお送りください。今後の参考にさせていただきます。
http://www.ibm.com/jp/manuals/main/mail.html
なお、日本 IBM 発行のマニュアルはインターネット経由でもご購入いただけます。詳しくは
http://www.ibm.com/jp/manuals/
の「ご注文について」をご覧ください。
(URL は、変更になる場合があります)
お客様の環境によっては、資料中の円記号がバックスラッシュと表示されたり、バックスラッシュが円記号と表示され
たりする場合があります。
原 典:
G251–2285–00
IBM Informix
IBM Informix Guide to SQL: Tutorial
Version 10.0/8.5
発 行:
日本アイ・ビー・エム株式会社
担 当:
ナショナル・ランゲージ・サポート
第1刷 2005.1
この文書では、平成明朝体™W3、平成明朝体™W9、平成角ゴシック体™W3、平成角ゴシック体™W5、および平成角ゴ
(財)日本規格協会と使用契約を締結し使用しているものです。フォ
シック体™W7を使用しています。この(書体*)は、
ントとして無断複製することは禁止されています。
注* 平成明朝体™W3、平成明朝体™W9、平成角ゴシック体™W3、
平成角ゴシック体™W5、平成角ゴシック体™W7
© Copyright International Business Machines Corporation 1996, 2004. All rights reserved.
© Copyright IBM Japan 2005
目次
はじめに . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
本書について. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
対象ユーザ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xii
ソフトウェア要件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . xii
ロケールに関する前提事項 . . . . . . . . . . . . . . . . . . . . . . . . . xii
デモンストレーション データベース . . . . . . . . . . . . . . . . . . . . . xiii
Dynamic Server バージョン 10.0 の新機能 . . . . . . . . . . . . . . . . . . . . xiv
表記規則 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiv
文字の表記規則 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
機能、製品、およびプラットフォーム . . . . . . . . . . . . . . . . . . . . . xvi
構文ダイアグラム . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvi
コード例の表記規則 . . . . . . . . . . . . . . . . . . . . . . . . . . . xx
関連マニュアル . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
インストール ガイド. . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
オンライン ノート . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
Informix エラー メッセージ集 . . . . . . . . . . . . . . . . . . . . . . . xxiii
マニュアル. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiv
オンライン ヘルプ . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiv
アクセシビリティ . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiv
IBM Informix Dynamic Server バージョン 10.0 および CSDK バージョン 2.90 マニュアル セット
xxv
業界標準への準拠 . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxviii
第 1 章 データベースの概念 . . . . . .
データ モデルによる説明 . . . . . . . .
データの格納 . . . . . . . . . . .
データの問合せ . . . . . . . . . .
データの変更 . . . . . . . . . . .
複数のユーザによる同時利用とセキュリティ .
データベース利用の制御 . . . . . . .
集中管理 . . . . . . . . . . . .
重要なデータベース用語 . . . . . . . .
リレーショナル データベース モデル . .
表 . . . . . . . . . . . . . .
列 . . . . . . . . . . . . . .
行 . . . . . . . . . . . . . .
ビュー . . . . . . . . . . . . .
シーケンス . . . . . . . . . . .
表の操作 . . . . . . . . . . . .
オブジェクト リレーショナル モデル (IDS)
構造化問合せ言語 (SQL). . . . . . . .
標準 SQL. . . . . . . . . . . .
© Copyright IBM Corp. 1996, 2004
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
2
3
4
5
6
6
8
8
8
9
10
10
10
10
10
11
12
13
iii
Informix SQL と ANSI SQL
対話型 SQL . . . . . .
一般的なプログラミング . .
ANSI 標準準拠データベース
広域言語サポート (GLS). .
サマリ . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
13
14
14
14
15
15
第 2 章 SELECT 文の作成 . . . . . . . . . . . . . . . . . . . . . . . . . 17
SELECT 文について . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
SELECT 文の出力 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
基本的な概念 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
単一表 SELECT 文 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
アスタリスク記号 (*) の使用方法 . . . . . . . . . . . . . . . . . . . . . . 25
ORDER BY 節を使用した行のソート . . . . . . . . . . . . . . . . . . . . . 26
特定の列の選択 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
WHERE 節の使用方法 . . . . . . . . . . . . . . . . . . . . . . . . . . 38
比較条件の作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
特定の行を選択するためのFIRST節の使用 . . . . . . . . . . . . . . . . . . . . 55
式と導出値 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
SELECT 文での行 ID 値の使用 . . . . . . . . . . . . . . . . . . . . . . . 65
複数表の SELECT 文 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
デカルト積の作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
結合の作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
問合せのショートカット . . . . . . . . . . . . . . . . . . . . . . . . . . 76
サマリ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
第 3 章 複合型データの選択 (IDS) . . . . . . . . . . . . . .
行 (ROW) 型データの選択 . . . . . . . . . . . . . . . . .
型付き表の列の選択 . . . . . . . . . . . . . . . . . .
行 (ROW) 型データが格納されている列の選択 . . . . . . . . .
コレクション (COLLECTION) 型の選択 . . . . . . . . . . . .
入れ子コレクション (COLLECTION) 型の選択 . . . . . . . . .
キーワード IN でコレクション (COLLECTION) 型データ内の要素を検索
表階層にある行の選択 . . . . . . . . . . . . . . . . . .
キーワード ONLY を使用しない上位表の行の選択 . . . . . . . .
キーワード ONLY を使用した上位表の行の選択. . . . . . . . .
上位表に別名を使用 . . . . . . . . . . . . . . . . . .
サマリ . . . . . . . . . . . . . . . . . . . . . . . .
第 4 章 SELECT 文での関数の使用 . . .
SELECT 文での関数の使用 . . . . . .
集計関数 . . . . . . . . . . .
時刻関数 . . . . . . . . . . .
日付変換関数 (IDS) . . . . . . . .
計数関数 (IDS) . . . . . . . . .
スマート ラージ オブジェクト関数 (IDS)
iv
IBM Informix SQL ガイド: チュートリアル
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . . . . 83
. . . . . . . . . 84
. . . . . . . . . 85
. . . . . . . . . 86
. . . . . . . . . 90
. . . . . . . . . 91
. . . . . . . . . 92
. . . . . . . . . 94
. . . . . . . . . 96
. . . . . . . . . 97
. . . . . . . . . 97
. . . . . . . . . 97
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 99
100
100
106
112
115
116
文字列操作関数 (IDS) . . . .
その他の関数 . . . . . . .
SELECT 文での SPL ルーチンの使用
データ暗号化関数の使用 (IDS) . .
サマリ . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
118
125
132
134
136
第 5 章 高度な SELECT 文の作成 . . . . . . . . . . . . . . . . . . . . . . 137
GROUP BY 節と HAVING 節の使用 . . . . . . . . . . . . . . . . . . . . . . 138
GROUP BY 節の使用方法 . . . . . . . . . . . . . . . . . . . . . . . . . 139
HAVING 節の使用方法 . . . . . . . . . . . . . . . . . . . . . . . . . . 142
高度な結合の作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
セルフ結合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
外部結合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
SELECT 文の副問合せ . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
相関副問合せ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
SELECT 文の副問合せ . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Projection 節での副問合せ . . . . . . . . . . . . . . . . . . . . . . . . . 158
WHERE 節の中の副問合せ . . . . . . . . . . . . . . . . . . . . . . . . 159
SELECT 文でのコレクションの処理 (IDS) . . . . . . . . . . . . . . . . . . . . 167
コレクション (COLLECTION) 型副問合せ . . . . . . . . . . . . . . . . . . . 167
コレクション (COLLECTION) 型導出表 . . . . . . . . . . . . . . . . . . . . 169
集合演算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
和集合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
積 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
差 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
サマリ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
第 6 章 データの変更 . . . . . . . . . . . .
データベースの変更 . . . . . . . . . . . . .
行の削除 . . . . . . . . . . . . . . . .
表のすべての行の削除 . . . . . . . . . . .
TRUNCATE TABLE を使用したすべての行の削除. .
指定された行の削除 . . . . . . . . . . . .
選択された行の削除 . . . . . . . . . . . .
行 (ROW) 型を含む行の削除 (IDS) . . . . . . .
コレクション (COLLECTION) 型を含む行の削除 (IDS)
上位表からの行の削除 (IDS) . . . . . . . . .
複雑な削除条件 . . . . . . . . . . . . .
削除結合の使用 (XPS) . . . . . . . . . . .
行の挿入 . . . . . . . . . . . . . . . .
単一行 . . . . . . . . . . . . . . . .
型付き表への行の挿入 (IDS) . . . . . . . . .
行 (ROW) 型列への挿入 (IDS) . . . . . . . .
上位表への行の挿入 (IDS) . . . . . . . . . .
列へのコレクション (COLLECTION) 型値の挿入 (IDS)
スマート ラージ オブジェクトの挿入 (IDS) . . . .
. . . . . . . . . . . . . . . 183
. . . . . . . . . . . . . . . 184
. . . . . . . . . . . . . . . 185
. . . . . . . . . . . . . . . 185
. . . . . . . . . . . . . . . 186
. . . . . . . . . . . . . . . 187
. . . . . . . . . . . . . . . 187
. . . . . . . . . . . . . . . 188
. . . . . . . . . . . . . . . 188
. . . . . . . . . . . . . . . 188
. . . . . . . . . . . . . . . 189
. . . . . . . . . . . . . . . 189
. . . . . . . . . . . . . . . 190
. . . . . . . . . . . . . . . 190
. . . . . . . . . . . . . . . 192
. . . . . . . . . . . . . . . 193
. . . . . . . . . . . . . . . 195
. . . . . . . . . . . . . . . 195
. . . . . . . . . . . . . . . 197
目次
v
複数の行の挿入および式の使用 . . . . . . . . . . . .
INSERT 文に SELECT 文を使用する場合の制約 . . . . . .
行の更新 . . . . . . . . . . . . . . . . . . . .
更新対象の行の選択 . . . . . . . . . . . . . . . .
一様値を使用する更新 . . . . . . . . . . . . . . .
更新の制限 . . . . . . . . . . . . . . . . . . .
選択値を使用する更新 . . . . . . . . . . . . . . .
行 (ROW) 型の更新 (IDS) . . . . . . . . . . . . . .
コレクション (COLLECTION) 型の更新 (IDS) . . . . . . .
上位表の行の更新 (IDS) . . . . . . . . . . . . . .
CASE 式による列の更新 . . . . . . . . . . . . . .
SQL 関数を使用したスマート ラージ オブジェクトの更新 (IDS) .
結合を使用した列の更新 . . . . . . . . . . . . . .
データベースとそのオブジェクトに対するアクセス権 . . . . .
データベース レベル アクセス権 . . . . . . . . . . .
表レベル アクセス権 . . . . . . . . . . . . . . .
表アクセス権の表示 . . . . . . . . . . . . . . . .
ロールへのアクセス権の付与 . . . . . . . . . . . . .
データ整合性 . . . . . . . . . . . . . . . . . . .
エンティティ保全性 . . . . . . . . . . . . . . . .
意味整合性 . . . . . . . . . . . . . . . . . . .
参照整合性 . . . . . . . . . . . . . . . . . . .
オブジェクト モードと違反の検出 . . . . . . . . . . .
中断された変更 . . . . . . . . . . . . . . . . . .
トランザクション . . . . . . . . . . . . . . . .
トランザクション ログ . . . . . . . . . . . . . . .
トランザクションの指定 . . . . . . . . . . . . . .
Informix データベース サーバを使用したバックアップとログ . . .
並行性およびロック . . . . . . . . . . . . . . . . .
IBM Informix データ レプリケーション (IDS) . . . . . . . .
サマリ . . . . . . . . . . . . . . . . . . . . .
第 7 章 外部データベースのデータへのアクセスおよび修正
他のデータベース サーバへのアクセス . . . . . . .
ANSI データベースへのアクセス . . . . . . . .
外部データベース サーバ間の結合の作成 . . . . . .
外部ルーチンへのアクセス (IDS) . . . . . . . .
リモート データベース アクセスの制約事項 . . . . .
SQL 文およびロギング モード . . . . . . . . .
外部データベース オブジェクトへのアクセス . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
198
198
200
200
200
201
202
203
204
204
205
206
206
207
207
207
208
209
209
210
210
211
214
221
222
222
224
225
227
227
228
. . . . . . . . . . . . . . 231
. . . . . . . . . . . . . . 231
. . . . . . . . . . . . . . 232
. . . . . . . . . . . . . . 232
. . . . . . . . . . . . . . 232
. . . . . . . . . . . . . . 232
. . . . . . . . . . . . . . 233
. . . . . . . . . . . . . . 233
第 8 章 SQL を使用したプログラミング . . . . . . . . . . . . . . . . . . . . 235
プログラム中の SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
SQL API 中の SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
アプリケーション言語の SQL . . . . . . . . . . . . . . . . . . . . . . . 237
静的埋込み . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
vi
IBM Informix SQL ガイド: チュートリアル
動的文 . . . . . . . . . . . . .
プログラム変数とホスト変数 . . . . . .
データベース サーバの呼出し . . . . . .
SQL 通信領域 . . . . . . . . . . .
SQLCODE フィールド . . . . . . . .
SQLERRD 配列 . . . . . . . . . .
SQLWARN 配列 . . . . . . . . . .
SQLERRM 文字列 . . . . . . . . .
SQLSTATE 値 . . . . . . . . . . .
単一行の抽出 . . . . . . . . . . . .
データ型の変換 . . . . . . . . . .
NULL データの処理 . . . . . . . . .
エラーの処理 . . . . . . . . . . .
複数行の抽出 . . . . . . . . . . . .
カーソルの宣言 . . . . . . . . . .
カーソルのオープン . . . . . . . . .
行の取出し . . . . . . . . . . . .
カーソル入力モード . . . . . . . . .
カーソルのアクティブ セット . . . . .
カーソルの使用: 部品展開 . . . . . . .
動的 SQL . . . . . . . . . . . . .
文の PREPARE 文による処理 . . . . .
PREPARE 文で処理された SQL 文の実行 .
動的ホスト変数 . . . . . . . . . .
PREPARE 文で処理された文の解放. . . .
実行の高速化 . . . . . . . . . . .
データ定義文の埋込み . . . . . . . . .
アプリケーションでのアクセス権の付与と取消し
ロールの割当て . . . . . . . . . .
サマリ . . . . . . . . . . . . . .
第 9 章 SQL プログラムによるデータの更新
DELETE の使用 . . . . . . . . . .
直接的な削除 . . . . . . . . . .
カーソルを使用した削除 . . . . . .
INSERT の使用 . . . . . . . . . .
INSERT カーソルの使用方法 . . . . .
定数の行 . . . . . . . . . . .
挿入の例 . . . . . . . . . . .
UPDATE 文の使用 . . . . . . . . .
UPDATE カーソルの使用方法 . . . .
表の仕上げ . . . . . . . . . . .
サマリ . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
238
238
239
240
240
241
242
244
245
245
246
247
248
249
250
250
251
252
253
255
257
258
259
260
260
261
261
261
263
264
. . . . . . . . . . . . . . . . . . . 265
. . . . . . . . . . . . . . . . . . . 266
. . . . . . . . . . . . . . . . . . . 266
. . . . . . . . . . . . . . . . . . . 268
. . . . . . . . . . . . . . . . . . . 270
. . . . . . . . . . . . . . . . . . . 270
. . . . . . . . . . . . . . . . . . . 272
. . . . . . . . . . . . . . . . . . . 273
. . . . . . . . . . . . . . . . . . . 275
. . . . . . . . . . . . . . . . . . . 275
. . . . . . . . . . . . . . . . . . . 276
. . . . . . . . . . . . . . . . . . . 277
第 10 章 マルチユーザ環境のためのプログラミング . . . . . . . . . . . . . . . . . 279
並行性およびパフォーマンス . . . . . . . . . . . . . . . . . . . . . . . . . 280
目次
vii
ロックおよび整合性 . . . . . . . . . . . . . . . . .
ロックおよびパフォーマンス . . . . . . . . . . . . . .
並行性の問題 . . . . . . . . . . . . . . . . . . .
ロックの動作 . . . . . . . . . . . . . . . . . . .
ロックの種類 . . . . . . . . . . . . . . . . . .
ロック範囲 . . . . . . . . . . . . . . . . . . .
ロックの継続期間 . . . . . . . . . . . . . . . .
データ修正中のロック . . . . . . . . . . . . . . .
SELECT 文でのロック . . . . . . . . . . . . . . . .
排他レベルの設定 . . . . . . . . . . . . . . . .
UPDATE カーソル . . . . . . . . . . . . . . . .
更新ロックの保存 . . . . . . . . . . . . . . . . .
INSERT 文、UPDATE 文、および DELETE 文により設定するロック
ロック タイプの動作の理解 . . . . . . . . . . . . . .
アクセス モードによるデータ変更の制御 . . . . . . . . . .
ロック モードの設定 . . . . . . . . . . . . . . . .
ロックの待機 . . . . . . . . . . . . . . . . . .
ロックの解除を待機しない . . . . . . . . . . . . .
一定時間ロックの解除を待機する . . . . . . . . . . .
デッドロックの処理 . . . . . . . . . . . . . . . .
外部デッドロックの処理 . . . . . . . . . . . . . .
単純な並行性 . . . . . . . . . . . . . . . . . . .
HOLD カーソル . . . . . . . . . . . . . . . . . .
SQL 文キャッシュの使用 . . . . . . . . . . . . . . .
サマリ . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
280
280
281
282
283
283
289
290
290
291
296
296
297
297
299
299
300
300
300
300
301
301
302
303
304
第 11 章 SPL ルーチンの作成と使用 . . . . . . . . . . . . . . . . . . . . . 305
SPL ルーチンの概要. . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
SPL ルーチンの機能. . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Extended Parallel Server での SPL ルーチンの動作 . . . . . . . . . . . . . . . . 308
SPL ルーチンの作成. . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
CREATE PROCEDURE 文または CREATE FUNCTION 文の使用. . . . . . . . . . . . 309
完全なルーチンの例 . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
プログラム内の SPL ルーチンの作成 . . . . . . . . . . . . . . . . . . . . . 321
分散操作でのルーチン . . . . . . . . . . . . . . . . . . . . . . . . . . 321
変数の定義と使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
局所変数の宣言 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
広域変数の宣言 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
変数への値の代入 . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
SPL ルーチンの式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
文ブロックの記述 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
暗黙的および明示的文ブロック . . . . . . . . . . . . . . . . . . . . . . . 336
カーソルの使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
FOREACH ループを使用したカーソルの定義 . . . . . . . . . . . . . . . . . . 338
IF - ELIF - ELSE 構造の使用 . . . . . . . . . . . . . . . . . . . . . . . 340
WHILE ループと FOR ループの追加 . . . . . . . . . . . . . . . . . . . . . 342
viii
IBM Informix SQL ガイド: チュートリアル
ループの終了 . . . . . . . . . . . . . . .
SPL 関数からの値の戻り . . . . . . . . . . . .
単一値の戻り . . . . . . . . . . . . . . .
複数値の戻り . . . . . . . . . . . . . . .
行 (ROW) 型データの処理 (IDS) . . . . . . . . .
ピリオド表記の優先順位 . . . . . . . . . . .
行 (ROW) 型式の更新 . . . . . . . . . . . .
コレクションの処理 (IDS) . . . . . . . . . . . .
コレクション (COLLECTION) 型の使用 . . . . . .
コレクション (COLLECTION) 型の準備 (IDS) . . . .
コレクション (COLLECTION) 型変数への要素の挿入. .
コレクション (COLLECTION) 型データからの要素の選択
コレクション (COLLECTION) 型要素の削除. . . . .
コレクション (COLLECTION) 型要素の更新. . . . .
コレクション全体の更新 . . . . . . . . . . .
コレクション (COLLECTION) 型データへの挿入 . . .
ルーチンの実行 . . . . . . . . . . . . . . .
EXECUTE 文の使用 . . . . . . . . . . . . .
CALL 文の使用 . . . . . . . . . . . . . .
式の中のルーチンの実行 . . . . . . . . . . .
RETURN 文による外部関数の実行 . . . . . . . .
SPL ルーチンからのカーソル関数の実行 . . . . . .
動的ルーチン名の指定 . . . . . . . . . . . .
ルーチンのアクセス権 . . . . . . . . . . . . .
ルーチンを登録する権限 . . . . . . . . . . .
ルーチンを実行する権限 . . . . . . . . . . .
ルーチンに関連付けられたオブジェクトのアクセス権 .
ルーチンを実行するための DBA アクセス権 . . . .
SPL ルーチンのエラー検出 . . . . . . . . . . .
コンパイル時の警告の表示 . . . . . . . . . .
ルーチンのテキストの生成 . . . . . . . . . .
SPL ルーチンのデバッグ . . . . . . . . . . . .
例外処理 . . . . . . . . . . . . . . . . .
エラー トラッピングと復旧 . . . . . . . . . .
ON EXCEPTION 文の制御の有効範囲 . . . . . . .
ユーザが生成する例外 . . . . . . . . . . . .
SPL ルーチンで処理される行数のチェック . . . . . .
サマリ . . . . . . . . . . . . . . . . . .
第 12 章 トリガの作成と使用 . .
トリガを使用するタイミング . . .
トリガの作成方法 . . . . . .
トリガ名の割当て . . . . .
トリガ イベントの指定 . . . .
トリガ アクションの定義 . . .
完全な構成の CREATE TRIGGER
.
.
.
.
.
.
文
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
344
344
345
346
348
348
349
349
350
351
353
356
359
363
364
368
373
373
375
376
377
377
377
379
379
380
382
383
384
384
385
386
388
388
389
390
392
393
. . . . . . . . . . . . . . . . . . . . . 395
. . . . . . . . . . . . . . . . . . . . . 396
. . . . . . . . . . . . . . . . . . . . . 397
. . . . . . . . . . . . . . . . . . . . . 398
. . . . . . . . . . . . . . . . . . . . . 398
. . . . . . . . . . . . . . . . . . . . . 398
. . . . . . . . . . . . . . . . . . . . . 399
目次
ix
トリガ アクションの使用方法 . . . . . . . . .
BEFORE および AFTER トリガ アクションの使用方法
FOR EACH ROW トリガ アクションの使用方法 . .
トリガ アクションとしての SPL ルーチンの使用方法
表階層のトリガ (IDS) . . . . . . . . . . . .
選択トリガの使用 (IDS) . . . . . . . . . . .
トリガ アクションを実行する SELECT 文 . . . .
選択トリガの実行についての制限 . . . . . . .
表階層の表に対する選択トリガ . . . . . . . .
リエントラント トリガ . . . . . . . . . . . .
ビューの INSTEAD OF トリガ (IDS) . . . . . . .
INSTEAD OF トリガを使用してビュー上で更新 . .
トリガ アクションのトレース . . . . . . . . .
SPL ルーチン内の TRACE 文の例 . . . . . . .
TRACE 出力の例 . . . . . . . . . . . . .
エラー メッセージの生成 . . . . . . . . . . .
固定エラー メッセージの適用 . . . . . . . .
可変エラー メッセージの生成 . . . . . . . .
サマリ . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
付録. アクセシビリティ .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 413
特記事項
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 417
索引 .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 421
x
.
IBM Informix SQL ガイド: チュートリアル
399
399
400
402
403
404
404
405
405
406
406
406
407
407
408
409
409
410
411
はじめに
本書について. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
対象ユーザ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xii
ソフトウェア要件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . xii
ロケールに関する前提事項 . . . . . . . . . . . . . . . . . . . . . . . . . xii
デモンストレーション データベース . . . . . . . . . . . . . . . . . . . . . xiii
Dynamic Server バージョン 10.0 の新機能 . . . . . . . . . . . . . . . . . . . . xiv
表記規則 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiv
文字の表記規則 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
機能、製品、およびプラットフォーム . . . . . . . . . . . . . . . . . . . . . xvi
構文ダイアグラム . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvi
コマンド行構文ダイアグラムの読み方 . . . . . . . . . . . . . . . . . . . xviii
キーワードおよび句読点 . . . . . . . . . . . . . . . . . . . . . . . . xix
識別子と名前 . . . . . . . . . . . . . . . . . . . . . . . . . . . . xx
コード例の表記規則 . . . . . . . . . . . . . . . . . . . . . . . . . . . xx
関連マニュアル . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
インストール ガイド. . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
オンライン ノート . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
オンライン ノートの入手先 . . . . . . . . . . . . . . . . . . . . . . . xxii
オンライン ノートのファイル名 . . . . . . . . . . . . . . . . . . . . . xxiii
Informix エラー メッセージ集 . . . . . . . . . . . . . . . . . . . . . . . xxiii
マニュアル. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiv
オンライン マニュアル . . . . . . . . . . . . . . . . . . . . . . . . xxiv
ペーパー マニュアル . . . . . . . . . . . . . . . . . . . . . . . . . xxiv
オンライン ヘルプ . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiv
アクセシビリティ . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiv
IBM Informix Dynamic Server バージョン 10.0 および CSDK バージョン 2.90 マニュアル セット
xxv
業界標準への準拠 . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxviii
はじめに
ここでは、本書に記載する情報の概要を説明し、使用する表記規則を示します。
本書について
本書では、データベース内のデータにアクセスし操作するための、構造化問合せ言語
(SQL) の基本的および高度な使用方法について説明します。データ操作言語 (DML)
文、トリガ、および DML 文が通常使用するストアド プロシジャ言語 (SPL) ルーチン
について記載します。
© Copyright IBM Corp. 1996, 2004
xi
本書は、Informix の SQL インプリメンテーションに関する一連の資料のうちの一冊で
す。「IBM Informix: SQL ガイド: 構文」には、SQL と SPL の構文記述について記載
されています。「IBM Informix: SQL ガイド: 参照」には、SQL の、言語ステートメン
トを除いた事項に関する参照情報が記載されています。そして、「IBM Informix: データ
ベース設計および実装 ガイド」には、SQL を使用してデータベースを実装し、管理す
る方法について記載されています。
対象ユーザ
本書は、次のユーザを対象としています。
v データベースのユーザ
v データベース管理者
v データベース アプリケーションのプログラマ
本書は、読者が次の知識や経験を保有していることを前提としています。
v 使用するコンピュータ、オペレーティング システム、およびオペレーティング シス
テムが提供するユーティリティに関する実際的な知識
v リレーショナル データベース操作の経験、またはデータベースの概念の理解
v コンピュータ プログラミングに関する経験
リレーショナル データベース、SQL、またはご使用のオペレーティング システムに関
する補足情報が必要な場合は、「IBM Informix: Dynamic Server スタートアップ ガイ
ド」の、ご使用のデータベース サーバの項目を参照してください。
ソフトウェア要件
本書では、使用するデータベース サーバが、以下のいずれかであることを前提としてい
ます。
v IBM Informix Extended Parallel Server バージョン 8.50
v IBM Informix Dynamic Server バージョン 10.0
ロケールに関する前提事項
IBM Informix 製品は、多くの言語、国/地域別情報、およびコード セットをサポートし
ています。文字セット、照合、数値データの表記、通貨、日付、および時刻に関する情
報はすべて、広域言語サポート (GLS) ロケールと呼ばれる 1 つの環境にまとめられて
います。
本書に記載する例は、デフォルト ロケール en_us.8859-1 を使用することを前提として
います。このロケールでは、日付、時刻、および通貨について、米国英語形式 (U.S.
English) の規則をサポートします。さらにこのロケールでは、ASCII コード セットと、
é、è、および ñ などの多くの 8 ビット文字を含む ISO 8859-1 コード セットをサポー
トします。
xii
IBM Informix SQL ガイド: チュートリアル
データまたは SQL 識別子でデフォルト以外の文字を使用する場合、または文字データ
をデフォルト以外の規則で照合する場合は、適切な非デフォルト ロケールを指定する必
要があります。
デフォルト以外のロケールの指定方法、追加構文、および GLS ロケールに関するその
他の考慮事項については、「IBM Informix: GLS ユーザーズ ガイド」を参照してくださ
い。
デモンストレーション データベース
データベース サーバ製品に付属する DB–Access ユーティリティには、以下のデモンス
トレーション データベースが 1 つ以上含まれます。
v stores_demo データベースでは、架空のスポーツ用品卸売り業者の例を使用して、リ
レーショナル スキーマについて説明します。IBM Informix の資料に記載されている
例の多くは、stores_demo データベースを基にしています。
Extended Parallel Server
v sales_demo データベースは、データ ウェアハウジング アプリケーションの次元スキ
ーマを説明します。次元データ モデルの概念については、「IBM Informix: データベ
ース設計および実装 ガイド」を参照してください。
Extended Parallel Server の終り
Dynamic Server
v superstores_demo データベースではオブジェクト リレーショナル スキーマについて
説明します。superstores_demo データベースには、拡張データ型、型および表の継
承、およびユーザ定義ルーチンの例が含まれます。
Dynamic Server の終り
デモンストレーション データベースの作成およびデータの追加については、
「IBM Informix: DB-Access ユーザーズ ガイド」を参照してください。それぞれのデー
タベースおよびその内容の説明については、「IBM Informix: SQL ガイド: 参照」を参
照してください。
デモンストレーション データベースのインストールに使用するスクリプトは、UNIX プ
ラットフォームの場合は $INFORMIXDIR/bin ディレクトリ、Windows 環境の場合は
%INFORMIXDIR%¥bin ディレクトリにあります。
はじめに
xiii
Dynamic Server バージョン 10.0 の新機能
このセクションでは、本書に記載する新機能をリストします。本書では、新機能を記載
すると同時に、旧バージョン以降に確認された誤記を修正しています。
本書には、以下の新機能について記載しています。
v 表をロックせずに行う、インデックスの作成と削除
CREATE INDEX および DROP INDEX の SQL 構文では、新規の ONLINE キーワ
ードがサポートされるようになりました。
v デフォルト ロールによるデータベース権限の管理
デフォルト ロールを作成し、それをデータベース レベルで個々のユーザまたは
PUBLIC に割り当てることができます。
v 外部ルーチンの登録の制限
DBSA (データベース サーバ管理者) は、新規の組込みロールである EXTEND を使
用して、EXTERNAL NAME 節を含む UDR を登録できるユーザを指定できます。
v 組込み不透明 (OPAQUE) 型のクロス データベース サポート
複合データ型のクロス データベース サポートはありません。複合データ型は、ロー
カル データベースでのみ操作できます。
v 列レベルの暗号化
新規の SQL 文である SET ENCRYPTION PASSWORD を使用して、列レベルの暗号
化を実装することにより、データの機密性を向上できます。新規の組込み関数は、デ
ータの暗号化および組込み復号化の方法を提供します。
データベース サーバのすべての新機能のリストは、「IBM Informix: Dynamic Server ス
タートアップ ガイド」を参照してください。
表記規則
ここでは、このマニュアルで使用される、以下の表記規則について説明します。これら
の表記規則を把握しておくと、本書および他の関連マニュアルの内容を理解するのに役
立ちます。
以下のような表記規則があります。
v 文字の表記規則
v その他の表記規則
v 構文ダイアグラム
v コマンド行の表記規則
xiv
IBM Informix SQL ガイド: チュートリアル
v コード例の表記規則
文字の表記規則
本書では、新しい用語、画面表示、コマンド構文などを表記するのに、以下の規則を使
用します。
表記規則
意味
KEYWORD
プログラミング言語の文中では、主要な要素 (キーワード) は、すべ
て大文字のセリフ フォントで表記されます。
イタリック体
イタリック体
イタリック体
本文中では、新しい用語および強調語がイタリック体で表記されま
す。構文とコードの例では、ユーザが指定する変数値は、イタリック
体で表示されます。
太文字
太文字
プログラム エンティティの名前 (クラス、イベント、および表)、環
境変数、ファイルやパス名、およびインターフェイス要素 (アイコ
ン、メニュー項目、およびボタンなど) が太文字で表示されます。
モノスペース
モノスペース
製品が表示する情報、およびユーザが入力する情報は、モノスペース
で表記されます。
KEYSTROKE
ユーザが押すキーは、大文字のサンセリフ フォントで表記されます
>
この記号は、メニュー項目を表します。例えば、「ツール」>「オプ
ション」を選択する、という記述は、「ツール」メニューから「オプ
ション」項目を選択することを指します。
ヒント: 文字の「入力」、またはコマンドの「実行」を指示された場合は、入力直後に
Enter を押してください。ただし、テキストを「手入力」、または他のキーを
「押す」ように指示された場合は、Enter を押す必要はありません。
はじめに
xv
機能、製品、およびプラットフォーム
機能、製品、およびプラットフォームのマークアップは、機能、製品、またはプラット
フォームに固有な情報を表します。このマークアップの例を次に示します。
Dynamic Server
IBM Informix Dynamic Server 固有の情報を示します。
Dynamic Server の終り
Extended Parallel Server
IBM Informix Extended Parallel Server 固有の情報を示します
Extended Parallel Server の終り
UNIX のみ
UNIX プラットフォーム固有の情報を示します。
UNIX のみ の終り
Windows のみ
Windows 環境固有の情報を示します。
Windows のみ の終り
これらのマークアップは、セクション内の 1 つ以上のパラグラフに適用される場合があ
ります。セクション全体が特定の製品またはプラットフォームに適用する場合は、次の
ように見出しテキストで示します。
表のソート (Linux のみ)
構文ダイアグラム
本書で使用する構文ダイアグラムは、以下のコンポーネントで構成されます。このダイ
アグラムは、システム レベルのコマンドを除くすべてのコマンドと、文の構文を表しま
す。
注: 2004 年以降、構文ダイアグラムは IBM 標準に準拠する形に再フォーマットされま
した。
SQL 文およびコマンド行文を表す構文ダイアグラムは、以下のように変更されました。
v 文の最初と最後には、終端の縦線に代わり、二重矢印が使用されます。
xvi
IBM Informix SQL ガイド: チュートリアル
v 構文セグメント ダイアグラムの最初と最後には、矢印の代わりに縦線が使用されま
す。
v ループを繰り戻す回数は、ゲート記号内の数字としてではなく、ダイアグラムの脚注
に表示されます。
v 構文が複数行にわたる場合は、同じ行にループ ダウンするのではなく、次の行に示
されます。
v 製品または条件固有のパスは、アイコンではなく、ダイアグラムの脚注に表示されま
す。
次の表に、構文ダイアグラムのコンポーネントを示します。
コンポーネントの PDF での表示
コンポーネントの HTML での表示
説明
>>----------------------
文の開始を示します。
----------------------->
文が次行に続くことを示し
ます。
>-----------------------
文が前行からの続きである
ことを示します。
-----------------------><
文の終端を示します。
--------SELECT----------
必須項目です。
--+-----------------+--’------LOCAL------’
オプションの項目です。
---+-----ALL-------+--+--DISTINCT-----+
’---UNIQUE------’
選択項目のある必須項目で
す。項目を 1 つのみ指定
する必要があります。
---+------------------+--+--FOR UPDATE-----+
’--FOR READ ONLY--’
オプショナル項目がメイン
行の下に選択肢で表示さ
れ、そのいずれかを指定で
きます。
.---NEXT---------.
----+----------------+--+---PRIOR--------+
’---PREVIOUS-----’
メイン行の下にある値はオ
プションで、そのいずれか
を指定できます。項目を指
定しない場合、行の上にあ
る値がデフォルトとして使
用されます。
はじめに
xvii
コンポーネントの PDF での表示
Table Reference
コンポーネントの HTML での表示
説明
.-------,-----------.
V
|
---+-----------------+--+---index_name---+
’---table_name---’
オプションの項目です。複
数の項目を指定できます。
各項目はコンマで区切る必
要があります。
>>-| Table Reference |-><
構文セグメントの参照で
す。
Table Reference
構文セグメントです。
|--+-----view--------+--|
+------table------+
’----synonym------’
view
table
synonym
コマンド行構文ダイアグラムの読み方
以下のコマンド行構文ダイアグラムでは、前セクションの表にリストした要素をいくつ
か使用しています。
No-Conversion ジョブの作成
onpladm create job
job
-n -d
-p
-t
device -D
database
project
table (1)
Setting the Run Mode
-S
server
-T
target
注:
1
4 ページ参照
このダイアグラムの 2 行目には、「Setting the Run Mode」という名前のセグメントが
あります (ダイアグラムの脚注に示す 4 ページに詳細を記載)。このセグメントを、次
のセグメント ダイアグラムで示します (ダイアグラムにはセグメント開始と終了のコン
ポーネントを使用します)。
Setting the Run Mode:
xviii
IBM Informix SQL ガイド: チュートリアル
l
c
-f
d
p
a
u
n
N
コマンドを正しく入力するには、左上のコマンドから開始します。次に、ダイアグラム
を右へ進み、必要な要素を入力します。ダイアグラムの要素は、大文字と小文字を区別
をする必要があります。
「No-Conversion ジョブの作成」ダイアグラムは、以下の手順を示しています。
1. onpladm create job を入力し、次にジョブ名を入力します。
2. 任意で -p と入力し、プロジェクト名を入力します。
3. 以下の必須要素を入力します。
v -n
v -d およびデバイス名
v -D およびデータベース名
v -t および表名
4. オプションで、以下の中から 1 つ以上の要素を選択し、任意の回数まで繰り返すこ
とができます。
v -S およびサーバ名
v -T およびターゲット サーバ名
v run mode。run mode を設定するには、Setting the Run Mode セグメント ダイア
グラムに従います。まず -f を入力し、次にオプションで d、p、または a を入力
し、最後にオプションで l または u を入力します。
5. 終端記号までダイアグラムを読み進めます。
これで、ダイアグラムが終了します。
キーワードおよび句読点
システム レベルのコマンドを除き、すべてのコマンドおよび文に予約された単語です。
構文ダイアグラム内のキーワードは、大文字で表記されます。コマンド内のキーワード
には、大文字と小文字の両方を使用できます。ただし、構文ダイアグラム内のキーワー
ドと完全に一致するスペルにしてください。
また、構文やコマンド内の句読点も、構文ダイアグラム内と一致するように使用しなけ
ればなりません。
はじめに
xix
識別子と名前
変数は、構文ダイアグラムや例の中で、識別子や名前の代わりに使用されます。変数は
コンテキストによって、任意の名前、識別子、リテラルに置き換えられます。また変数
は、追加構文ダイアグラムで拡張される複合構文要素を表すためにも使用されます。構
文ダイアグラム、例、またはテキスト内で使用される変数は、小文字のイタリック体 で
表記されます。
次の構文ダイアグラムでは、変数を使用して、単純な SELECT 文の一般的な形を示し
ています。
SELECT column_name FROM table_name
この形の SELECT 文を作成する場合は、変数 column_name および table_name を特定
の列名と表名に置き換えます。
コード例の表記規則
このマニュアルでは、SQL コードの例が随所に使用されています。特に明記されていな
い限り、記載されるコードは、特定の IBM Informix アプリケーション開発ツール専用
ではありません。
例の中に SQL 文のみがリストされる場合、これらの文は、セミコロン (;) で区切られ
ません。例えば、以下のようなコードの例が使用されます。
CONNECT TO stores_demo
...
DELETE FROM customer
WHERE customer_num = 121
...
COMMIT WORK
DISCONNECT CURRENT
この SQL コードをある製品で使用する場合、その製品の構文規則を適用する必要があ
ります。例えば DB–Access を使用する場合、文と文の間はセミコロン (;) で区切る必
要があります。SQL API を使用する場合、EXEC SQL を文の最初に指定し、文の最後
にセミコロン (;)、または適切な区切り記号を指定する必要があります。
ヒント: コード例内の省略記号は、フル アプリケーションではそこにコードが追加され
ることを示します。概念の説明には必要ないため、それらのコードは省略され
ています。
特定のアプリケーション開発ツール、または SQL API の SQL 文の詳細については、
製品に付属するマニュアルを参照してください。
xx
IBM Informix SQL ガイド: チュートリアル
関連マニュアル
詳しくは、以下のマニュアル セットを参照してください。
v インストール ガイド
v オンライン ノート
v Informix エラー メッセージ集
v マニュアル
v オンライン ヘルプ
インストール ガイド
インストール ガイドは、製品 CD の /doc ディレクトリ、または IBM Web サイトか
らダウンロードした場合には製品の圧縮ファイルの /doc ディレクトリにあります。ま
た、インストール ガイドは、IBM Informix Online Documentation サイト
(http://www.ibm.com/software/data/informix/pubs/library/) からも入手できます。
オンライン ノート
以下のセクションでは、このマニュアルの情報を補足するオンライン ファイルについて
説明します。IBM Informix 製品を使用する前に、これらのファイルを参照してくださ
い。このファイルには、アプリケーションおよびパフォーマンスに関する重要な情報が
含まれています。
はじめに
xxi
オンライン ファイル
説明
フォーマット
TOC ノート
HTML
TOC (目次) ノート ファイルには、リリース
ノート、修正された問題と既知の問題について
のファイル、および個々のマニュアル タイト
ルに該当するすべてのドキュメント ノート フ
ァイルへの、ハイパーリンクの包括的なディレ
クトリが記載されています。
ドキュメント ノート
それぞれのマニュアルのドキュメント ノート HTML、テキ
には、マニュアルに記載されている情報を補足 スト
する重要な情報と修正、マニュアルの出版後に
変更された情報が含まれています。
リリース ノート
リリース ノート ファイルには、IBM Informix HTML、テキ
製品の以前バージョンとの機能の違いと、その スト
違いが現行の製品に及ぼす影響について記載し
ています。製品により、このファイルに既知の
問題とその修正処置も含まれる場合がありま
す。
マシン ノート
(Windows 以外のプラットフォームのみ) マシ テキスト
ン ノート ファイルには、ご使用のコンピュー
タで IBM Informix 製品を構成して使用するた
めに行うべきプラットフォーム固有の処置につ
いて記載しています。
修正された問題と既知
の問題についてのファ
イル
このテキスト ファイルには、現行バージョン テキスト
で確認されている問題がリストされています。
また、ユーザから報告された現行バージョンお
よび以前のバージョンで修正された問題もリス
トされています。
オンライン ノートの入手先
オンライン ノートは IBM Informix Online Documentation サイト
(http://www.ibm.com/software/data/informix/pubs/library/) から入手できます。さらに、以下
に説明するように、これらのファイルをインストール後、またはインストール前に取得
できます。
インストール前
すべてのオンライン ノートは、製品 CD の /doc ディレクトリにあります。ドキュメ
ント ノート、リリース ノート、および修正された問題と既知の問題についてのファイ
ルにアクセスする最も簡単な方法は、TOC ノート ファイルからのハイパーリンクを介
したアクセスです。
xxii
IBM Informix SQL ガイド: チュートリアル
マシン ノート、および修正された問題と既知の問題についてのファイルは、テキスト
フォーマットでのみ提供されます。
インストール後
デフォルト ロケールの UNIX プラットフォームでは、ドキュメント ノート、リリース
ノート、およびマシン ノートのファイルは、$INFORMIXDIR/release/en_us/0333 ディ
レクトリにあります。
Dynamic Server
Windows では、ドキュメント ノートおよびリリース ノートは Informix フォルダに格
納されています。このフォルダを表示するには、タスクバーから、「スタート」>「プ
ログラム」>「IBM Informix Dynamic Server version」>「Documentation Notes」また
は「Release Notes」を選択します。
マシン ノートは、Windows プラットフォームには適用されません。
Dynamic Server の終り
オンライン ノートのファイル名
オンライン ノートのファイル形式は以下のとおりです。
オンライン ファイル
ファイル形式
例
TOC ノート
prod_os_tocnotes_version.html
ids_win_tocnotes_10.0.html
ドキュメント ノート
prod_bookname_docnotes_version.html/txt
ids_hpl_docnotes_10.0.html
リリース ノート
prod_os_relnotes_version.html/txt
ids_unix_relnotes_10.0.txt
マシン ノート
prod_machine_notes_version.txt
ids_machine_notes_10.0.txt
修正された問題と既知の問 prod_defects_version.txt
題についてのファイル
ids_win_fixed_and_known
_defects_version.txt
ids_defects_10.0.txt
client_defects_2.90.txt
ids_win_fixed_and_known
_defects_10.0.txt
Informix エラー メッセージ集
このファイルは、Informix 製品のバージョン番号別のエラー メッセージおよび修正処置
の包括的なインデックスです。
はじめに
xxiii
UNIX プラットフォームでは、finderr コマンドを使用してエラー メッセージおよび修
正処置を確認します。
Dynamic Server
Windows では、Informix エラー メッセージ集ユーティリティを使用してエラー メッセ
ージおよび修正処置を確認します。このユーティリティを表示するには、タスクバーか
ら「スタート」>「プログラム」>「IBM Informix Dynamic Server version」>
「Informix エラー メッセージ集」を選択します。
Dynamic Server の終り
IBM Informix Online Documentation サイト
(http://www.ibm.com/software/data/informix/pubs/library/) でこれらのファイルにアクセスす
ることもできます。
マニュアル
オンライン マニュアル
IBM Informix 製品では、電子フォーマットのマニュアルを含む CD が提供されます。
マニュアルを CD からインストールするか、または CD からこれらに直接アクセスで
きます。オンライン マニュアルのインストール、表示、および印刷の方法については、
CD に付属するインストール ガイドを参照してください。同じオンライン マニュアル
を IBM Informix Online Documentation サイト
(http://www.ibm.com/software/data/informix/pubs/library/) から入手することもできます。
ペーパー マニュアル
ハードコピー マニュアルを注文するには、営業担当員に連絡するか、または IBM
Publications Center Web サイト (http://www.ibm.com/software/howtobuy/data.html) にアク
セスしてください。
オンライン ヘルプ
それぞれのグラフィカル ユーザ インターフェイス (GUI) で提供される IBM Informix
オンライン ヘルプでは、そのインターフェイスおよび機能についての情報が表示されま
す。オンライン ヘルプを表示するには、それぞれの GUI のヘルプ機能を使用してくだ
さい。
アクセシビリティ
IBM は、身体障害のある閲覧者にもマニュアルへのアクセスを可能にするように努力し
ています。IBM のマニュアルは HTML 形式で入手できるため、スクリーン リーダ (読
上げソフトウェア) などの支援テクノロジーを使用してアクセスできます。IBM のマニ
ュアルの構文ダイアグラムは、スクリーン リーダ (読上げソフトウェア) を使用する場
xxiv
IBM Informix SQL ガイド: チュートリアル
合に限り利用できる小数点付き 10 進数フォーマットに従っています。小数点付き 10
進数フォーマットについて詳しくは、付録の『アクセシビリティ』を参照してくださ
い。
IBM Informix Dynamic Server バージョン 10.0 および CSDK バージョン 2.90 マ
ニュアル セット
以下の表に、IBM Informix Dynamic Server バージョン 10.0 および CSDK バージョン
2.90 マニュアル セットを構成するマニュアルのリストを表示します。これらのマニュ
アルの PDF および HTML バージョンは、
http://www.ibm.com/software/data/informix/pubs/library/ で入手できます。これらのマニュ
アルのハードコピー バージョンは、IBM Publications Center
(http://www.ibm.com/software/howtobuy/data.html) で注文できます。
表 1. Database Server のマニュアル
マニュアル
内容
管理者ガイド
データベース サーバの理解、構成、および管理。
管理者の参照
Informix Dynamic Server 用の参考資料。データベース サーバ ユーティリ
ティ onmode と onstat の構文、構成パラメータと sysmasters 表と論理
ログ レコードについての説明などが含まれます。
バックアップおよび復元 ガ
イド
データのバックアップおよび復元を行うために ON-Bar および ontape ユ
ーティリティを使用する際に理解しておく必要がある概念と方法。
DB-Access ユーザーズ ガイ
ド
DB-Access ユーティリティを使用した、Informix データベースのデータの
アクセス、修正、および取得。
DataBlade API
Function Reference
DataBlade API 関数、および DataBlade API がサポートする ESQL/C 関
数のサブセット。DataBlade API を使用して、Informix データベースのデ
ータにアクセスするクライアント LIBMI アプリケーションおよび C 言
語のユーザ定義ルーチンを開発できます。
DataBlade API
Programmer’s Guide
Dynamic Server で提供されている C 言語のアプリケーション プログラ
ミング インターフェイスである DataBlade API。DataBlade API を使用し
て、Informix データベースに格納されているデータにアクセスするクライ
アント アプリケーションおよびサーバ アプリケーションを開発します。
データベース設計および実
装 ガイド
Informix データベースの設計、実装、および管理。
エンタープライズ レプリケ
ーション ガイド
複数のデータベース サーバ間でデータを複製するためにエンタープライ
ズ レプリケーション システムを設計、実装、および管理する方法。
エラー メッセージ ファイ
ル
IBM Informix 製品の使用時に受け取る可能性がある番号付きエラー メッ
セージの原因と修正処置。
はじめに
xxv
表 1. Database Server のマニュアル (続き)
マニュアル
内容
スタートアップ ガイド
IBM Informix Dynamic Server にバンドルされている製品、および他の
IBM 製品とのインターオペラビリティの説明。Dynamic Server の重要な
機能と各バージョンの新機能の要約。
SQL ガイド: 参照
Informix データベース、データ型、システム カタログ表、環境変数、お
よび stores_demo デモンストレーション データベースについての情報。
SQL ガイド: 構文
Informix のすべての SQL 文と SPL 文の構文についての詳細な説明。
SQL ガイド: チュートリア
ル
Informix 製品で実装された SQL についてのチュートリアル。リレーショ
ナル データベースでの作業時に使用される基本的な概念と用語を説明し
ます。
ハイ パフォーマンス ロー
ダ ユーザーズ ガイド
Informix データベースへ/から大量のデータをロードおよびアンロードする
ための、ハイ パフォーマンス ローダ (HPL) へのアクセスと使用。
インストール ガイド
(Microsoft Windows 用)
Windows での IBM Informix Dynamic Server のインストール。
インストール ガイド
(UNIX および Linux 用)
UNIX および Linux での IBM Informix Dynamic Server のインストー
ル。
J/Foundation Developer’s
Guide
Java プログラム言語による Informix Dynamic Server with J/Foundation 用
ユーザ定義ルーチン (UDR) の記述。
Large Object Locator
DataBlade Module User’s
Guide
ラージ オブジェクト データを作成または格納する他のモジュールから使
用可能な DataBlade ファウンデーション モジュールである Large Object
Locator の使用。Large Object Locator は、ラージ オブジェクトへの単一
で一貫したインターフェイスの作成を可能にし、データベースの外部に保
存されているデータも組み込むようにラージ オブジェクトの概念を拡張
します。
移行ガイド
Informix データベース サーバの最新バージョンへの変換および最新バー
ジョンからのリバージョン。異なる Informix データベース サーバ間の移
行について説明します。
Optical Subsystem Guide
光ディスクへのバイト (BYTE) 型およびテキスト (TEXT) 型データの格
納を支援するユーティリティである光ディスク記憶サブシステム。
パフォーマンス ガイド
最適なパフォーマンスを実現するための IBM Informix Dynamic Server の
構成と運用。
R-Tree Index User’s Guide
適切なデータ型に対する R ツリー インデックスの作成、R ツリー アク
セス方法を使用する演算子クラスの新規作成、および R ツリー副アクセ
ス方法を使用するデータベースの管理。
SNMP Subagent Guide
簡易ネットワーク管理プロトコル (SNMP) ネットワーク マネージャによ
る Informix サーバ状態の監視を可能にする、IBM Informix サブエージェ
ント。
xxvi
IBM Informix SQL ガイド: チュートリアル
表 1. Database Server のマニュアル (続き)
マニュアル
内容
Storage Manager 管理者ガイ
ド
Informix データベース サーバ向けの記憶装置およびメディアを管理する
Informix 格納域マネージャ (ISM)。
Trusted Facility Guide
監査ログの作成と管理を含む、Dynamic Server の安全保護監査機能。
ユーザ定義ルーチンおよび
データ タイプ 開発者ガイ
ド
新規の型を定義し、ユーザ定義ルーチン (UDR) を使用して IBM Informix
Dynamic Server の機能を拡張する方法。
Virtual-Index Interface
Programmer’s Guide
IBM Informix Dynamic Server に組み込まれたインデックス方式を拡張す
るための、仮想インデックス インターフェイス (VII) による副アクセス
方法 (インデックス) の作成。通常は DataBlade モジュールで使用しま
す。
Virtual-Table Interface
Programmer’s Guide
仮想テーブル インターフェイス (VTI) での主アクセス方法の作成。これ
により、ユーザは Informix の表、および Informix Dynamic Server のス
トレージ方式に準拠しないデータに対して、単一の SQL インターフェイ
スを使用できます。
表 2. クライアント/接続関連のマニュアル
マニュアル
内容
Client Products Installation
Guide
UNIX、Linux、および Windows を使用しているコンピュータへの、IBM
Informix Client Software Developer’s Kit (Client SDK) および IBM
Informix Connect のインストール。
Embedded SQLJ User’s
Guide
Java プログラムに SQL 文を埋め込むための IBM Informix Embedded
SQLJ の使用。
ESQL/C Programmer’s
Manual
C 言語用埋込み SQL の IBM Informix 実装。
GLS ユーザーズ ガイド
IBM Informix API およびデータベース サーバでの、各国の言語、国/地域
別情報、およびコード セットの処理を可能にする、広域言語サポート
(GLS) 機能。
JDBC Driver Programmer’s
Guide
Java アプリケーションまたはアプレットから Informix データベースへの
接続を行うための、JDBC ドライバのインストールと使用。
.NET Provider Reference
Guide
.NET クライアント アプリケーションによる Informix データベース内の
データのアクセスと操作を可能にするための、Informix .NET Provider の
使用。
ODBC Driver Programmer’s
Manual
Informix データベースにアクセスし、Informix データベース サーバと対
話するための、Informix ODBC Driver API の使用。
はじめに
xxvii
表 2. クライアント/接続関連のマニュアル (続き)
マニュアル
内容
OLE DB Provider
Programmer’s Guide
ActiveX Data Object (ADO) アプリケーションや Web ページなどのクラ
イアント アプリケーションから Informix サーバのデータへのアクセスを
可能にするための、Informix OLE DB Provider のインストールと構成。
Object Interface for C++
Programmer’s Guide
C++ オブジェクト インターフェイスおよび全クラス参照からなるアーキ
テクチャ。
表 3. DataBlade Developer’s Kit のマニュアル
マニュアル
内容
DataBlade Developer’s Kit
User’s Guide
BladeSmith および BladePack を使用した DataBlade モジュールの開発と
パッケージ化。
DataBlade Module
Development Overview
DataBlade モジュール開発の基本的な説明。DataBlade モジュールの開発
例が含まれています。
DataBlade Module Installation DataBlade モジュールのインストール、および Informix データベースで
and Registration Guide
DataBlade モジュールを管理するための BladeManager の使用。
業界標準への準拠
米国規格協会 (ANSI) と国際標準化機構 (ISO) は、共同で構造化問合せ言語 (SQL) 用
の一連の業界標準を確立しました。IBM Informix SQL ベースの製品は、ISO 9075:1992
と同一である、SQL-92 エントリ レベル (ANSI X3.135-1992 として発行) に完全準拠し
ています。さらに、Informix データベース サーバの多くの機能が、SQL-92 中間および
全レベル、および X/Open SQL CAE (共通アプリケーション環境) 標準に準拠していま
す。
xxviii
IBM Informix SQL ガイド: チュートリアル
第 1 章 データベースの概念
データ モデルによる説明 . . . . . . . .
データの格納 . . . . . . . . . . .
データの問合せ . . . . . . . . . .
データの変更 . . . . . . . . . . .
複数のユーザによる同時利用とセキュリティ .
データベース利用の制御 . . . . . . .
アクセス管理ストラテジ . . . . . .
集中管理 . . . . . . . . . . . .
重要なデータベース用語 . . . . . . . .
リレーショナル データベース モデル . .
表 . . . . . . . . . . . . . .
列 . . . . . . . . . . . . . .
行 . . . . . . . . . . . . . .
ビュー . . . . . . . . . . . . .
シーケンス . . . . . . . . . . .
表の操作 . . . . . . . . . . . .
オブジェクト リレーショナル モデル (IDS)
構造化問合せ言語 (SQL). . . . . . . .
標準 SQL. . . . . . . . . . . .
Informix SQL と ANSI SQL . . . . .
対話型 SQL . . . . . . . . . . .
一般的なプログラミング . . . . . . .
ANSI 標準準拠データベース . . . . .
広域言語サポート (GLS). . . . . . .
サマリ . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2
3
4
5
6
6
6
8
8
8
9
10
10
10
10
10
11
12
13
13
14
14
14
15
15
本章について
この章では、基本的なデータベース概念と、以下のトピックの概要について説明しま
す。
v データ モデル
v 複数ユーザ
v データベース用語
v SQL (構造化問合せ言語)
データベースは、SELECT 文で開始します。これについては、17 ページの『第 2 章
SELECT 文の作成』で説明します。
© Copyright IBM Corp. 1996, 2004
1
データ モデルによる説明
データベースに収集される情報とファイルに収集される情報の基本的な違いは、データ
の編成方法にあります。フラット ファイルは物理的に編成されます。つまり、ある項目
は他の項目の前か後といった関係しかありません。しかし、データベースの内容はデー
タ モデル に従って編成されます。データ モデルは計画またはマップであり、データの
単位を定義し、各単位間の相互関係を指定します。
例えば、数字はファイルにもデータベースにも入れることができます。ファイルでの数
字は、ファイル内のある場所に置かれる単なる数字に過ぎません。これに対して、デー
タベースでの数字は、データ モデルによって割り当てられた特定のロール (データベー
ス サーバ管理の役割分担) を持っています。このロールには、顧客 が注文 した品目
として販売された製品 の価格 が含まれます。これら価格、製品、品目、注文、および
顧客というそれぞれの要素もまた、データ モデルによって指定されたロールを持ってい
ます。データ モデルを図 1 に図示します。
2
IBM Informix SQL ガイド: チュートリアル
1015 06/27/98 1 case baseball gloves $450.00
1014 06/25/98 1 case footballs $960.00
1013 06/22/98 1 each tennis racquet $19.80
1012 06/18/98 1 case volleyballs $840.00
1011 06/18/98 5 each tennis racquet $99.00
1010 06/17/98 1 case tennis balls $36.00
1003
05/22/98
1001
05/20/98
tennis
racquet
$19.80
2
volleyball
nets
Anthony
Higgins
1011
06/18/98
1013
06/22/98
1
case
tennis
balls
図 1. データ モデル使用の利点
データ モデルの設計は、データベースを作成するときに行います。そのモデルから策定
される計画に従って、データの単位を挿入します。資料によっては、データ モデル の
代わりにスキーマ という用語を使用している場合があります。
データの格納
データベースには、データベースの編成方法も格納されます。これも、データベースが
ファイルと異なる点です。
ファイルは複雑な内部構造を持っていますが、その構造の定義はファイル内ではなく、
ファイルを作成したり使用したりするプログラムの内部に格納されます。例えば、ワー
ド プロセッシング プログラムに格納される文書ファイルには、文書の形式を記述する
第 1 章 データベースの概念
3
詳細な構造が含まれる場合があります。しかし、この構造はファイルではなくプログラ
ム内で定義されているため、ワード プロセッシング プログラムのみがファイルの内容
を解読することができます。
データ モデルの場合はその記述先となるデータベースに格納されます。したがってデー
タベース内に構造が定義されているため、データベースを使用するすべてのプログラム
での利用が可能です。データ モデルはデータの項目名だけでなくデータ型も定義するた
め、プログラムはデータベースに合わせて処理を変化させることができます。例えば、
あるデータベースで価格 項目が 8 桁の 10 進数であり、小数部が 2 桁であるとしま
す。プログラムは、このデータ型の数字に適した記憶域を割り当てることができます。
プログラムとデータベースの関係については、235 ページの『第 8 章 SQL を使用した
プログラミング』と 265 ページの『第 9 章 SQL プログラムによるデータの更新』で説
明します。
データの問合せ
データベースとファイルでは、そのアクセス方法も異なります。ファイル内のデータ
は、順番に検索して、各行または各レコード内の特定の物理位置にある特定の値を探す
ことができます。つまり、「1 番目のフィールドに 1013 という数値を持つレコードは
どれか」という問合せをすることになります。図 2 に、このタイプの検索を示します。
1015 06/27/98 1 case baseball gloves $450.00
1013 06/22/98 1 each tennis racquet $19.80
06/22/98 1 case tennis balls
$36.00
06/22/98 1 case tennis balls
$48.00
1012 06/18/98 1 case volleyballs $840.00
1011 06/18/98 5 each tennis racquet $99.00
1010 06/17/98 1 case tennis balls $36.00
図 2. ファイルの順次探索
これに対し、データベースに対して問合せを行う場合は、モデルで定義された用語を使
用します。データベースに対しては、次のような問合せを実行できます。「New Jersey
の顧客 が注文 した Shimara Corporation 製の製品 で、出荷日 が第 3 四半期のものは
何か」。このタイプの問合せについて、図 3 に示します。
4
IBM Informix SQL ガイド: チュートリアル
1016
06/29/98
Shimara
New Jersey
Cathy
O'Brian
1019
07/16/98
1023
07/24/98
Bob
Shorter
Run: Next Restart Exit
Display the next page of query results
--------stores-----------Press CTRL-W for Help-----1019 Bob Shorter SHM swim cap 07/16/98
図 3. データベースの問合せ
つまり、ファイルに格納されているデータにアクセスする場合は、ファイルの物理的な
レイアウトを表す用語で問合せを行う必要があるということです。データベースへの問
合せを行うときは、コンピュータの記憶域に関する詳細は無視し、データベースで定義
された現実の世界を反映する言葉を使用して、問合せを行うことができます。
問合せに使用する言語については、17 ページの『第 2 章 SELECT 文の作成』と 137
ページの『第 5 章 高度な SELECT 文の作成』で説明します。
また、データ モデルをビルドして実装する方法については、「IBM Informix: データベ
ース設計および実装 ガイド」を参照してください。
データの変更
データ モデルを使用すると、データベースの内容を変更するときにミスを起こす可能性
を小さくすることもできます。例えば、「Presta または Schraeder というメーカー のす
べての在庫品 を検索して、その価格 を 13% 上げる」というような文で、データベー
スに問合せを行うことができます。このように、データの意味を反映する用語で、変更
内容を記述します。ファイル内にあるレコードのフィールドの詳細を検討することに時
間や労力を割く必要がなくなり、エラーの確率が低くなります。
第 1 章 データベースの概念
5
格納されているデータを変更する文の詳細については、 183 ページの『第 6 章 データ
の変更』を参照してください。
複数のユーザによる同時利用とセキュリティ
データベースは、多くのユーザの共通資源にすることができます。1 つのデータベース
に対して、複数のユーザが同時に問合せや変更ができます。その場合は問合せと変更が
衝突せず順次処理されるよう、データベース サーバ (すべてのデータベースの内容を管
理するプログラム) が調整します。
ユーザが並行してデータベースを利用することには大きな利点がありますが、同時にセ
キュリティとプライバシーという新たな問題が生じます。一部のデータベースはプライ
ベートであり、個人が独自に使用するためにセットアップされています。特定のグルー
プ間でのみ共有する必要がある機密事項を格納するデータベースもあります。また、一
般にアクセスできるデータベースもあります。
データベース利用の制御
Informix データベース ソフトウェアには、データベースの利用を制御する機能が組み込
まれています。次のように機能するように、データベースを設計できます。
v 個人専用のデータベースにする。
v データベースの内容全体をすべてのユーザまたは特定のユーザに公開する。
v 一部のユーザに対し、表示できるデータの選択を制限する (ユーザのグループごとに
異なるデータを表示する)。
v 特定のユーザに、特定のデータの表示を許可し、その変更を禁止する。
v 特定のユーザに、新しいデータの追加を許可し、古いデータの変更を禁止する。
v 特定のユーザに、既存のデータのすべて、あるいは特定の部分のみの変更を許可す
る。
v 追加または変更されたデータが、データ モデルに準拠していることを確認する。
アクセス管理ストラテジ
データベース管理者 (DBA) は、ロール を設定してクラスのメンバとして扱うことによ
って、多くのユーザのアクセス権を標準化したり変更したりすることができます。DBA
がロールにアクセス権を割り当てると、そのロールのすべてのユーザにアクセス権が付
与されます。それらのロールを有効化するには、ユーザは SET ROLE 文を発行する必
要があります。ロールの定義と操作に使用する SQL 文には、CREATE ROLE、DROP
ROLE、GRANT、REVOKE、および SET ROLE があります。
ロールを作成して付与するには:
1. CREATE ROLE 文を使用して、現行のデータベース内に新規ロールを作成します。
2. GRANT 文を使用して、そのロールにアクセス権を付与します。
6
IBM Informix SQL ガイド: チュートリアル
3. GRANT ROLE 文を使用して、そのロールをユーザまたは PUBLIC (すべてのユー
ザ) に付与します。
4. ユーザは、SET ROLE 文を発行してそのロールを有効化する必要があります。
ロールの定義と操作のための SQL 構文の詳細については、「IBM Informix: SQL ガイ
ド: 構文」を参照してください。
DBA は、デフォルト ロール を定義して、個々のユーザまたは特定のデータベースの
PUBLIC グループにロールを割り当てることができます。ユーザがそのデータベースを
使用して接続を確立すると、SET ROLE 文を発行しなくても、自動的にロールが活動化
されます。各ユーザは、デフォルト ロールのアクセス権のほか、ユーザに個々に付与さ
れたアクセス権を持ちます。
注: 異なるデフォルト ロールがユーザと PUBLIC に割り当てられた場合は、ユーザの
デフォルト ロールが優先されます。
デフォルト ロールにアクセス権を定義して付与するには:
1. CREATE ROLE 文を使用して、現行のデータベース内に新規ロールを作成します。
2. GRANT 文を使用して、そのロールにアクセス権を付与します。
3. ロールをユーザに付与し、次の構文を使用して、そのロールをユーザまたは PUBLIC
のデフォルト ロールとして設定します。
GRANT DEFAULT ROLE rolename TO username
または
GRANT DEFAULT ROLE rolename TO PUBLIC
4. ユーザからデフォルト ロールの関連付けを解除するには、REVOKE DEFAULT
ROLE 文を使用します。
デフォルト ロールを削除できるのは、DBA またはデータベース所有者のみです。
5. 現行のロールをデフォルト ロールにリセットするには、SET ROLE DEFAULT 文を
使用します。
セキュリティ上の理由から、DBA はアクセスが限定されたロールを作成できます。例
えば、データベース システム管理者 (DBSA) または DBSA が組込み EXTEND ロール
を付与したユーザのみが、EXTERNAL キーワードで定義された UDR を作成または削
除できます。ロールの定義と操作のための外部ルーチン参照セグメントまたは SQL 文
の詳細については、「IBM Informix: SQL ガイド: 構文」を参照してください。
デフォルト ロールの詳細については、「IBM Informix: Dynamic Server 管理者ガイド」
を参照してください。
データベースに対するアクセス権を付与および制限する方法については、
「IBM Informix: データベース設計および実装 ガイド」を参照してください。
第 1 章 データベースの概念
7
集中管理
多くの人が使用するデータベースは貴重であるため、大切なビジネス資産として保護す
る必要があります。多くの貴重なデータをコンパイルし、なおかつ多くの社員がそのデ
ータへアクセスできるように管理することは、非常に重要な問題です。この難題を解決
するには、パフォーマンスを維持しながらデータを保護する必要があります。データベ
ース サーバを使用すれば、これらのタスクを集中化できます。
データベースは、損害が起こらないよう保護しなければなりません。ソフトウェアおよ
びハードウェアの障害、火災や洪水といった自然災害のリスクなど、数多くの危険があ
ります。重要なデータベースが消失すると、かなりの確率で損害が発生します。損害が
発生すると、消失したデータの再作成に費用および労力が発生するだけでなく、データ
ベース ユーザの生産時間が奪われ、ユーザが作業できない間に取引や信用が失われるこ
とがあります。データベースを定期的にバックアップすることで、このような災害によ
る影響を少なくすることができます。
多くのユーザが使用する大規模なデータベースの場合は、保守と調整が必要です。担当
者がシステム資源の利用状況やデータベースの発展過程を図表で監視し、障害が発生し
やすい部分を予測し、データベースの拡張を計画することが必要です。ユーザからアプ
リケーション プログラムの問題が報告された場合、担当者は問題を診断して解決しなけ
ればなりません。迅速な応答が重要な場合、担当者はシステムのパフォーマンスを分析
して、応答が遅れる原因を突き止めなければなりません。
重要なデータベース用語
次の章に進む前に、いくつかの用語について理解しておく必要があります。使用するデ
ータベース サーバによって、データベースおよびデータ モデルを説明する用語が異な
る場合があります。
リレーショナル データベース モデル
Informix データベース サーバで作成するデータベースは、オブジェクト リレーショナ
ル データベースです。実際には、すべてのデータは行 および列 で構成される表 形式
で格納されます。次にそれぞれの説明を示します。
8
関係
説明
表 = エンティティ
各表は、1 つの対象または 1 種類の事柄についてデ
ータベースが持っているすべてのデータを表しま
す。
列 = 属性
各列は、表が記述する対象が持つ 1 つの機能、特
性、またはファクトを表します。
行 = インスタンス
各行は、表が記述する対象が持つ 1 つのインスタン
スを表します。
IBM Informix SQL ガイド: チュートリアル
エンティティおよび属性の選択方法についてのルールもありますが、それらが重要にな
るのはデータベースを新しく設計する場合だけです (データベース設計の詳細について
は、「IBM Informix: データベース設計および実装 ガイド」を参照してください)。既存
のデータベースではデータ モデルは既に設定されています。既存のデータベースを使用
する場合、表と列の名前、および表と列が現実の世界で何に対応しているかを理解して
おけば十分です。
表
データベースは、1 つ以上の表にグループ分けされる情報を収集したものです。表は、
行と列が編成するデータ項目 の配列です。デモンストレーション データベースは、す
べての Informix データベース サーバ製品とともに配布されます。次の図に、デモンス
トレーション データベースの表の一部を示します。
stock_num
.
.
.
manu_code
.
.
.
description
.
.
.
unit_price
.
.
.
unit
.
.
.
unit_descr
.
.
.
1
HRO
baseball gloves
250.00
case
10 gloves/case
1
HSK
baseball gloves
800.00
case
10 gloves/case
1
SMT
baseball gloves
450.00
case
10 gloves/case
2
HRO
baseball
126.00
case
24/case
3
HSK
baseball bat
240.00
case
12/case
4
HSK
football
960.00
case
24/case
4
HRO
football
480.00
case
24/case
5
.
.
.
NRG
.
.
.
tennis racquet
.
.
.
28.00
.
.
.
each
.
.
.
each
.
.
.
313
ANZ
swim cap
60.00
case
12/box
表は、1 つのエンティティ、つまりデータベースが記述する対象の 1 つの型について、
DBA (Database Administrator: データベース管理者) が格納するものすべてを表現しま
す。例の表 stock は、スポーツ用品店が在庫として持つ商品について、DBA が格納す
る必要のあるすべてを表しています。このほかに、デモンストレーション データベース
には、customer や orders といったエンティティを表す表があります。
データベースは表の集合と考えることができます。データベースを作成することは、互
いに関連する複数の表を作成することになります。表に対して問合せまたは変更を行う
権限は、表単位で制御することができるため、ユーザによって参照または変更できる表
が異なることもあります。
第 1 章 データベースの概念
9
列
表の各列には、属性 が 1 つ含まれます。属性とは、表の対象を記述する 1 つの特性、
機能、またはファクトです。表 stock の列には、在庫品に関するファクトとして、在庫
数、メーカー コード、説明、価格、および取扱い単位が示されています。
行
表の各行は表の対象のインスタンス で、そのエンティティの具体例になります。表
stock の各行は、スポーツ用品店が販売する商品の各品目を表しています。
ビュー
ビューは特定の SELECT 文に基づいた仮想表です。また、ビューはデータベースの内
容を動的に制御するピクチャでもあります。プログラマはこれを使用してユーザが参照
し、操作する情報を決定します。ユーザによって参照できるデータベースの内容は異な
り、これらの内容へのアクセスはいくつかの方法で制限することができます。
シーケンス
シーケンスは、定義された範囲内のすべての番号シーケンスを生成するデータベース オ
ブジェクトです。番号シーケンスは降順と昇順のいずれも可能であり、ともに単調で
す。シーケンスの詳細については、「IBM Informix: SQL ガイド: 構文」を参照してく
ださい。
表の操作
データベースは表の集まりなので、データベースの操作は表に対する操作ということに
なります。オブジェクト リレーショナル モデルは、選択、射影、結合という 3 つの基
本操作をサポートしています。図 4 は選択および射影の操作を示しています。これら 3
つの操作については、後の章で多数の例を使用して詳細に説明します。
10
IBM Informix SQL ガイド: チュートリアル
図 4. 選択と射影の説明
表からデータを選択する 場合、選択する行と、無視する行とがあります。例えば、デー
タベース管理システムに対し、表 stock について「manufacturer code が HSK で、unit
price が 200.00 から 300.00 である行をすべて選択する」という問合せを行うことがで
きます。
表からデータを射影する 場合、選択する列と、無視する列とがあります。例えば、デー
タベース管理システムに対し、表 stock について「列 stock_num、unit_descr、および
unit_price を射影する」という問合せを行うことができます。
各表には 1 つのエンティティに関する情報のみが格納されるため、複数のエンティティ
について情報が必要な場合はそれらの表を結合 しなければなりません。表を結合するに
は多くの方法があります。結合操作の詳細については、 137 ページの『第 5 章 高度な
SELECT 文の作成』 を参照してください。
オブジェクト リレーショナル モデル (IDS)
Dynamic Server を使用してオブジェクト リレーショナル データベースをビルドできま
す。オブジェクト リレーショナル データベースは、文字列、整数、日付、10 進数など
の英数字データをサポートするとともに、次のオブジェクト関連機能により、リレーシ
ョナル モデルの機能を拡張します。
v 拡張性。新しいデータ型 (およびそれをサポートするアクセス方法と関数)、およびユ
ーザ定義ルーチン (UDR) を定義して、データベース サーバの機能を拡張することが
できます。これにより、画像、音声、映像、サイズの大きいテキスト文書などを格納
および管理することが可能になります。
第 1 章 データベースの概念
11
IBM およびサード パーティ ベンダは、いくつかのデータ型とそのアクセス方法を
DataBlade モジュール または共有クラス ライブラリにパッケージ化しています。ユ
ーザは必要に応じて、これらをデータベース サーバにアドオンできます。DataBlade
モジュールを使用すると、直線、多角形、楕円、および円といった 2 次元空間 (地理
空間) オブジェクトなどの非従来型のデータ型を格納して、R ツリー インデックス
からこれらにアクセスすることができます。また DataBlade モジュールには、サイズ
の大きいテキスト文書に対する新しいタイプのアクセス方法が用意されており、これ
には、フレーズ照合、あいまい検索、シノニム照合などが含まれます。
さらに、データ型およびアクセス方法を追加できる Dynamic Server の機能を使用し
て、自分でデータベース サーバを拡張することもできます。詳しくは、
「IBM Informix: ユーザ定義ルーチンおよびデータ タイプ 開発者ガイド」を参照し
てください。
UDR を SPL および C プログラム言語で作成し、アプリケーション論理のカプセル
化または Dynamic Server の機能拡張を実行できます。詳しくは、 305 ページの『第
11 章 SPL ルーチンの作成と使用』 を参照してください。
v 複合データ型。1 つ以上の既存のデータ型を組み合わせた新しいデータ型を定義する
ことができます。複合データ型を使用すれば、列や表のレベルでデータをより柔軟に
編成できます。例えば、単一型の値の集合を含む列や、複数のコンポーネント型を含
む列を、複合データ型で定義することが可能です。
v 継承。他のオブジェクトのプロパティを取得するオブジェクト (型および表) を定義
したり、定義したオブジェクトに固有のプロパティを新しく追加したりすることがで
きます。
Dynamic Server には、関係モデルがもつ以上のオブジェクト指向の機能がありますが、
データはすべて行 と列 をもつ表 の形式で表されます。オブジェクト リレーショナル
モデルはリレーショナル モデルの機能を拡張したものですが、必要に応じて、データ
モデルを従来型のリレーショナル データベースとして実装することもできます。
エンティティおよび属性の選択方法についてのルールもありますが、それらが重要にな
るのはデータベースを新しく設計する場合だけです。オブジェクト リレーショナル デ
ータベースの設計に関する詳細は、「IBM Informix: データベース設計および実装 ガイ
ド」を参照してください。
構造化問合せ言語 (SQL)
ほとんどのコンピュータ ソフトウェアでは、「New Jersey の顧客が行った発注のうち
出荷日が第 3 四半期にあたっているものはどれか」というような、日常用語でデータベ
ース問合せを行える段階には達していません。したがって、ユーザはソフトウェアが簡
単に解析できる制限的な構文で質問を記述する必要があります。次のような用語を使用
して、デモンストレーション データベースへの同じ質問を行うことができます。
12
IBM Informix SQL ガイド: チュートリアル
SELECT * FROM customer, orders
WHERE customer.customer_num = orders.customer_num
AND customer.state = ’NJ’
AND orders.ship_date
BETWEEN DATE(’7/1/98’) AND DATE(’9/30/98’)
この問合せは、構造化問合せ言語 (SQL) の例です。SQL とは、データベースに関する
すべての操作を指示するために使用する言語です。SQL は文で構成され、各文は、機能
を指定する 1 つか 2 つのキーワードで開始します。Informix に実装する SQL には、
ALLOCATE DESCRIPTOR から WHENEVER 文までの多くの SQL 文が含まれます。
ほとんどの文は、データベースをセットアップしたり、調整したりする場合にだけ使用
します。データベースへの問合せやデータベースの更新のために定期的に使用する文は
3 つか 4 つです。SQL 文の詳細については、「IBM Informix: SQL ガイド: 構文」を参
照してください。
SELECT 文は、ほとんどの場合に使用します。SELECT 文は、データベースからデータ
を抽出するのに使用できる唯一の文です。また最も複雑な文でもあります。本書では、
第 2 章と第 3 章を SELECT 文の説明に当てています。
標準 SQL
SQL および関係モデルは、1970 年代のはじめから半ばにかけて、IBM で発明および開
発されました。IBM によって、実用的なリレーショナル データベースの実装が可能で
あること、および SQL がこれらを制御できる便利な言語であることが証明されてか
ら、他の SQL インプリメンテーションが開発されるようになりました。
パフォーマンスや競争力を高め、またはローカルなハードウェアやソフトウェア機能を
使用するために実装されるこれらの SQL は、インプリメンテーションごとに異なって
おり、IBM バージョンの言語と微妙に異なっています。そこでこのような相違点を最小
限にするため、1980 年代初期に標準化委員会が設立されました。
米国規格協会 (ANSI) がスポンサである委員会 X3H2 は、1986 年に SQL1 規格を発行
しました。この規格では、SQL 機能のコア セット、および SELECT などの文の構文が
定義されています。
Informix SQL と ANSI SQL
Informix が実装する SQL は、標準 SQL と互換性があります。また、Informix SQL
は、この言語の IBM バージョンとも互換性があります。ただし、Informix SQL には、
標準に対して拡張機能 が装備されているため、特定の文に対するオプションまたは機
能、およびその他の広範なルールが追加されています。ただし、相違点のほとんどは、
日常的には使用頻度の低い文に関係しています。例えば、通常使用する SQL の 90%
を占める SELECT 文には、ほとんど違いがありません。
第 1 章 データベースの概念
13
ただし、Informix SQL の拡張機能が存在するため、矛盾が発生します。Informix の数多
くのユーザは、プログラムおよびストアド ルーチン内に Informix スタイルの SQL を
埋め込んでいます。IBM データ管理製品スイートに Informix 製品が組み込まれた現
在、ユーザは IBM に対して Informix スタイルの SQL 言語を変更しないように要求し
ています。一方、ANSI 標準に完全に準拠する方法でデータベースを使用する機能が必
要なユーザも存在します。これらのユーザは、標準に準拠するよう IBM が言語を変更
することを要求しています。
IBM では、次のような調整を行うことでこの矛盾を解決します。
v 標準に対する拡張機能を備えた SQL の Informix スタイル バージョンをデフォルト
で使用できる。
v Informix スタイルの SQL 言語処理プログラムに対して、SQL の使用をチェックし、
Informix の拡張機能を使用する場合は常に警告フラグを立てるように要求できる。
Informix と ANSI 標準が異なる場合は、Informix 構文が SQL の ANSI 標準の拡張で
あることが「IBM Informix: SQL ガイド: 構文」に示されています。
対話型 SQL
本書の例を実行したり、SQL およびデータベース設計を実験するには、SQL 文を対話
式に実行できるプログラムが必要です。DB–Access は、このプログラムに該当します。
このプログラムを使用すると、SQL 文を構成してから、SQL をデータベース サーバに
渡して実行し、結果をユーザに表示することができます。
一般的なプログラミング
SQL 文を取り込んでデータベース サーバとの間でデータを交換するプログラムを作成
できます。すなわち、データベースからデータを検索し、選択した形式にフォーマット
できます。任意のソースから任意の形式でデータを取り出し、処理して、データベース
に挿入するプログラムを作成することもできます。
データベースのデータおよびオブジェクトと連動するような、ストアド ルーチンと呼ば
れるプログラムを作成することができます。作成したストアド ルーチンはデータベース
の表に直接格納されます。その後、DB–Access または IBM Informix ESQL/C のような
SQL アプリケーション プログラム インターフェイス (API) でストアド ルーチンを実
行できます。
235 ページの『第 8 章 SQL を使用したプログラミング』と 265 ページの『第 9 章
SQL プログラムによるデータの更新』には、プログラム内での SQL の使用方法の概要
について記載しています。
ANSI 標準準拠データベース
ANSI 標準準拠のデータベースを作成するには、作成時にキーワード MODE ANSI を
使用します。そのようなデータベース内では、ANSI/ISO 標準の一定の特性が適用され
14
IBM Informix SQL ガイド: チュートリアル
ます。例えば、データを更新する動作はすべて自動的にトランザクション内で実行され
るため、変更は完全に行われるか、それとも全く行われないかが保証されます。ANSI
標準準拠のデータベース間の動作の違いについては、「IBM Informix: SQL ガイド: 構
文」の文の説明に記載されています。ANSI 標準準拠データベースの詳細については、
「IBM Informix: データベース設計および実装 ガイド」を参照してください。
広域言語サポート (GLS)
Informix データベース サーバ製品には、広域言語サポート (GLS) 機能があります。
GLS を使用することで、U.S. ASCII 英語に加え、他のロケールで SQL データおよび
識別子に ASCII が対応していない文字を使用することができます。また、GLS 機能を
使用して特定のロケールの習慣に対応することができます。ロケール ファイルには、金
額形式、日付形式、照合順序などについての文化に固有の情報が含まれています。GLS
に関する詳細は、「IBM Informix: GLS ユーザーズ ガイド」を参照してください。
サマリ
データベースは関連する情報の集まりですが、他のデータ格納方法とは基本的に異なり
ます。データベースには、データだけでなく、各データ項目を定義したり、その意味を
他の項目や現実の世界と対比して指定するデータ モデルが格納されます。
複数のユーザが同時にデータベースにアクセスして変更を加えることができます。ユー
ザによって参照できるデータベースの内容は異なり、これらの内容へのアクセスはいく
つかの方法で制限することができます。
リレーショナル データベースは表で構成され、表は列と行で構成されます。リレーショ
ナル モデルでは、選択、射影、結合という、表に対する 3 つの基本操作がサポートさ
れています。
オブジェクト リレーショナル データベースは、リレーショナル データベースの機能を
拡張したものです。ユーザは、音声、映像、サイズの大きいテキスト文書などを格納お
よび管理できる新しいデータ型を定義することができます。1 つ以上の既存のデータ型
を組み合わせた複合データ型を定義すると、データを、列や表により柔軟に編成できま
す。また、別のデータベース オブジェクトのプロパティを継承する型および表を定義し
たり、定義したオブジェクトに固有のプロパティを新しく追加したりできます。
データベースの操作、またはデータベースへの問合せを実行するには、SQL を使用しま
す。SQL は IBM が開発し、ANSI が標準化した言語です。ANSI で定義された言語に
Informix の拡張機能を追加して使用しますが、IBM Informix ツールを使用すると、
ANSI 標準に厳密に準拠させることもできます。
データベース操作は、2 層のソフトウェアによって実行されます。下位層はデータベー
ス サーバであり、常に SQL 文を実行し、ディスク内およびコンピュータ メモリ内の
データを管理します。上位層は、IBM、ユーザ、他のベンダ、または他のユーザなどに
第 1 章 データベースの概念
15
より作成される多くのアプリケーションのいずれかになります。ミドルウェアはデータ
ベース サーバとアプリケーションをリンクするコンポーネントで、データベース ベン
ダから提供され、クライアント プログラムをデータベース サーバにバインドします。
IBM Informix Stored Procedure Language (SPL) は、そのようなツールの一例です。
16
IBM Informix SQL ガイド: チュートリアル
第 2 章 SELECT 文の作成
SELECT 文について . . . . . . . . . .
SELECT 文の出力 . . . . . . . . . .
ラージ オブジェクト データ型の出力 . .
ユーザ定義のデータ型の出力 . . . . .
非デフォルト コード セットの出力 . . .
基本的な概念 . . . . . . . . . . .
アクセス権 . . . . . . . . . . .
関係演算 . . . . . . . . . . . .
選択と射影 . . . . . . . . . . .
結合 . . . . . . . . . . . . .
単一表 SELECT 文 . . . . . . . . . .
アスタリスク記号 (*) の使用方法 . . . .
列の再配列 . . . . . . . . . . .
ORDER BY 節を使用した行のソート . . .
昇順 . . . . . . . . . . . . .
降順 . . . . . . . . . . . . .
複数の列を基にしたソート . . . . . .
特定の列の選択 . . . . . . . . . . .
サブ文字列の選択 . . . . . . . . .
ORDER BY と英語以外のデータ . . . .
WHERE 節の使用方法 . . . . . . . .
比較条件の作成 . . . . . . . . . . .
行のインクルード . . . . . . . . .
行の除外 . . . . . . . . . . . .
行範囲の指定 . . . . . . . . . .
特定範囲の行の除外 . . . . . . . .
WHERE 節を使用した値のサブセットの検索
NULL 値の識別 . . . . . . . . .
複合条件の作成 . . . . . . . . . .
正確なテキスト比較の使用 . . . . . .
変数テキスト検索の使用 . . . . . . .
単一文字ワイルドカードの使用 . . . .
MATCHES と非デフォルト ロケール . .
特殊文字のプロテクト . . . . . . .
WHERE 節でのサブスクリプトの使用方法.
特定の行を選択するためのFIRST節の使用 . .
ORDER BY 節を使用しない FIRST 節 . .
ORDER BY 節を使用する FIRST 節 . .
式と導出値 . . . . . . . . . . . .
算術式 . . . . . . . . . . . . .
© Copyright IBM Corp. 1996, 2004
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
19
19
19
20
20
20
20
21
21
23
24
25
25
26
27
27
28
30
35
36
38
38
40
40
41
42
43
45
46
47
48
48
52
53
54
55
56
57
58
58
17
CASE 式 . . . . . . .
導出列のソート . . . . .
SELECT 文での行 ID 値の使用
複数表の SELECT 文 . . . . .
デカルト積の作成 . . . . .
結合の作成 . . . . . . .
交差結合 (IDS) . . . . .
等価結合 . . . . . . .
自然結合 . . . . . . .
複数表結合 . . . . . .
問合せのショートカット . . .
別名の使用 . . . . . .
INTO TEMP 節. . . . .
サマリ . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
63
64
65
66
67
68
69
69
72
74
76
76
79
80
本章について
SELECT は、最も重要かつ複雑な SQL 文です。この文は、SQL 文 INSERT、
UPDATE、および DELETE とともにデータを操作するために使用します。SELECT 文
は、データベースからデータを抽出するために使用します。INSERT 文の一部である場
合は新規行を作成し、UPDATE 文の一部である場合は情報を更新できます。
SELECT 文はデータベース内の情報を問合せる主要な方法です。SELECT 文はプログラ
ム、レポート、フォーム、スプレッドシートなどからデータを抽出する際に重要な働き
をします。また、SELECT 文は DB–Access のような問合せツールで使用できるほか、
アプリケーションに埋め込むこともできます。
この章では、SELECT 文を使用して、リレーショナル データベースへ問合せを行い、
データを抽出する基本的な方法を紹介します。具体的には、1 つ以上の表から複数の列
または行の情報を得るために文をカスタマイズする方法、SELECT 文に式や関数をイン
クルードする方法、データベース内の表間のさまざまな結合条件を設定する方法につい
て説明します。SELECT 文の構文および使用方法の詳細は、「IBM Informix: SQL ガイ
ド: 構文」に記載されています。
本書に記載されている例の大部分には、IBM Informix SQLAPI またはデータベース ユ
ーティリティのソフトウェアに付属のデータベース stores_demo の表が使用されていま
す。簡略化のため、各 SELECT 文では抽出されるデータの一部のみを例示します。デ
モンストレーション データベースの構造と内容については、「IBM Informix: SQL ガイ
ド: 参照」を参照してください。SQL では大文字と小文字を区別しませんが、例の中で
は強調するためにキーワードを大文字で表記しています。
18
IBM Informix SQL ガイド: チュートリアル
SELECT 文について
SELECT 文は、リレーショナル データベースのデータを選択して表示する機能を持つ
複数の節から構成されています。それらの節を使用すると、1 つ以上の表やビューから
1 つ以上の条件を指定して列や行を抽出し、データの順番をそろえたり、集計をとって
一時表に格納することができます。
ここでは、SELECT 文を構成する 5 つの節の使用方法を説明します。5 つの節は次の
順序で SELECT 文にインクルードしなければなりません。
1. Projection 節
2. FROM 節
3. WHERE 節
4. ORDER BY 節
5. INTO TEMP 節
Projection 節と FROM 節のみが必須です。この 2 つの節は、抽出の対象となる表と列
を指定するため、データベースに対するすべての問合せの基本となります。他の節は、
次に示す目的に応じて使用します。
v 特定の行を選択したり、join 条件を作成する場合は、WHERE 節を追加する。
v データを作成する順序を変更する場合は、ORDER BY 節を追加する。
v 後で別の問合せで利用できるように問合せ結果を一時表に保存する場合は、INTO
TEMP 節を追加する。
SELECT 文のその他 2 つの節 GROUP BY および HAVING を使用すると、より複雑
なデータ抽出を行うことができます。これらの節については、 137 ページの『第 5 章
高度な SELECT 文の作成』に記載されています。もう 1 つの節 INTO は、SELECT
文からデータを受け取るために、プログラムまたはホスト変数を指定する場合に使用し
ます。SELECT 文を使用するための完全な構文およびルールについては、
「IBM Informix: SQL ガイド: 構文」に記載されています。
SELECT 文の出力
構文はすべての IBM Informix 製品に共通ですが、結果出力の形式と表示はアプリケー
ションに依存します。この章および第 5 章の例に示す SELECT 文とその出力は、
DB–Access で対話型問合せ言語オプションを使用した場合に表示されるものを使用して
います。
ラージ オブジェクト データ型の出力
ラージ オブジェクトを含む SELECT 文を発行する場合、DB–Access は以下のような結
果を表示します。
v テキスト (TEXT) 型列または CLOB 型列には、列の内容が表示される。
v バイト (BYTE) 型列には、実際値ではなく、<BYTE value> が表示される。
第 2 章 SELECT 文の作成
19
v BLOB 型列には、実際値ではなく、<SBlob data> が表示される。
ユーザ定義のデータ型の出力
DB–Access では、特別なルールを使用して、複合データ型または不透明 (OPAQUE) 型
を含む列からの出力を表示します。これらのデータ型については、「IBM Informix: デー
タベース設計および実装 ガイド」を参照してください。
非デフォルト コード セットの出力
文字 (CHAR) 型列の代わりに各国語文字 (NCHAR) 型列を、または可変長文字
(VARCHAR) 型列の代わりに各国語可変長文字 (NVARCHAR) 型を問合せる SELECT
文を発行できます。
広域言語サポート (GLS) の詳細については、「IBM Informix: GLS ユーザーズ ガイ
ド」を参照してください。非デフォルト コード セットにおける各国語文字 (NCHAR)
型および各国語可変長文字 (NVARCHAR) 型の使用方法の詳細については、
「IBM Informix: データベース設計および実装 ガイド」および「IBM Informix: SQL ガ
イド: 参照」を参照してください。
基本的な概念
SELECT 文は、INSERT、UPDATE、および DELETE 文とは異なり、データベース内の
データを変更しません。単にデータの問合せを行います。データの変更は、1 回に 1 人
のユーザしか実行できませんが、データの問合せや選択 は、複数のユーザが同時に行う
ことができます。データを変更する文については、 183 ページの『第 6 章 データの変
更』を参照してください。INSERT、UPDATE、および DELETE 文の構文の説明は、
「IBM Informix: SQL ガイド: 構文」を参照してください。
リレーショナル データベースでは 1 つの列 が 1 データ要素となり、表の各行に共通
して存在する特定のタイプの情報を表します。行 とは、単一のエンティティに関する情
報の集まりで、各項目がデータベースの表の各列に相当します。
データベースの表、システム カタログ表、ビュー などの行や列を選択することができ
ます。システム カタログ表はデータベースに関する情報を格納した特殊な表です。ビュ
ーはカスタマイズされたデータ セットを格納するために作成された仮想テーブルです。
システム カタログ表については、「IBM Informix: SQL ガイド: 参照」に記載されてい
ます。また、ビューについては、「IBM Informix: データベース設計および実装 ガイ
ド」に記載されています。
アクセス権
データの問合せを行う前に、データベースの接続アクセス権と表の選択アクセス権を所
有している必要があります。通常、これらの権限はすべてのユーザに与えられていま
す。データベースに対するアクセス権については、「IBM Informix: データベース設計お
よび実装 ガイド」および「IBM Informix: SQL ガイド: 構文」の GRANT 文と
REVOKE 文に記載されています。
20
IBM Informix SQL ガイド: チュートリアル
関係演算
関係演算 では、1 つ以上の表または関係 を操作して、別の表を作成します。関係演算
には、選択、射影、結合の 3 種類があります。ここでは選択、射影、および簡単な結合
の例を示します。
選択と射影
リレーショナル データベースでいう選択 とは、1 つの表から特定の条件に合致した行
を水平方向 に抽出することを意味します。選択を行う SELECT 文は、表の中のいくつ
かの行とその行に含まれる列をすべて戻します。選択は、SELECT 文の WHERE 節を
使用して実装されます。図 5 にその例を示します。
SELECT * FROM customer WHERE state = ’NJ’
図 5. 問合せ
この問合せを行うと、図 6 に示すような結果になります。表 customer の中の指定条件
に合致した一部の行について、その行に属するすべての列が抽出されます。この例で
は、DB–Access が個別行の各列のデータを表示します。
customer_num
fname
lname
company
address1
address2
city
state
zipcode
phone
119
Bob
Shorter
The Triathletes Club
2405 Kings Highway
customer_num
fname
lname
company
address1
address2
city
state
zipcode
phone
122
Cathy
O‘Brian
The Sporting Life
543d Nassau
Cherry Hill
NJ
08002
609-663-6079
Princeton
NJ
08540
609-342-0054
図 6. 問合せ結果
関係型の用語では、射影 は、一意な行を保持している 1 つの表の列から垂直方向の サ
ブセットを取得することと定義されます。射影を行う、この種の SELECT 文は、表の
中のいくつかの列とその列に含まれる行をすべて戻します。
第 2 章 SELECT 文の作成
21
射影は、SELECT 文の Projection 節の射影リスト を使用して実装されます。図 7 にそ
の例を示します。
SELECT city, state, zipcode FROM customer
図 7. 問合せ
図 8 には、表 customer と同数の行がありますが、その表にある列のサブセットだけが
射影 されます。各行から少量のデータのみが選択されるため、DB–Access は行からの
すべてのデータを 1 行で表示できます。
city
state zipcode
Sunnyvale
San Francisco
Palo Alto
Redwood City
Los Altos
Mountain View
Palo Alto
Redwood City
Sunnyvale
Redwood City
Sunnyvale
..
.
Oakland
Cherry Hill
Phoenix
Wilmington
Princeton
Jacksonville
Bartlesville
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
94086
94117
94303
94026
94022
94063
94304
94063
94086
94062
94085
CA
NJ
AZ
DE
NJ
FL
OK
94609
08002
85016
19898
08540
32256
74006
図 8. 問合せ結果
通常使用する SELECT 文のほとんどは、選択と射影の両方を同時に行います。このよ
うな問合せでは、図 9 に示すように、表の一部の行と列が戻されます。
SELECT UNIQUE city, state, zipcode
FROM customer
WHERE state = ’NJ’
図 9. 問合せ
図 10 では、表 customer の一部の行と列が抽出されています。
22
IBM Informix SQL ガイド: チュートリアル
city
state zipcode
Cherry Hill
Princeton
NJ
NJ
08002
08540
図 10. 問合せ結果
結合
複数の表が共通の 1 つ以上の列に接続されている場合に結合が行われ、結果の新規表が
作成されます。表 items および表 stock のサブセットを使用した問合せを図 11 に示
し、結合の概念を説明します。
SELECT UNIQUE item_num, order_num,
stock.stock_num, description
FROM items, stock
WHERE items.stock_num = stock.stock_num
items (
)
stock (
)
item_num
order_num
stock_num
stock_num
manu_code
description
1
1
2
3
1
1001
1002
1002
1003
1005
1
4
3
5
5
1
1
2
4
5
HRO
HSK
HRO
HSK
NRG
baseball gloves
baseball gloves
baseball
football
tennis racquet
item_num
order_num
stock_num
description
1
1
3
1
1001
1002
1003
1005
1
4
5
5
baseball gloves
football
tennis racquet
tennis racquet
図 11. 2 つの表の結合
図 12 では、表 customer と表 state を結合しています。
第 2 章 SELECT 文の作成
23
SELECT UNIQUE city, state, zipcode, sname
FROM customer, state
WHERE customer.state = state.code
図 12. 問合せ
図 13 は、表 customer と表 state の両方で指定した行および列から構成されていま
す。
city
state zipcode sname
Bartlesville
Blue Island
Brighton
Cherry Hill
Denver
Jacksonville
Los Altos
Menlo Park
Mountain View
Mountain View
Oakland
Palo Alto
Palo Alto
Phoenix
Phoenix
Princeton
Redwood City
Redwood City
Redwood City
San Francisco
Sunnyvale
Sunnyvale
Wilmington
OK
NY
MA
NJ
CO
FL
CA
CA
CA
CA
CA
CA
CA
AZ
AZ
NJ
CA
CA
CA
CA
CA
CA
DE
74006
60406
02135
08002
80219
32256
94022
94025
94040
94063
94609
94303
94304
85008
85016
08540
94026
94062
94063
94117
94085
94086
19898
Oklahoma
New York
Massachusetts
New Jersey
Colorado
Florida
California
California
California
California
California
California
California
Arizona
Arizona
New Jersey
California
California
California
California
California
California
Delaware
図 13. 問合せ結果
単一表 SELECT 文
データベース内の 1 つの表に対する問合せにもさまざまな方法があります。SELECT
文を目的に合わせて構成し、次の処理を実行できます。
v すべての列、または特定の列のみを抽出する。
v すべての行、または特定の行のみを抽出する。
v 抽出したデータに対して計算のみの処理を行う。
v 抽出したデータを目的に応じて並べ替える。
24
IBM Informix SQL ガイド: チュートリアル
最も基本的な SELECT 文には、2 つの必須の節である Projection 節と FROM 節のみ
が含まれます。
アスタリスク記号 (*) の使用方法
図 14 は、射影リスト の manufact 表のすべての列を指定します。明示的 選択リスト
は、表から射影する列名または式のリストです。
SELECT manu_code, manu_name, lead_time FROM manufact
図 14. 問合せ
図 15 では、射影リストの省略形としてワイルドカード を意味するアスタリスク記号
(*) を使用し、表の中のすべての列の名前を表しています。表のすべての列を、その定
義されている順で指定する場合、このアスタリスク記号 (*) を使用します。暗黙的な
選択リストでは、アスタリスク記号を使用します。
SELECT * FROM manufact
図 15. 問合せ
表 manufact には 3 列しかないため、図 14 と図 15 は同じ処理を意味し、同じ結果、
つまり表 manufact 内のすべての列と行のリストを出力します。図 16 に結果を示しま
す。
manu_code manu_name
SMT
ANZ
NRG
HSK
HRO
SHM
KAR
NKL
PRC
Smith
Anza
Norge
Husky
Hero
Shimara
Karsten
Nikolus
ProCycle
lead_time
3
5
7
5
4
30
21
8
9
図 16. 問合せ結果
列の再配列
図 17 では、射影リストで列の順番を変更することでリストされる列の順番を変更する
方法を示しています。
第 2 章 SELECT 文の作成
25
SELECT manu_name, manu_code, lead_time FROM manufact
図 17. 問合せ
図 18 には、直前の問合せ結果と同じ列が含まれていますが、列の順番の指定が異なる
ため表示が異なっています。
manu_name
Smith
Anza
Norge
Husky
Hero
Shimara
Karsten
Nikolus
ProCycle
manu_code lead_time
SMT
ANZ
NRG
HSK
HRO
SHM
KAR
NKL
PRC
3
5
7
5
4
30
21
8
9
図 18. 問合せ結果
ORDER BY 節を使用した行のソート
問合せ結果は、特に順序付けされていません。例えば、22 ページの図 8 と図 18 は、ラ
ンダムな順序で表示されています。
ORDER BY 節を SELECT 文に追加し、特定の順序でデータをソートすることができま
す。ORDER BY 節は、任意のリモートまたはローカルの表またはビューの列名リスト
です。射影リストで使用できる式はすべて、ORDER BY リストでも使用できます。
ORDER BY リストで使用される列が選択トリガを持つ場合、そのトリガは活動化され
ません。
図 19 は、表 manufact の列 manu_code、manu_name、および lead_time のすべての
行を、lead_time の順にソートして戻します。
SELECT manu_code, manu_name, lead_time
FROM manufact
ORDER BY lead_time
図 19. 問合せ
26
IBM Informix SQL ガイド: チュートリアル
Dynamic Server
射影リストには、ORDER BY 節で使用する列を含めなくても構いません。つまり、射
影リストに抽出されない列を基にデータをソートすることもできます。図 20 は、表
manufact の列 manu_code および manu_name のすべての行を、lead_time の順にソー
トして戻します。列 lead_time は、SELECT リストで宣言されていませんが、ORDER
BY 節に含めることができます。
SELECT manu_code, manu_name,
FROM manufact
ORDER BY lead_time
図 20. 問合せ
Dynamic Server の終り
昇順
SELECT 文が抽出したデータは、デフォルトでは昇順 にソートされて表示されます。
ASCII 文字集合において、昇順は、文字 (CHARACTER) 型の場合は大文字の A から小
文字の z への順序になり、数値のデータ型の場合は最低値から最高値への順序になりま
す。日付 (DATE) 型および日時 (DATETIME) 型の場合は、最も早い日時から最新の日
時への順序、時間隔 (INTERVAL) 型の場合は最短の期間から最長の期間への順序にな
ります。
降順
降順は昇順とは逆に、文字 (CHARACTER) 型の場合は、英小文字の z から始まり大文
字の A に至る順序です。数値データ型の場合は数値が減少していく順序です。漢字など
の日本語文字は文字コードの逆順になります。日付 (DATE) 型および日時
(DATETIME) 型の場合は、最新の日時から最も早い日時への順序、時間隔 (INTERVAL)
型の場合は最長の期間から最短の期間への順序になります。図 21 に、降順の例を示し
ます。
SELECT * FROM manufact ORDER BY lead_time DESC
図 21. 問合せ
列名の後にキーワード DESC が続く場合は、抽出されたデータが降順 にソートされま
す。図 22 に例を示します。
第 2 章 SELECT 文の作成
27
manu_code manu_name
SHM
KAR
PRC
NKL
NRG
HSK
ANZ
HRO
SMT
lead_time
Shimara
Karsten
ProCycle
Nikolus
Norge
Husky
Anza
Hero
Smith
30
21
9
8
7
5
5
4
3
図 22. 問合せ結果
ORDER BY 節には、組込みデータ型の任意の列を指定でき (テキスト (TEXT) 型、バ
イト (BYTE) 型、BLOB 型、または CLOB 型を除く)、データベース サーバはその列
の値に基づいてデータをソートします。
複数の列を基にしたソート
複数の列に ORDER BY を指定して、多重ソート を実行することもできます。デフォ
ルトは昇順のままですが、ORDER BY 節で最初にリストされる列が優先されます。
図 23 と図 25、およびそれぞれに対応する問合せ結果に、多重ソートの例を示します。
選択されたデータの表示の順番を変更するには、ORDER BY 節で命名した 2 つの列の
順番を変えます。
SELECT stocknum, manu_code, description, unit_price
FROM stock
ORDER BY manu_code, unit_price
図 23. 問合せ
図 24 では、列 manu_code の値がアルファベット順に並ぶようにソートされ、
ANZ、HRO など、同じ manu_code を持つ行はさらに列 unit_price の値により昇順に
ソートされています。
28
IBM Informix SQL ガイド: チュートリアル
stock_num manu_code description
unit_price
5
9
6
313
201
310
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
tennis racquet
volleyball net
tennis ball
swim cap
golf shoes
kick board
$19.80
$20.00
$48.00
$60.00
$75.00
$84.00
111
112
113
5
6
1
SHM
SHM
SHM
SMT
SMT
SMT
10-spd, assmbld
12-spd, assmbld
18-spd, assmbld
tennis racquet
tennis ball
baseball gloves
$499.99
$549.00
$685.90
$25.00
$36.00
$450.00
..
.
図 24. 問合せ結果
図 25 では、ORDER BY 節の列の順序は逆になります。
SELECT stock_num, manu_code, description, unit_price
FROM stock
ORDER BY unit_price, manu_code
図 25. 問合せ
図 26 では、データは unit_price の昇順に表示され、複数の行に同じ unit_price がある
場合 (例えば、$20.00、$48.00、$312.00)、manu_code はアルファベット順に表示されま
す。
第 2 章 SELECT 文の作成
29
stock_num manu_code description
unit_price
302
302
5
9
103
HRO
KAR
ANZ
ANZ
PRC
ice pack
ice pack
tennis racquet
volleyball net
frnt derailleur
$4.50
$5.00
$19.80
$20.00
$20.00
108
6
305
303
311
SHM
ANZ
HRO
PRC
SHM
crankset
tennis ball
first-aid kit
socks
water gloves
$45.00
$48.00
$48.00
$48.00
$48.00
113
1
8
4
SHM
HSK
ANZ
HSK
18-spd, assmbld
baseball gloves
volleyball
football
..
.
..
.
$685.90
$800.00
$840.00
$960.00
図 26. 問合せ結果
ORDER BY 節の列の順序、およびキーワード DESC の位置は重要です。図 27 中の各
文の ORDER BY 節に含まれている構成要素は同じですが、それぞれが異なる結果を出
力します。ここでは出力結果は表示していません。
SELECT * FROM stock ORDER BY manu_code, unit_price DESC
SELECT * FROM stock ORDER BY unit_price, manu_code DESC
SELECT * FROM stock ORDER BY manu_code DESC, unit_price
SELECT * FROM stock ORDER BY unit_price DESC, manu_code
図 27. 問合せ
特定の列の選択
前節では、表からすべてのデータを抽出して順序付けする方法について説明しました。
しかし、すべてのデータではなく、特定の列のデータのみを抽出する場合もよくありま
す。この場合も、Projection 節と FROM 節を使用して列と表を指定します。また通常、
ORDER BY 節も指定して、データを昇順か降順に並べます。
表 orders のすべての顧客番号を探索する場合は、図 28 に示す文を使用します。
30
IBM Informix SQL ガイド: チュートリアル
SELECT customer_num FROM orders
図 28. 問合せ
この問合せ結果は、図 29 に示すように、表 orders の列 customer_num のデータをす
べて抽出してリスト表示します。重複した顧客番号も表示されます。
customer_num
104
101
104
..
.
122
123
124
126
127
図 29. 問合せ結果
問合せ結果に重複する顧客番号が含まれているのは、一部の顧客が複数件の注文を出し
ているためです。重複した行を射影で表示させる必要がある場合もあります。それ以外
では、それぞれの値が表示される頻度ではなく、個々の異なる値を表示するだけでよい
のです。
重複行を非表示にするには、問合せのレベルごとに、キーワード DISTINCT、またはそ
のシノニムである UNIQUE を選択対象リストの先頭にインクルードします。図 30 に
例を示します。
SELECT DISTINCT customer_num FROM orders
SELECT UNIQUE customer_num FROM orders
図 30. 問合せ
リストを読みやすくするには、図 30 を使用して、図 31 で示すように表 orders の顧客
番号のみの表示にします。
第 2 章 SELECT 文の作成
31
customer_num
101
104
106
110
111
112
115
116
117
119
120
121
122
123
124
126
127
図 31. 問合せ結果
ある顧客からの電話問合せで、顧客注文番号 DM354331 を検索する必要があるとしま
す。表 orders のすべての顧客注文番号をリストするために、図 32 で示す文を使用しま
す。
SELECT po_num FROM orders
図 32. 問合せ
この SELECT 文の問合せ結果は、図 33 に示すように、表 orders の列 po_num をす
べて抽出して表示します。
po_num
B77836
9270
B77890
8006
2865
Q13557
278693
..
.
図 33. 問合せ結果
32
IBM Informix SQL ガイド: チュートリアル
しかし、このリストは便利な順番に並んでいるとはいえません。ORDER BY 節を追加
して列データを昇順でソートすると、図 35 で示すように特定の po_num を検出しやす
くすることができます。
SELECT po_num FROM orders ORDER BY po_num
図 34. 問合せ
po_num
278693
278701
2865
429Q
4745
8006
8052
9270
B77836
B77890
..
.
図 35. 問合せ結果
表から複数の列を選択するには、Projection 節の射影リストにこれらの列をリストしま
す。図 36 に示すように、列を選択する順序は、列が検索される順序、つまり左から右
への順序になります。
SELECT ship_date, order_date, customer_num,
order_num, po_num
FROM orders
ORDER BY order_date, ship_date
図 36. 問合せ
28 ページの『複数の列を基にしたソート』に示すように、ORDER BY 節を使用してデ
ータを昇順または降順にソートし、多重ソートを行うことができます。図 37 に、昇順
の例を示します。
第 2 章 SELECT 文の作成
33
ship_date
order_date customer_num
06/01/1998
05/26/1998
05/23/1998
05/30/1998
06/09/1998
05/20/1998
05/21/1998
05/22/1998
05/22/1998
05/24/1998
05/30/1998
05/31/1998
06/07/1998
06/14/1998
06/17/1998
06/18/1998
06/18/1998
06/22/1998
06/25/1998
06/27/1998
06/29/1998
07/09/1998
07/10/1998
07/11/1998
07/11/1998
07/23/1998
07/24/1998
07/24/1998
06/05/1998
07/06/1998
06/21/1998
06/29/1998
06/29/1998
07/03/1998
07/10/1998
07/03/1998
07/16/1998
07/12/1998
07/13/1998
07/13/1998
07/16/1998
07/16/1998
07/25/1998
07/30/1998
07/30/1998
104
101
104
106
116
112
117
110
111
115
117
104
104
106
110
119
120
121
122
123
124
126
127
order_num po_num
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1012
1011
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
B77836
9270
B77890
8006
2865
Q13557
278693
LZ230
4745
429Q
278701
B77897
B77930
8052
MA003
PC6782
DM354331
S22942
Z55709
W2286
C3288
W9925
KF2961
図 37. 問合せ結果
SELECT と ORDER BY 節を使用して表の中の複数列を抽出する場合、ORDER BY 節
で整数を使用すると、列の位置を簡単に参照できるようになります。ORDER BY リス
トの要素に整数がある場合、データベース サーバはそれを、射影リスト内の位置と認識
します。例えば、ORDER BY リストで 3 (ORDER BY 3) を使用する場合は、射影リ
ストの 3 番目の項目が参照されます。図 38 の文は、図 39 に示すように、同じデータ
を抽出し、表示します。
SELECT customer_num, order_num, po_num, order_date
FROM orders
ORDER BY 4, 1
SELECT customer_num, order_num, po_num, order_date
FROM orders
ORDER BY order_date, customer_num
図 38. 問合せ
34
IBM Informix SQL ガイド: チュートリアル
customer_num
order_num po_num
104
101
104
106
116
112
117
110
111
115
104
117
104
106
110
119
120
121
122
123
124
126
127
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
B77836
9270
B77890
8006
2865
Q13557
278693
LZ230
4745
429Q
B77897
278701
B77930
8052
MA003
PC6782
DM354331
S22942
Z55709
W2286
C3288
W9925
KF2961
order_date
05/20/1998
05/21/1998
05/22/1998
05/22/1998
05/24/1998
05/30/1998
05/31/1998
06/07/1998
06/14/1998
06/17/1998
06/18/1998
06/18/1998
06/22/1998
06/25/1998
06/27/1998
06/29/1998
07/09/1998
07/10/1998
07/11/1998
07/11/1998
07/23/1998
07/24/1998
07/24/1998
図 39. 問合せ結果
図 40 に示すように、列名に整数を割り当てた場合は、キーワード DESC を ORDER
BY 節に含めることができます。
SELECT customer_num, order_num, po_num, order_date
FROM orders
ORDER BY 4 DESC, 1
図 40. 問合せ
このように指定すると、抽出されたデータは、まず列 order_date の値で降順にソート
され、次に列 customer_num の値で昇順にソートされます。
サブ文字列の選択
サブ文字列 を射影リストに含めることにより、文字カラムの値の一部を選択できます。
マーケティング部門で顧客にダイレクト メールを発送することになり、郵便番号を基に
して顧客の居住分布を調査すると仮定します。図 41 に示す問合せと同様の文を記述し
ます。
第 2 章 SELECT 文の作成
35
SELECT zipcode[1,3], customer_num
FROM customer
ORDER BY zipcode
図 41. 問合せ
図 41 では、サブ文字列で列 zipcode (州を示す) の最初の 3 文字と customer_num 全
体を選択して、図 42 で示されているように、それらを郵便番号で昇順にリストしま
す。
zipcode customer_num
021
080
085
198
322
..
.
943
943
946
125
119
122
121
123
103
107
118
図 42. 問合せ結果
ORDER BY と英語以外のデータ
Informix データベース サーバでは、デフォルトで、データベースのデータに対して米国
英語 (U.S. English) 言語環境が使用されます。米国英語 (U.S. English) ロケールは、コ
ード セット順にソートされたデータを指定します。このデフォルト ロケールは、ISO
8859-1 コード セットを使用します。
データベースに英語以外のデータが含まれている場合、データを各国語文字 (NCHAR)
型、または各国語可変長文字 (NVARCHAR) 型の列に格納し、データの言語でソートで
きるようにする必要があります。ORDER BY 節は、各言語に対応した順序でデータを
戻す必要があります。図 43 では、SELECT 文の ORDER BY 節を使用して、表
abonnés を検索し、選択された情報を列 nom 内のデータでソートします。
SELECT numéro,nom,prénom
FROM abonnés
ORDER BY nom
図 43. 問合せ
この問合せ結果の照合順序は、次のようにシステムによって異なります。
36
IBM Informix SQL ガイド: チュートリアル
v 列 nom が文字 (CHAR) 型の場合と各国語文字 (NCHAR) 型の場合。データベース
サーバは文字 (CHAR) 型列のデータをコード セットに出てくる順序でソートしま
す。データベース サーバは各国語文字 (NCHAR) 型列のデータをロケールの照合部
分にリストされている文字の順序でソートします。
v データベースへのアクセス時に、データベース サーバが英語以外の正しいロケール
を使用している場合。英語以外のロケールを使用するには、環境変数
CLIENT_LOCALE および DB_LOCALE を該当するロケール名に設定する必要があり
ます。
図 43 で予想どおりの結果を戻すには、列 nom が、フランス語のロケールを使用する
データベース内の各国語文字 (NCHAR) 型データでなければなりません。また、より小
さい、より大きい、...に等しいなどの演算は、ユーザ指定のロケールの影響を受けま
す。英語以外のデータおよびロケールに関する詳細は、「IBM Informix: GLS ユーザー
ズ ガイド」を参照してください。
図 44 と図 45 に、2 つの異なる出力を示します。
numéro
nom
prénom
13612
13606
13607
13602
13604
13610
13613
13603
13611
13609
13600
13615
13601
13608
13605
13614
Azevedo
Dupré
Hammer
Hämmer
LaForêt
LeMaître
Llanero
Montaña
Oatfield
Tiramisù
da Sousa
di Girolamo
Ålesund
Étaix
Ötker
Øverst
Edouardo Freire
Michèle Françoise
Gerhard
le Greta
Jean-Noël
Héloïse
Gloria Dolores
José Antonio
Emily
Paolo Alfredo
João Lourenço Antunes
Giuseppe
Sverre
Émile
Hans-Jürgen
Per-Anders
図 44. 問合せ結果
図 44 は、ISO 8859-1 のコード セット順に準拠しています。小文字より大文字が前に
順序付けられており、アクセント付き文字で始まる名前 (Ålesund、Étaix、Ötker、および
Øverst) をリストの末尾に移動します。
第 2 章 SELECT 文の作成
37
numéro
nom
prénom
13601
13612
13600
13615
13606
13608
13607
13602
13604
13610
13613
13603
13611
13605
13614
13609
Ålesund
Azevedo
da Sousa
di Girolamo
Dupré
Étaix
Hammer
Hämmer
LaForêt
LeMaître
Llanero
Montaña
Oatfield
Ötker
Øverst
Tiramisù
Sverre
Edouardo Freire
João Lourenço Antunes
Giuseppe
Michèle Françoise
Émile
Gerhard
le Greta
Jean-Noël
Héloïse
Gloria Dolores
José Antonio
Emily
Hans-Jürgen
Per-Anders
Paolo Alfredo
図 45. 問合せ結果
図 45 は、データベース サーバが適切なロケール ファイルを参照した場合、英語以外
の文字を含む名前 (Ålesund、Étaix、Ötker、および Øverstt) が ISO 8859-1 コード セッ
トとは異なる順序で照合されることを示しています。英語以外で始まっている名前は、
ロケールで正しくソートされます。この場合、大文字と小文字は区別されません。
WHERE 節の使用方法
SELECT 文が戻す行のセットは、その文に対するアクティブ セット です。単一行
SELECT 文は、1 つの行を戻します。SELECT 文に WHERE 節を追加して、特定の行
を参照できます。例えば、WHERE 節を使用して行に制限を設定し、特定の顧客からの
注文や、特定の顧客サービス担当者からの問合せが入力された行のみがデータベース サ
ーバから戻されるようにします。
WHERE 節を使用して、比較条件 や結合条件 を設定できます。ここでは、比較条件の
設定についてのみ説明します。結合条件については、後述します。
比較条件の作成
SELECT 文の WHERE 節は、表示する行を指定します。比較条件は、特定のキーワー
ド および演算子 を使用して、検索条件を定義します。
例えば、キーワード BETWEEN、IN、LIKE、または MATCHES のうち 1 つを使用し
て等価性をテストしたり、キーワード IS NULL を使用して NULL 値をテストするこ
とができます。キーワード NOT とこれらのキーワードを組み合わせて、否定条件を設
定することもできます。
38
IBM Informix SQL ガイド: チュートリアル
次の表に、キーワードの代わりに WHERE 節で使用して等値関係をテストする関係演算
子 のリストを示します。
演算子
演算
=
等しい
!= または <>
等しくない
>
より大きい
>=
より大か等しい
<
より小さい
<=
より小か等しい
文字 (CHAR) 型式では、より大きい は ASCII 照合順序において後 であることを意味
し、小文字は大文字の後になり、両者とも数値の後になります。「IBM Informix: SQL
ガイド: 構文」の ASCII 文字セット グラフを参照してください。日付 (DATE) 型およ
び日時 (DATETIME) 型式では、より大きい は時間的に後 であることを意味し、時間
隔 (INTERVAL) 型式では、期間が長い ことを意味します。
NULL 値をキーワード IS NULL または IS NOT NULL でテストする場合を除き、テ
キスト (TEXT) 型またはバイト (BYTE) 型列を使用して比較条件を作成することはでき
ません。
Dynamic Server
NULL 値をキーワード IS NULL または IS NOT NULL でテストする場合を除き、
BLOB 型または CLOB 型列を使用して Dynamic Server での比較条件を作成すること
はできません。
Dynamic Server の終り
前のページに示したキーワードや演算子を WHERE 節に使用すると、次のような動作を
する比較条件付き問合せを作成できます。
v 特定の値を検索する
v 特定の値を除外する
v 特定の範囲の値を検索する
v 一部の値を検索する
v NULL 値を識別する
以下に示す基準で変数テキストの検索を実行するには、WHERE 節に先行するキーワー
ドおよび演算子を使用して比較条件付きの問合せを作成します。
v 文字列を正確に比較する
第 2 章 SELECT 文の作成
39
v 単一文字ワイルドカードを使用する
v 値の範囲を制限する単一文字ワイルドカードを使用する
v 可変長ワイルドカードを使用する
v サブスクリプト付け
問合せの型それぞれの例を次に示します。
行のインクルード
図 46 で示されているように、関係演算子等号 (=) を使用して行を WHERE 節にインク
ルードします。
SELECT customer_num, call_code, call_dtime, res_dtime
FROM cust_calls
WHERE user_id = ’maryj’
図 46. 問合せ
図 46 は、図 47 に示す行のセットを戻します。
customer_num
106
121
127
call_code
call_dtime
res_dtime
D
O
I
1998-06-12 08:20 1998-06-12 08:25
1998-07-10 14:05 1998-07-10 14:06
1998-07-31 14:30
図 47. 問合せ結果
行の除外
関係演算子 != または <> を使用して行を WHERE 節から除外します。
図 48 では、問合せの対象が ANSI 標準準拠データベースであることを前提にしていま
す。文には、表 customer の所有者、すなわち、この表の作成者のログイン名が指定さ
れています。この修飾子 (所有者名) は、表の作成者が現行ユーザの場合や、データベ
ースが ANSI 標準準拠でない場合は必要ありません。ただし、いずれの場合でも修飾子
をインクルードすることはできます。所有者の命名に関する詳細は、「IBM Informix:
SQL ガイド: 構文」を参照してください。
40
IBM Informix SQL ガイド: チュートリアル
SELECT customer_num, company, city, state
FROM odin.customer
WHERE state != ’CA’
SELECT customer_num, company, city, state
FROM odin.customer
WHERE state <> ’CA’
図 48. 問合せ
図 49 で示されているように、図 48 の 2 つの SELECT 文では、ユーザ odin が所有す
る表 customer で、列 state 内の値と CA は等しくないという指定により値を除外して
います。
customer_num
119
120
121
122
123
124
125
126
127
128
company
The Triathletes Club
Century Pro Shop
City Sports
The Sporting Life
Bay Sports
Putnum’s Putters
Total Fitness Sports
Neelie’s Discount Sp
Big Blue Bike Shop
Phoenix College
city
Cherry Hill
Phoenix
Wilmington
Princeton
Jacksonville
Bartlesville
Brighton
Denver
Blue Island
Phoenix
state
NJ
AZ
DE
NJ
FL
OK
MA
CO
NY
AZ
図 49. 問合せ結果
行範囲の指定
図 50 に、WHERE 節で行範囲を指定する 2 つの方法を示します。
SELECT catalog_num, stock_num, manu_code, cat_advert
FROM catalog
WHERE catalog_num BETWEEN 10005 AND 10008
SELECT catalog_num, stock_num, manu_code, cat_advert
FROM catalog
WHERE catalog_num >= 10005 AND catalog_num <= 10008
図 50. 問合せ
第 2 章 SELECT 文の作成
41
図 50 の各文では、列 catalog_num の値の範囲を 10005 から 10008 までと指定してい
ます。最初の文ではキーワードを、2 番目の文では関係演算子をそれぞれ使用して、行
の抽出を行います。図 51 に結果を示します。
catalog_num 10005
stock_num
3
manu_code
HSK
cat_advert
High-Technology Design Expands the Sweet Spot
catalog_num 10006
stock_num
3
manu_code
SHM
cat_advert
Durable Aluminum for High School and Collegiate Athletes
catalog_num 10007
stock_num
4
manu_code
HSK
cat_advert
Quality Pigskin with Joe Namath Signature
catalog_num 10008
stock_num
4
manu_code
HRO
cat_advert
Highest Quality Football for High School
and Collegiate Competitions
図 51. 問合せ結果
表 catalog にはバイト (BYTE) 型の列が含まれていますが、この列を SELECT 文で指
定しても <BYTE value> と列名に表示されるだけなので、指定されていません。SQL
API アプリケーションを記述することで、テキスト (TEXT) 型およびバイト (BYTE)
型の値を表示できます。
特定範囲の行の除外
図 52 では、キーワード NOT BETWEEN を使用して、列 zipcode に 94000 から
94999 の文字範囲を持つ行を 図 53 のように除外します。
SELECT fname, lname, city, state
FROM customer
WHERE zipcode NOT BETWEEN ’94000’ AND ’94999’
ORDER BY state
図 52. 問合せ
42
IBM Informix SQL ガイド: チュートリアル
fname
lname
city
state
Frank
Fred
Eileen
Jason
Marvin
James
Bob
Cathy
Kim
Chris
Lessor
Jewell
Neelie
Wallack
Hanlon
Henry
Shorter
O’Brian
Satifer
Putnum
Phoenix
Phoenix
Denver
Wilmington
Jacksonville
Brighton
Cherry Hill
Princeton
Blue Island
Bartlesville
AZ
AZ
CO
DE
FL
MA
NJ
NJ
NY
OK
図 53. 問合せ結果
WHERE 節を使用した値のサブセットの検索
40 ページの『行の除外』と同様、図 54 では、ANSI 準拠のデータベースを使用するこ
とを想定しています。これらの例で所有者名を示す修飾子が引用符で囲まれているの
は、英大文字と英小文字を区別するためです。
SELECT lname, city, state, phone
FROM ’Aleta’.customer
WHERE state = ’AZ’ OR state = ’NJ’
ORDER BY lname
SELECT lname, city, state, phone
FROM ’Aleta’.customer
WHERE state IN (’AZ’, ’NJ’)
ORDER BY lname
図 54. 問合せ
図 54 の各文は、表 Aleta.customer の列 state に AZ または NJ のサブセットが含まれ
る行を抽出します。これを 図 55 に示します。
lname
city
state phone
Jewell
Lessor
O’Brian
Shorter
Phoenix
Phoenix
Princeton
Cherry Hill
AZ
AZ
NJ
NJ
602-265-8754
602-533-1817
609-342-0054
609-663-6079
図 55. 問合せ結果
第 2 章 SELECT 文の作成
43
キーワード IN を使用して、テキスト (TEXT) 型列またはバイト (BYTE) 型列をテスト
することはできません。
Dynamic Server
また、Dynamic Server を使用する場合は、キーワード IN を使用して BLOB 型または
CLOB 型列をテストできません。
Dynamic Server の終り
図 56 に ANSI 標準準拠データベースでの問合せ例を示しますが、ここでは表の所有者
名の前後に引用符がついていません。図 54 の 2 つの問合せは表 Aleta.customer を検
索しましたが、図 56 は表 ALETA.customer (別の表) を検索します。この 2 つは、
ANSI 準拠のデータベースが所有者名を検索する方法が異なります。
SELECT lname, city, state, phone
FROM Aleta.customer
WHERE state NOT IN (’AZ’, ’NJ’)
ORDER BY state
図 56. 問合せ
図 56 では、キーワード NOT IN を追加することにより、state 列のサブセット AZ お
よび NJ を除外するようにサブセットを変更します。図 57 に示す結果は、state 列の順
序になります。
44
IBM Informix SQL ガイド: チュートリアル
lname
city
state phone
Pauli
Sadler
Currie
Higgins
Vector
Watson
Ream
Quinn
Miller
Jaeger
Keyes
Lawson
Beatty
Albertson
Grant
Parmelee
Sipes
Baxter
Neelie
Wallack
Hanlon
Henry
Satifer
Putnum
Sunnyvale
San Francisco
Palo Alto
Redwood City
Los Altos
Mountain View
Palo Alto
Redwood City
Sunnyvale
Redwood City
Sunnyvale
Los Altos
Menlo Park
Redwood City
Menlo Park
Mountain View
Redwood City
Oakland
Denver
Wilmington
Jacksonville
Brighton
Blue Island
Bartlesville
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CO
DE
FL
MA
NY
OK
408-789-8075
415-822-1289
415-328-4543
415-368-1100
415-776-3249
415-389-8789
415-356-9876
415-544-8729
408-723-8789
415-743-3611
408-277-7245
415-887-7235
415-356-9982
415-886-6677
415-356-1123
415-534-8822
415-245-4578
415-655-0011
303-936-7731
302-366-7511
904-823-4239
617-232-4159
312-944-5691
918-355-2074
図 57. 問合せ結果
NULL 値の識別
IS NULL または IS NOT NULL オプションを使用して、NULL 値をチェックします。
NULL 値とはデータが存在していない状態か、または未知の値のいずれかを指します。
また、NULL 値はゼロや空白とは異なります。
図 58 は、NULL paid_date を持つ行をすべて戻します。結果は、図 59 に示します。
SELECT order_num, customer_num, po_num, ship_date
FROM orders
WHERE paid_date IS NULL
ORDER BY customer_num
図 58. 問合せ
第 2 章 SELECT 文の作成
45
order_num
customer_num
1004
1006
1007
1012
1016
1017
106
112
117
117
119
120
po_num
ship_date
8006
Q13557
278693
278701
PC6782
DM354331
05/30/1998
06/05/1998
06/29/1998
07/12/1998
07/13/1998
図 59. 問合せ結果
複合条件の作成
論理演算子 AND、OR、および NOT を使用して、複数の比較条件またはブール
(BOOLEAN) 式を結合することができます。ブール (BOOLEAN) 式は、TRUE または
FALSE を評価します。また、NULL 値が含まれている場合は、unknown として評価しま
す。
図 60 では、演算子 AND は、WHERE 節の 2 つの比較式を結合します。
SELECT order_num, customer_num, po_num, ship_date
FROM orders
WHERE paid_date IS NULL
AND ship_date IS NOT NULL
ORDER BY customer_num
図 60. 問合せ
この問合せは、図 61 に示すように、NULL paid_date または NOT NULL ship_date を
含むすべての行を戻します。
order_num customer_num po_num
1004
1007
1012
1017
106
117
117
120
8006
278693
278701
DM354331
図 61. 問合せ結果
46
IBM Informix SQL ガイド: チュートリアル
ship_date
05/30/1998
06/05/1998
06/29/1998
07/13/1998
正確なテキスト比較の使用
以下の例の WHERE 節では、キーワード LIKE、キーワード MATCHES、または等号
(=) 関係演算子を使用して、正確なテキスト比較を検索します。これまでの例と異な
り、ここでは現行データベースにない表に対して問合せを行います。現行データベース
にない表にアクセスできるのは、アクセス対象となるデータベースと現行データベース
の ANSI 標準準拠の状態が同じである場合のみです。現行データベースが ANSI 標準
準拠データベースの場合は、アクセス対象となる表は ANSI 標準準拠データベースに存
在している必要があります。現行データベースが ANSI 標準非準拠データベースの場合
は、アクセス対象となる表は ANSI 標準非準拠データベースに存在している必要があり
ます。
この章でこれまで使用してきたデータベースは、デモンストレーション データベースで
すが、次の例の FROM 節で指定している所有者 bubba 作成の表 manatee は、syzygy
という名前の ANSI 標準準拠のデータベース内にあります。現行データベースにない表
にアクセスする方法については、「IBM Informix: SQL ガイド: 構文」を参照してくだ
さい。
図 62 のすべての文は、図 63 に示すように、列 description に helmet という単一文字
が含まれるすべての行を抽出します。
SELECT stock_no, mfg_code, description, unit_price
FROM syzygy:bubba.manatee
WHERE description = ’helmet’
ORDER BY mfg_code
SELECT stock_no, mfg_code, description, unit_price
FROM syzygy:bubba.manatee
WHERE description LIKE ’helmet’
ORDER BY mfg_code
SELECT stock_no, mfg_code, description, unit_price
FROM syzygy:bubba.manatee
WHERE description MATCHES ’helmet’
ORDER BY mfg_code
図 62. 問合せ
結果は 図 63 のようになります。
第 2 章 SELECT 文の作成
47
stock_no mfg_code
991
991
991
991
991
ABC
BKE
HSK
PRC
SPR
description
unit_price
helmet
helmet
helmet
helmet
helmet
$222.00
$269.00
$311.00
$234.00
$245.00
図 63. 問合せ結果
変数テキスト検索の使用
フィールドのサブ文字列検索に基づく変数テキスト 問合せに、キーワード LIKE およ
び MATCHES を使用することができます。反対の条件を指定するには、キーワード
NOT をインクルードします。キーワード LIKE は ANSI 標準ですが、MATCHES は
Informix の拡張です。
変数テキスト検索文字列には、LIKE または MATCHES とともに、次の表に示すワイル
ドカードを含めることができます。
キーワード
記号
意味
LIKE
%
ゼロまたは 1 文字以上と評価する
LIKE
_
1 文字と評価する
LIKE
¥
次の 1 文字を一般文字として扱う
MATCHES
*
ゼロまたは 1 文字以上と評価する
MATCHES
?
1 文字と評価する (NULL を除く)
MATCHES
[ ]
1 文字または値の範囲と評価する
MATCHES
¥
次の 1 文字を一般文字として扱う
LIKE またはキーワード MATCHES を使用して、テキスト (TEXT) 型列またはバイト
(BYTE) 型列をテストすることはできません。
また、Dynamic Server を使用する場合は、LIKE またはキーワード MATCHES を使用
して BLOB 型または CLOB 型列をテストできません。
単一文字ワイルドカードの使用
図 64 の文は、WHERE 節での単一文字ワイルドカードの使用方法を示します。また、
現行のデータベースに含まれない表への問合せも行っています。表 stock は、外部のデ
ータベース sloth 内にあります。現行のデモンストレーション データベースの外部にな
い場合、sloth は meerkat というデータベース サーバ上にあります。
48
IBM Informix SQL ガイド: チュートリアル
詳しくは、 231 ページの『第 7 章 外部データベースのデータへのアクセスおよび修
正』 および「IBM Informix: SQL ガイド: 構文」を参照してください。
SELECT stock_num, manu_code, description, unit_price
FROM sloth@meerkat:stock
WHERE manu_code LIKE ’_R_’
AND unit_price >= 100
ORDER BY description, unit_price
SELECT stock_num, manu_code, description, unit_price
FROM sloth@meerkat:stock
WHERE manu_code MATCHES ’?R?’
AND unit_price >= 100
ORDER BY description, unit_price
図 64. 問合せ
図 64 の各文は、図 65 に示すように、manu_code の中央の文字が R である行のみを抽
出します。比較 ’_R_’ (LIKE) または ’?R?’ (MATCHES) は、次の項目を左から右へ指
定します。
v 任意の単一文字
v 文字 R
v 任意の単一文字
stock_num manu_code description
205
2
1
7
102
114
4
110
110
307
306
308
304
HRO
HRO
HRO
HRO
PRC
PRC
HRO
PRC
HRO
PRC
PRC
PRC
HRO
3 golf balls
baseball
baseball gloves
basketball
bicycle brakes
bicycle gloves
football
helmet
helmet
infant jogger
tandem adapter
twin jogger
watch
unit_price
$312.00
$126.00
$250.00
$600.00
$480.00
$120.00
$480.00
$236.00
$260.00
$250.00
$160.00
$280.00
$280.00
図 65. 問合せ結果
初めの文字の範囲を指定する WHERE 節: 図 66 は、manu_code が A から H で
始まる行のみを選択し、図 67 に示す行のみを戻します。テスト ’[A-H]’ は、A から H
第 2 章 SELECT 文の作成
49
の任意の単一文字を指定します。キーワード LIKE と同等なワイルドカード記号はあり
ません。
SELECT stock_num, manu_code, description, unit_price
FROM stock
WHERE manu_code MATCHES ’[A-H]*’
ORDER BY description, manu_code
図 66. 問合せ
stock_num manu_code description
unit_price
205
205
2
3
1
1
7
ANZ
HRO
HRO
HSK
HRO
HSK
HRO
3 golf balls
3 golf balls
baseball
baseball bat
baseball gloves
baseball gloves
basketball
$312.00
$312.00
$126.00
$240.00
$250.00
$800.00
$600.00
313
6
5
8
9
304
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
swim cap
tennis ball
tennis racquet
volleyball
volleyball net
watch
$60.00
$48.00
$19.80
$840.00
$20.00
$170.00
..
.
図 67. 問合せ結果
可変長ワイルドカードを使用する WHERE 節: 図 68 の SELECT 文は、文字列
の末尾にワイルドカードを使用して、列 description の値が bicycle で始まるすべての
行を抽出します。
SELECT stock_num, manu_code, description, unit_price
FROM stock
WHERE description LIKE ’bicycle%’
ORDER BY description, manu_code
SELECT stock_num, manu_code, description, unit_price
FROM stock
WHERE description MATCHES ’bicycle*’
ORDER BY description, manu_code
図 68. 問合せ
50
IBM Informix SQL ガイド: チュートリアル
いずれの文も、図 69 に示す行を戻します。
stock_num manu_code description
102
102
114
107
106
101
101
105
105
PRC
SHM
PRC
PRC
PRC
PRC
SHM
PRC
SHM
bicycle
bicycle
bicycle
bicycle
bicycle
bicycle
bicycle
bicycle
bicycle
brakes
brakes
gloves
saddle
stem
tires
tires
wheels
wheels
unit_price
$480.00
$220.00
$120.00
$70.00
$23.00
$88.00
$68.00
$53.00
$80.00
図 69. 問合せ結果
比較 ’bicycle%’ または ’bicycle*’ は、文字 bicycle の後に 0 個以上の文字の任意の
シーケンスが続く文字を指定します。これらは bicycle stem と一致し、stem がワイル
ドカードと対応しています。列 description にこれに該当する値があれば、bicycle 単独
の場合も一致します。
図 70 は、PRC の manu_code を除外するもう 1 つの比較条件を追加することによっ
て、さらに検索を絞り込みます。
SELECT stock_num, manu_code, description, unit_price
FROM stock
WHERE description LIKE ’bicycle%’
AND manu_code NOT LIKE ’PRC’
ORDER BY description, manu_code
図 70. 問合せ
この文は、図 71 に示す行のみを抽出します。
stock_num manu_code description
102 SHM
101 SHM
105 SHM
bicycle brakes
bicycle tires
bicycle wheels
unit_price
$220.00
$68.00
$80.00
図 71. 問合せ結果
%cycle’ のように比較条件の先頭にワイルドカードを使用して大規模な表に対する問合
せを行うと、実行にかなりの時間を要する場合がよくあります。インデックスを使用す
ることができないため、すべての行が検索されます。
第 2 章 SELECT 文の作成
51
MATCHES と非デフォルト ロケール
Informix データベース サーバでは、デフォルトで、データベースのデータに対して米国
英語 (U.S. English) 言語環境が使用されます。このデフォルト ロケールは、ISO 8859-1
コード セットを使用します。米国英語 (U.S. English) ロケールは、MATCHES がコー
ド セットの順序を使用することを指定します。
データベースがデフォルトでないロケールを使用する場合、範囲を指定する MATCHES
節は、文字 (CHARACTER) 型 (文字 (CHAR) 型、各国語文字 (NCHAR) 型、可変長文
字 (VARCHAR) 型、各国語可変長文字 (NVARCHAR) 型、およびラージ可変長文字
(LVARCHAR) 型を含む) にそのロケールの照合順序を使用します。MATCHES の範囲
におけるこの機能は、一般ルールに対する例外であり、各国語文字 (NCHAR) 型および
各国語可変長文字 (NVARCHAR) 型列のみがロケールに固有な照合を使用できます。た
だし、ロケールが特定の照合順序を指定しない場合、MATCHES はコード セットの順
序を使用します。
Dynamic Server
SET COLLATION 文を使用して、セッション用に DB_LOCALE の設定とは異なるデー
タベース ロケールを指定できます。SET COLLATION の説明については、
「IBM Informix: SQL ガイド: 構文」を参照してください。
Dynamic Server の終り
SELECT numéro,nom,prénom
FROM abonnés
WHERE nom MATCHES ’[E-P]*’
ORDER BY nom
図 72. 問合せ
図 73 では、Étaix、Ötker、および Øverst の行が選択およびリストされていません。こ
れは、ISO 8859-1 コード セット順序では、名前の最初のアクセントの付いた文字は、
列 nom の MATCHES の範囲 E から P に含まれていないためです。
52
IBM Informix SQL ガイド: チュートリアル
numéro
nom
13607
13602
13604
13610
13613
13603
13611
Hammer
Hämmer
LaForêt
LeMaître
Llanero
Montaña
Oatfield
prénom
Gerhard
Greta
Jean-Noël
Héloïse
Gloria Dolores
José Antonio
Emily
図 73. 問合せ結果
英語以外のデータおよびロケールに関する詳細は、「IBM Informix: GLS ユーザーズ ガ
イド」を参照してください。
特殊文字のプロテクト
図 74 では、キーワード ESCAPE を、LIKE またはキーワード MATCHES とともに使
用しています。これにより、特殊文字がワイルドカード記号として誤って解釈されるの
を防ぐことができます。
SELECT * FROM cust_calls
WHERE res_descr LIKE ’%!%%’ ESCAPE ’!’
図 74. 問合せ
キーワード ESCAPE は、エスケープ文字 (この例では、!) を指定し、ワイルドカード
ではなくデータとして解釈されるようにように、後続の 1 文字をプロテクトします。こ
の例では、エスケープ文字を指定すると、中央のパーセント記号 (%) がデータとして処
理されます。キーワード ESCAPE を使用すると、ワイルドカード LIKE のパーセント
記号 (%) で、列 res_descr 内のパーセント記号 (%) のオカレンスを検索することがで
きます。この問合せは、図 75 に示す行を抽出します。
第 2 章 SELECT 文の作成
53
customer_num
call_dtime
user_id
call_code
call_descr
res_dtime
res_descr
116
1997-12-21 11:24
mannyn
I
Second complaint from this customer!
Received two cases righthanded outfielder
glove (1 HRO) instead of one case lefties.
1997-12-27 08:19
Memo to shipping (Ava Brown) to send case
of lefthanded gloves, pick up wrong case;
memo to billing requesting 5% discount to
placate customer due to second offense
and lateness of resolution because of
holiday.
図 75. 問合せ結果
WHERE 節でのサブスクリプトの使用方法
SELECT 文の WHERE 節でサブスクリプト付け をすることにより、列の文字または数
値の範囲を指定することができます。図 76 に例を示します。
SELECT catalog_num, stock_num, manu_code, cat_advert,
cat_descr
FROM catalog
WHERE cat_advert[1,4] = ’High’
図 76. 問合せ
サブスクリプト [1,4] により、図 76 は、列 cat_advert の最初の 4 文字が High であ
るすべての行を抽出します。この結果を図 77 に示します。
54
IBM Informix SQL ガイド: チュートリアル
catalog_num 10004
stock_num
2
manu_code
HRO
cat_advert
Highest Quality Ball Available, from Hand-Sti
tching to the Robinson Signature
cat_descr
Jackie Robinson signature ball. Highest professional quality,
used by National League.
catalog_num 10005
stock_num
3
manu_code
HSK
cat_advert
High-Technology Design Expands the Sweet Spot
cat_descr
Pro-style
wood. Available in sizes: 31, 32, 33, 34, 35.
..
.
catalog_num 10045
stock_num
204
manu_code
KAR
cat_advert
High-Quality Beginning Set of Irons. Appropriate
for High School Competitions
cat_descr
Ideally balanced for optimum control. Nylon covered shaft.
catalog_num 10068
stock_num
310
manu_code
ANZ
cat_advert
High-Quality Kickboard
cat_descr
White. Standard size.
図 77. 問合せ結果
特定の行を選択するためのFIRST節の使用
SELECT 文に FIRST 節をインクルードし、SELECT 文の条件に一致する最初の行を、
指定された数だけ戻すようにすることができます。キーワード FIRST のすぐ後に数値
を入れて、問合せで戻す行の最大数を指定します。FIRST 節を含む SELECT 文が実行
されたときにデータベース サーバが戻す行は、その SELECT 文に ORDER BY 節も含
まれるかどうかにより異なります。
SELECT 文が副問合せまたはビュー定義の一部である場合は、FIRST 節を使用できませ
ん。
FIRST 節の使用に関する制約事項については、「IBM Informix: SQL ガイド: 構文」の
SELECT 文の説明を参照してください。
第 2 章 SELECT 文の作成
55
ORDER BY 節を使用しない FIRST 節
FIRST 節を含む SELECT 文で ORDER BY 節を使用しない場合、SELECT 文の条件と
一致するすべての行が戻される可能性があります。言い替えると、適合する行のどれを
戻すかをデータベース サーバが決定するため、問合せ結果はオプティマイザが選択する
問合せ予定により異なります。
図 78 では、FIRST 節を使用して、表 state の最初の 5 行を戻します。
SELECT FIRST 5 * FROM state
図 78. 問合せ
code sname
AK
HI
CA
OR
WA
Alaska
Hawaii
California
Oregon
Washington
図 79. 問合せ結果
また、FIRST 節を使用して、表内のすべての列名とデータ型を判別できるほか、多くの
行を戻す可能性のある問合せをテストできます。図 80 では、表の最初の行の列の値
を、FIRST 節を使用して戻します。
SELECT FIRST 1 * FROM orders
図 80. 問合せ
56
IBM Informix SQL ガイド: チュートリアル
order_num
order_date
customer_num
ship_instruct
backlog
po_num
ship_date
ship_weight
ship_charge
paid_date
1001
05/20/1998
104
express
n
B77836
06/01/1998
20.40
$10.00
07/22/1998
図 81. 問合せ結果
ORDER BY 節を使用する FIRST 節
ORDER BY 節を FIRST 節とともに SELECT 文で使用し、特定の列の最大値および最
小値を含む行を戻すことができます。図 82 では、ORDER BY 節を使用して (アルファ
ベット順で) 表 state の最初の 5 つの州を戻します。図 82 は、ORDER BY 節を使用
している点以外は図 78 と同じですが、図 78 とは異なる結果を戻します。
SELECT FIRST 5 * FROM state ORDER BY sname
図 82. 問合せ
code sname
AL
AK
AZ
AR
CA
Alabama
Alaska
Arizona
Arkansas
California
図 83. 問合せ結果
図 84 では、ORDER BY とともに FIRST 節を使用し、表 stock の最も高価な商品を
10 個戻します。
SELECT FIRST 10 description, unit_price
FROM stock ORDER BY unit_price DESC
図 84. 問合せ
第 2 章 SELECT 文の作成
57
description
football
volleyball
baseball gloves
18-spd, assmbld
irons/wedge
basketball
12-spd, assmbld
10-spd, assmbld
football
bicycle brakes
unit_price
$960.00
$840.00
$800.00
$685.90
$670.00
$600.00
$549.00
$499.99
$480.00
$480.00
図 85. 問合せ結果
式と導出値
SELECT 文の SELECT 節には、列名以外の要素も指定できます。SELECT 文の
Projection 節に式 をリストして列データの計算を行い、1 つ以上の列の内容から導出
した情報を表示できます。
式の基本構成要素は、列名、定数、引用符付き文字列、キーワードです。これらを演算
子で自由に組み合わせて式を構成します。また、SELECT 文をプログラムに埋め込む
と、式にホスト変数 (プログラム データ) を含めることができます。
算術式
算術式には、58 にリストされている算術演算子 が 1 つ以上含まれ、計算結果の数値が
戻されます。
演算子
演算
+
加算
-
減算
*
乗算
/
除算
テキスト (TEXT) 型またはバイト (BYTE) 型列を算術式に使用することはできません。
Dynamic Server では、算術式に BLOB 型または CLOB 型を指定できません。
算術演算子は、データベース内のデータを実際に変更することなく、指定した計算の結
果を確認することができます。後で参照、計算、または即時レポートの作成を行うため
に、変更したデータを一時表に保存するには、INTO TEMP 節を追加します。図 86
58
IBM Informix SQL ガイド: チュートリアル
は、unit_price が $400 以上の場合、列 unit_price に関して 7% の消費税を計算しま
す (ただし、データベース内のデータは更新されません)。
SELECT stock_num, description, unit_price, unit_price * 1.07
FROM stock
WHERE unit_price >= 400
図 86. 問合せ
この結果は、図 87 に示すように、列 expression に表示されます。
stock_num description
1
1
4
4
7
8
102
111
112
113
203
baseball gloves
baseball gloves
football
football
basketball
volleyball
bicycle brakes
10-spd, assmbld
12-spd, assmbld
18-spd, assmbld
irons/wedge
unit_price
(expression)
$800.00
$450.00
$960.00
$480.00
$600.00
$840.00
$480.00
$499.99
$549.00
$685.90
$670.00
$856.00
$481.50
$1027.20
$513.60
$642.00
$898.80
$513.60
$534.99
$587.43
$733.91
$716.90
図 87. 問合せ結果
図 88 では、注文量が 5 より少ない場合、$6.50 の追加料金を計算します。
SELECT item_num, order_num, quantity,
total_price, total_price + 6.50
FROM items
WHERE quantity < 5
図 88. 問合せ
この結果は、図 89 に示すように、列 expression に表示されます。
第 2 章 SELECT 文の作成
59
item_num
..
.
order_num quantity total_price
(expression)
1
1
2
1
2
1
2
3
4
1001
1002
1002
1003
1003
1004
1004
1004
1004
1
1
1
1
1
1
1
1
1
$250.00
$960.00
$240.00
$20.00
$840.00
$250.00
$126.00
$240.00
$800.00
$256.50
$966.50
$246.50
$26.50
$846.50
$256.50
$132.50
$246.50
$806.50
1
2
3
4
5
6
1023
1023
1023
1023
1023
1023
2
2
1
1
1
1
$40.00
$116.00
$80.00
$228.00
$170.00
$190.00
$46.50
$122.50
$86.50
$234.50
$176.50
$196.50
図 89. 問合せ結果
図 90 は、顧客注文を受けてから (call_dtime) 納入するまでの (res_dtime) 間隔を、
日、時間、および分で計算し、列 expression に表示します。
SELECT customer_num, call_code, call_dtime,
res_dtime - call_dtime
FROM cust_calls
ORDER BY customer_num
図 90. 問合せ
customer_num call_code call_dtime
106
110
116
116
119
121
127
D
L
I
I
B
O
I
1998-06-12
1998-07-07
1997-11-28
1997-12-21
1998-07-01
1998-07-10
1998-07-31
(expression)
08:20
10:24
13:34
11:24
15:00
14:05
14:30
0
0
0
5
0
0
00:05
00:06
03:13
20:55
17:21
00:01
図 91. 問合せ結果
表示ラベルの使用: 表示ラベル を計算済みデータまたは導出データの列に設定し
て、デフォルトの列見出し expression と置き換えることができます。図 86、図 88、お
60
IBM Informix SQL ガイド: チュートリアル
よび図 92 では、導出データが列 expression に表示されます。図 92 で導出値が表示さ
れる列には、taxed という記述ヘッダが付けられます。
SELECT stock_num, description, unit_price,
unit_price * 1.07 taxed
FROM stock
WHERE unit_price >= 400
図 92. 問合せ
図 93 ではラベル taxed が、演算 unit_price * 1.07 の結果を表示する射影リストの
式に割り当てられています。
stock_num description
1
1
4
4
7
8
102
111
112
113
203
baseball gloves
baseball gloves
football
football
basketball
volleyball
bicycle brakes
10-spd, assmbld
12-spd, assmbld
18-spd, assmbld
irons/wedge
unit_price
taxed
$800.00
$450.00
$960.00
$480.00
$600.00
$840.00
$480.00
$499.99
$549.00
$685.90
$670.00
$856.00
$481.50
$1027.20
$513.60
$642.00
$898.80
$513.60
$534.99
$587.43
$733.91
$716.90
図 93. 問合せ結果
図 94 では、ラベル surcharge を、演算 total_price + 6.50 の結果を表示する列に定
義します。
SELECT item_num, order_num, quantity,
total_price, total_price + 6.50 surcharge
FROM items
WHERE quantity < 5
図 94. 問合せ
図 95 で示されているように、出力では、列に surcharge というラベルが割り当てられ
ます。
第 2 章 SELECT 文の作成
61
item_num
..
.
order_num quantity total_price
surcharge
1
1
2
1
2
1001
1002
1002
1003
1003
1
1
1
1
1
$250.00
$960.00
$240.00
$20.00
$840.00
$256.50
$966.50
$246.50
$26.50
$846.50
1
2
3
4
5
6
1023
1023
1023
1023
1023
1023
2
2
1
1
1
1
$40.00
$116.00
$80.00
$228.00
$170.00
$190.00
$46.50
$122.50
$86.50
$234.50
$176.50
$196.50
図 95. 問合せ結果
図 96 では、日時 (DATETIME) 型列 call_dtime を日時 (DATETIME) 型列 res_dtime
から減算した結果を表示する列に、ラベル span を割り当てます。
SELECT customer_num, call_code, call_dtime,
res_dtime - call_dtime span
FROM cust_calls
ORDER BY customer_num
図 96. 問合せ
図 97 で示されているように、出力では、列に span というラベルが付きます。
customer_num call_code call_dtime
106
110
116
116
119
121
127
D
L
I
I
B
O
I
1998-06-12
1998-07-07
1997-11-28
1997-12-21
1998-07-01
1998-07-10
1998-07-31
図 97. 問合せ結果
62
IBM Informix SQL ガイド: チュートリアル
span
08:20
10:24
13:34
11:24
15:00
14:05
14:30
0
0
0
5
0
0
00:05
00:06
03:13
20:55
17:21
00:01
CASE 式
CASE 式は、プログラム言語の CASE 文の概念に似た条件式です。データの表示方法
を変える場合に、CASE 式を使用します。CASE 式により、いくつかの条件テストのど
れが TRUE と評価されるかによって、文はいくつかの可能な結果の 1 つを戻すことが
できます。
CASE 式には、テキスト (TEXT) 型またはバイト (BYTE) 型の値を使用できません。
既婚/独身を表す列は数字 1、2、3、および 4 で表示され、それぞれ未婚、既婚、離
別、死別を示します。データベースに効率的に格納するためには短い値 (1,2,3,4) が適
していても、人事部のスタッフにとっては、詳しい値 (未婚、既婚、離別、死別) のほ
うが便利なことがあります。このような場合、CASE 式を使用して、異なる値のセット
を簡単に変換できます。
Dynamic Server
また、CASE 式は、拡張データ型やキャスト式をサポートします。
Dynamic Server の終り
次の例は、複数の WHEN 節を使用する CASE 式です。この式は、表 stock の列
manu_code について、より詳しい値を戻します。WHEN 条件がいずれも偽の場合、
NULL が結果のデフォルトになります (ELSE NULL 節は省略できます)。
SELECT
CASE
WHEN
WHEN
WHEN
WHEN
ELSE
END
FROM stock
manu_code
manu_code
manu_code
manu_code
NULL
=
=
=
=
"HRO"
"SHM"
"PRC"
"ANZ"
THEN
THEN
THEN
THEN
"Hero"
"Shimara"
"ProCycle"
"Anza"
CASE 式には、必ず 1 つ以上の WHEN 節をインクルードします。後続の WHEN 節お
よび ELSE 節はオプションです。WHEN 条件が TRUE と評価されない限り、結果の値
は NULL です。NULL の結果は、IS NULL 式を使用して処理できます。NULL 値の処
理の詳細については、「IBM Informix: SQL ガイド: 構文」を参照してください。
図 98 は、表 orders の中でまだ顧客に出荷されていない注文がある場合に、フラグを立
てる文字列値を戻す単純な CASE 式です。
第 2 章 SELECT 文の作成
63
SELECT order_num, order_date,
CASE
WHEN ship_date IS NULL
THEN "order not shipped"
END
FROM orders
図 98. 問合せ
order_num order_date (expression)
1001
1002
1003
1004
1005
1006
1007
05/20/1998
05/21/1998
05/22/1998
05/22/1998
05/24/1998
05/30/1998 order not shipped
05/31/1998
1019
1020
1021
1022
1023
07/11/1998
07/11/1998
07/23/1998
07/24/1998
07/24/1998
..
.
図 99. 問合せ結果
CASE 式を使用して列を更新する方法については、205 ページの『CASE 式による列の
更新』を参照してください。
導出列のソート
図 100 と図 102 で示されているように、式として ORDER BY 節を使用すると、式に
設定した表示ラベルまたは整数を使用することができます。
SELECT customer_num, call_code, call_dtime,
res_dtime - call_dtime span
FROM cust_calls
ORDER BY span
図 100. 問合せ
図 100 は、表 cust_calls から、図 96 と同じデータを抽出します。図 100 では、
ORDER BY 節により、span 列の導出値の昇順にデータが表示されます。
64
IBM Informix SQL ガイド: チュートリアル
customer_num call_code call_dtime
127
121
106
110
116
119
116
I
O
D
L
I
B
I
1998-07-31
1998-07-10
1998-06-12
1998-07-07
1997-11-28
1998-07-01
1997-12-21
span
14:30
14:05
08:20
10:24
13:34
15:00
11:24
0
0
0
0
0
5
00:01
00:05
00:06
03:13
17:21
20:55
図 101. 問合せ結果
図 102 は、整数を使用して演算 res_dtime - call_dtime の結果を表示し、図 101 に表
示されるのと同じ行を抽出します。
SELECT customer_num, call_code, call_dtime,
res_dtime - call_dtime span
FROM cust_calls
ORDER BY 4
図 102. 問合せ
SELECT 文での行 ID 値の使用
データベース サーバは、固有行 ID 番号をフラグメント化されていない表に割り当てま
す。rowid は、実際はどの表にも存在する隠れた列です。rowid の連続値には特に意味
はなく、チャンク内の物理データの格納場所によって異なる場合があります。行 ID を
使用して、表の行に関連付けられた内部レコード番号を検索することができます。フラ
グメント表の行に自動的に列 rowid が含まれることはありません。
アプリケーションでのアクセス方法には、行 ID ではなく主キーを使用することをお勧
めします。主キーは ANSI の SQL 仕様で定義されているため、これをデータへのアク
セスに使用することで、アプリケーションの移植性を高めることができます。また、デ
ータベース サーバでは、主キーを使用してフラグメント表内のデータにアクセスした方
が、行 ID 番号を使用して同一データにアクセスするよりも、所要時間が短くて済みま
す。
行 ID の詳細については、「IBM Informix: データベース設計および実装 ガイド」およ
び「IBM Informix: Dynamic Server 管理者ガイド」を参照してください。
図 103 では、Projection 節で行 ID とワイルドカードのアスタリスク記号 (*) を使用し
て、表 manufact の各行をその行 ID とともに抽出します。
第 2 章 SELECT 文の作成
65
SELECT rowid, * FROM manufact
図 103. 問合せ
rowid manu_code manu_name
257
258
259
260
261
262
263
264
265
SMT
ANZ
NRG
HSK
HRO
SHM
KAR
NKL
PRC
Smith
Anza
Norge
Husky
Hero
Shimara
Karsten
Nikolus
ProCycle
lead_time
3
5
7
5
4
30
21
8
9
図 104. 問合せ結果
絶対に行 ID を永続 表に格納したり、外部キーとして使用したりしないでください。表
を削除してから外部データから再ロードすると、行 ID の値はすべて変更されます。
複数表の SELECT 文
FROM 節に表名を指定して、複数の表からデータを選択することができます。各表 の
1 つ以上の関連する列間の結合 条件を作成するには、WHERE 節を追加します。この
WHERE 節は一時複合表を作成します。結合条件を満たす行のペアはすべてリンクさ
れ、単一行を形成しています。
単純結合 では、各表内の 1 つの列の関係に基づいて複数表の情報を結合します。複合
結合 は、各表内の複数列の関係に基づいた複数表の結合です。
結合を作成するには、各表の少なくとも 1 つの列の間で、結合条件 と呼ばれる関係を
指定する必要があります。列は比較の対象となるため、互換データ型を含んでいなけれ
ばなりません。大きな表を結合する場合は、結合条件で列にインデックスを付けると効
率的です。
データ型については、「IBM Informix: SQL ガイド: 参照」および「IBM Informix: デー
タベース設計および実装 ガイド」に記載されています。インデックス機能の詳細につい
ては、「IBM Informix: Dynamic Server 管理者ガイド」を参照してください。
66
IBM Informix SQL ガイド: チュートリアル
デカルト積の作成
表の結合条件が明示的に示されていない複数表の問合せを実行する場合は、デカルト積
を作成します。デカルト積は、表におけるすべての行の組合せからなります。デカルト
積の結果は通常、非常に大きくなります。
図 105 では、2 つの表から選択してデカルト積を作成します。
SELECT * FROM customer, state
図 105. 問合せ
表 state には 52 行、表 customer には 28 行しかありませんが、図 105 を行うと、一
方の表の行数と他方の表の行数の乗算が行われ、図 106 のように実用性のない 1,456 行
が抽出されます。
第 2 章 SELECT 文の作成
67
customer_num
fname
lname
company
address1
address2
city
state
zipcode
phone
code
sname
101
Ludwig
Pauli
All Sports Supplies
213 Erstwild Court
customer_num
fname
lname
company
address1
address2
city
state
zipcode
phone
code
sname
101
Ludwig
Pauli
All Sports Supplies
213 Erstwild Court
customer_num
fname
lname
company
address1
address2
city
state
zipcode
phone
code
sname
..
.
101
Ludwig
Pauli
All Sports Supplies
213 Erstwild Court
Sunnyvale
CA
94086
408-789-8075
AK
Alaska
Sunnyvale
CA
94086
408-789-8075
HI
Hawaii
Sunnyvale
CA
94086
408-789-8075
CA
California
図 106. 問合せ結果
加えて、連結された行に表示されるデータの一部は、矛盾しています。例えば、表
customer の city と state はカリフォルニア州のアドレスを示しますが、表 state の
code と sname は他の州のものである場合があります。
結合の作成
理論的には、結合の最初の段階でデカルト積を作成します。このデカルト積を詳細化ま
たは制限し、意味のない行データの組合せを除去するには、有効な結合条件を指定した
WHERE 節を SELECT 文に含めます。
68
IBM Informix SQL ガイド: チュートリアル
このセクションでは、交差結合、等価結合、自然結合、および複数表結合 について説明
します。セルフ結合 や外部結合 などの複雑な結合については、第 5 章に記載されてい
ます。
交差結合 (IDS)
交差結合では、選択されたすべての表のすべての行を結合し、デカルト積を作成しま
す。交差結合の結果は非常に大きくなり、管理が困難になる場合があります。
図 107 では、ANSI 結合構文を使用して、交差結合を作成します。
SELECT * FROM customer CROSS JOIN
state
図 107. 問合せ
図 107 の結果は、図 105 の結果と同じになります。また、WHERE 節を指定すること
で、交差結合をフィルターに掛けることも可能です。
デカルト積の詳細については、67 ページの『デカルト積の作成』を参照してください。
ANSI 構文の詳細については、150 ページの『ANSI 結合構文』を参照してください。
等価結合
等価結合は、等価関係 (列の値が一致しているかどうか) に基づく結合です。この等価
性は、図 108 に示すように、WHERE 節に比較演算の等号 (=) で示されます。
SELECT * FROM manufact, stock
WHERE manufact.manu_code = stock.manu_code
図 108. 問合せ
図 108 では、表 manufact と表 stock を列 manu_code に基づいて結合します。この問
合せでは、図 109 で示されているように、2 つの列の値が等しい場合、それらの行のみ
を抽出します。
第 2 章 SELECT 文の作成
69
manu_code
manu_name
lead_time
stock_num
manu_code
description
unit_price
unit
unit_descr
SMT
Smith
3
1
SMT
baseball gloves
$450.00
case
10 gloves/case
manu_code
manu_name
lead_time
stock_num
manu_code
description
unit_price
unit
unit_descr
SMT
Smith
3
5
SMT
tennis racquet
$25.00
each
each
manu_code
manu_name
lead_time
stock_num
manu_code
description
unit_price
unit
unit_descr
SMT
Smith
3
6
SMT
tennis ball
$36.00
case
24 cans/case
manu_code
manu_name
lead_time
stock_num
manu_code
description
unit_price
unit
unit_descr
..
.
ANZ
Anza
5
5
ANZ
tennis racquet
$19.80
each
each
図 109. 問合せ結果
この等結合では、選択対象リストですべての列が要求されたため、図 109 には、表
manufact と stock の両方の列 manu_code が含まれています。
追加の制約がある等価結合として、結合された列の値の等価性に基づく比較条件をもつ
等価結合を作成することもできます。このような結合の場合、WHERE 節に指定される
比較条件には、等号 (=) のほかに関係演算子が使用されます。
70
IBM Informix SQL ガイド: チュートリアル
結合する表の列が同じ名前を持つ場合、図 110 に示すように、列名の前に各表の名前と
ピリオド (.) を付加する必要があります。
SELECT order_num, order_date, ship_date, cust_calls.*
FROM orders, cust_calls
WHERE call_dtime >= ship_date
AND cust_calls.customer_num = orders.customer_num
ORDER BY orders.customer_num
図 110. 問合せ
図 110 は、列 customer_num を結合し、表 cust_calls の call_dtime が表 orders の
ship_date 以上である行のみを選択します。図 111 に、結合されて戻される行を示しま
す。
第 2 章 SELECT 文の作成
71
order_num
order_date
ship_date
customer_num
call_dtime
user_id
call_code
call_descr
res_dtime
res_descr
1004
05/22/1998
05/30/1998
106
1998-06-12 08:20
maryj
D
Order received okay, but two of the cans of
ANZ tennis balls within the case were empty
1998-06-12 08:25
Authorized credit for two cans to customer,
issued apology. Called ANZ buyer to report
the qa problem.
order_num
order_date
ship_date
customer_num
call_dtime
user_id
call_code
call_descr
res_dtime
res_descr
1008
06/07/1998
07/06/1998
110
1998-07-07 10:24
richc
L
Order placed one month ago (6/7) not received.
1998-07-07 10:30
Checked with shipping (Ed Smith). Order out
yesterday-was waiting for goods from ANZ.
Next time will call with delay if necessary.
order_num
order_date
ship_date
customer_num
call_dtime
user_id
call_code
call_descr
1023
07/24/1998
07/30/1998
127
1998-07-31 14:30
maryj
I
Received Hero watches (item # 304) instead
of ANZ watches
res_dtime
res_descr
Sent memo to shipping to send ANZ item 304
to customer and pickup HRO watches. Should
be done tomorrow, 8/1
図 111. 問合せ結果
自然結合
自然結合は、結合列がデータを重複して表示しないように構成された等価結合の一種で
す。図 112 に例を示します。
72
IBM Informix SQL ガイド: チュートリアル
SELECT manu_name, lead_time, stock.*
FROM manufact, stock
WHERE manufact.manu_code = stock.manu_code
図 112. 問合せ
等価結合の例と同様、図 112 では、表 manufact と表 stock を列 manu_code に基づい
て結合します。選択対象リストがさらに詳しく定義されているため、図 113 に示すよう
に、抽出された各行に対して列 manu_code がリストされるのは 1 回のみです。
manu_name
lead_time
stock_num
manu_code
description
unit_price
unit
unit_descr
Smith
3
1
SMT
baseball gloves
$450.00
case
10 gloves/case
manu_name
lead_time
stock_num
manu_code
description
unit_price
unit
unit_descr
Smith
3
5
SMT
tennis racquet
$25.00
each
each
manu_name
lead_time
stock_num
manu_code
description
unit_price
unit
unit_descr
Smith
3
6
SMT
tennis ball
$36.00
case
24 cans/case
manu_name
lead_time
stock_num
manu_code
description
unit_price
unit
unit_descr
..
.
Anza
5
5
ANZ
tennis racquet
$19.80
each
each
図 113. 問合せ結果
第 2 章 SELECT 文の作成
73
すべての結合には、結合性 があります。つまり、WHERE 節の結合条件の順序は結合の
意味に影響を与えません。
図 114 の文は同じ自然結合を作成します。
SELECT catalog.*, description, unit_price, unit, unit_descr
FROM catalog, stock
WHERE catalog.stock_num = stock.stock_num
AND catalog.manu_code = stock.manu_code
AND catalog_num = 10017
SELECT catalog.*, description, unit_price, unit, unit_descr
FROM catalog, stock
WHERE catalog_num = 10017
AND catalog.manu_code = stock.manu_code
AND catalog.stock_num = stock.stock_num
図 114. 問合せ
いずれの文も 図 115 に示す行を抽出します。
catalog_num 10017
stock_num
101
manu_code
PRC
cat_descr
Reinforced, hand-finished tubular. Polyurethane belted.
Effective against punctures. Mixed tread for super wear
and road grip.
cat_picture <BYTE value>
cat_advert
Ultimate in Puncture Protection, Tires
Designed for In-City Riding
description bicycle tires
unit_price
$88.00
unit
box
unit_descr
4/box
図 115. 問合せ結果
図 114 には、テキスト (TEXT) 型列 cat_descr、バイト (BYTE) 型列 cat_picture、お
よび可変長文字 (VARCHAR) 型列 cat_advert が含まれます。
複数表結合
複数表の結合では、関連する 1 つ以上の列で複数の表を結合します。この結合は、等結
合または自然結合です。
74
IBM Informix SQL ガイド: チュートリアル
図 116 では、catalog、stock、および manufact の各表において等結合が作成されま
す。
SELECT * FROM catalog, stock, manufact
WHERE catalog.stock_num = stock.stock_num
AND stock.manu_code = manufact.manu_code
AND catalog_num = 10025
図 116. 問合せ
図 116 は、図 117 に示す行を抽出します。
catalog_num 10025
stock_num
106
manu_code
PRC
cat_descr
Hard anodized alloy with pearl finish; 6mm hex bolt hard ware.
Available in lengths of 90-140mm in 10mm increments.
cat_picture <BYTE value>
cat_advert
stock_num
manu_code
description
unit_price
unit
unit_descr
manu_code
manu_name
lead_time
ProCycle Stem with Pearl Finish
106
PRC
bicycle stem
$23.00
each
each
PRC
ProCycle
9
図 117. 問合せ結果
manu_code は 3 回 (1 つの表につき 1 回)、stock_num は 2 回使用されています。
図 116 のように複数表の問合せで行が重複しないようにするには、図 118 に示すよう
に、射影リストに特定の列を含めて SELECT 文をより詳細に定義します。
SELECT catalog.*, description, unit_price, unit,
unit_descr, manu_name, lead_time
FROM catalog, stock, manufact
WHERE catalog.stock_num = stock.stock_num
AND stock.manu_code = manufact.manu_code
AND catalog_num = 10025
図 118. 問合せ
第 2 章 SELECT 文の作成
75
図 118 では、ワイルドカードを使用して、最も多くの列を含む表から列をすべて選択
し、他の 2 つの表の列を指定します。図 119 は、図 118 が作成した自然結合を示して
います。この問合せでは、直前の例と同じ情報を表示していますが、重複した行は含ま
れていません。
catalog_num 10025
stock_num
106
manu_code
PRC
cat_descr
Hard anodized alloy with pearl finish. 6mm hex bolt
hardware. Available in lengths of 90-140mm in 10mm increments.
cat_picture <BYTE value>
cat_advert
ProCycle Stem with Pearl Finish
description bicycle stem
unit_price
$23.00
unit
each
unit_descr
each
manu_name
ProCycle
lead_time
9
図 119. 問合せ結果
問合せのショートカット
別名、INTO TEMP 節、および表示ラベルを使用すると、結合と複数表への問合せを高
速で処理し、他で使用するための出力を作成することができます。
別名の使用
SELECT 文の FROM 節の表に別名 を割り当てることにより、複数表問合せを短縮し、
読みやすくすることができます。例えば、他の節にある列名のプレフィックスとして使
用するなど、表名が使用されるところであれば、別名を使用することができます。
SELECT s.stock_num, s.manu_code, s.description,
s.unit_price, c.catalog_num,
c.cat_advert, m.lead_time
FROM stock s, catalog c, manufact m
WHERE s.stock_num = c.stock_num
AND s.manu_code = c.manu_code
AND s.manu_code = m.manu_code
AND s.manu_code IN (’HRO’, ’HSK’)
AND s.stock_num BETWEEN 100 AND 301
ORDER BY catalog_num
図 120. 問合せ
76
IBM Informix SQL ガイド: チュートリアル
結合性のある SELECT 文では、別名を定義する前に使用することができます。図 120
では、表 stock の別名 s、表 catalog の別名 c、および表 manufact の別名 m が
FROM 節で指定され、列のプレフィックスとして SELECT 節と WHERE 節で使用され
ます。
図 120 の長さを、別名を使用していない図 121 の長さと比較してみてください。
SELECT stock.stock_num, stock.manu_code, stock.description,
stock.unit_price, catalog.catalog_num,
catalog.cat_advert,
manufact.lead_time
FROM stock, catalog, manufact
WHERE stock.stock_num = catalog.stock_num
AND stock.manu_code = catalog.manu_code
AND stock.manu_code = manufact.manu_code
AND stock.manu_code IN (’HRO’, ’HSK’)
AND stock.stock_num BETWEEN 100 AND 301
ORDER BY catalog_num
図 121. 問合せ
図 120 と図 121 は同義であり、図 122 に示すデータを抽出します。
stock_num
110
manu_code
HRO
description helmet
unit_price
$260.00
catalog_num 10033
cat_advert
Lightweight Plastic with Vents Assures Cool
Comfort Without Sacrificing Protection
lead_time
4
stock_num
110
manu_code
HSK
description helmet
unit_price
$308.00
catalog_num 10034
cat_advert
Teardrop Design Used by Yellow Jerseys; You
Can Time the Difference
lead_time
5
..
.
図 122. 問合せ結果
テキスト (TEXT) 型列 cat_descr またはバイト (BYTE) 型列 cat_picture にORDER
BY 節を使用することはできません。
第 2 章 SELECT 文の作成
77
また、別名を使用すると、現行のデータベースにない表の問合せを簡単に行うことがで
きます。
図 123 では、現在のデータベースまたはシステム以外の別のデータベースおよびシステ
ムに常駐する 2 つの表の列を結合します。
SELECT order_num, lname, fname, phone
FROM masterdb@central:customer c, sales@western:orders o
WHERE c.customer_num = o.customer_num
AND order_num <= 1010
図 123. 問合せ
別名 c および o を、ロング database@system:table ネームである
masterdb@central:customer と sales@western:orders にそれぞれ割り当てることによ
り、別名を使用して WHERE 節の式を短縮し、図 124 に示す情報を抽出することがで
きます。
order_num lname
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
Higgins
Pauli
Higgins
Watson
Parmelee
Lawson
Sipes
Jaeger
Keyes
Grant
fname
Anthony
Ludwig
Anthony
George
Jean
Margaret
Arnold
Roy
Frances
Alfred
phone
415-368-1100
408-789-8075
415-368-1100
415-389-8789
415-534-8822
415-887-7235
415-245-4578
415-743-3611
408-277-7245
415-356-1123
図 124. 問合せ結果
現行データベースにない表にアクセスする方法については、231 ページの『他のデータ
ベース サーバへのアクセス』および「IBM Informix: SQL ガイド: 構文」を参照してく
ださい。
また、現行表と現行ビューのロング名だけでなく現行のデータベースにない表とビュー
のロング名に対するクイック リファレンスとしてシノニム を使用することもできま
す。シノニムの作成および使用方法の詳細については、「IBM Informix: データベース設
計および実装 ガイド」を参照してください。
78
IBM Informix SQL ガイド: チュートリアル
INTO TEMP 節
INTO TEMP 節を SELECT 文に追加すると、データベースを変更せずに、問合せまた
は操作できる個別の表へ複数表の問合せ結果を一時的に保存することができます。SQL
セッションを終了した場合、あるいはプログラムまたはレポートを終了した場合は一時
表が削除されます。
図 125 のように、一時表 stockman を作成して、その表に問合せ結果を格納します。一
時表では、すべての列に名前を付けなければならないため、別名 adj_price が必要で
す。
SELECT DISTINCT stock_num, manu_name, description,
unit_price, unit_price * 1.05 adj_price
FROM stock, manufact
WHERE manufact.manu_code = stock.manu_code
INTO TEMP stockman;
SELECT * from stockman;
図 125. 問合せ
stock_num manu_name
1
1
1
2
3
4
4
description
Hero
Husky
Smith
Hero
Husky
Hero
Husky
baseball
baseball
baseball
baseball
baseball
football
football
gloves
gloves
gloves
Shimara
ProCycle
ProCycle
Hero
Shimara
Anza
Shimara
Shimara
Hero
Shimara
Anza
Shimara
tandem adapter
infant jogger
twin jogger
ear drops
ear drops
kick board
kick board
water gloves
racer goggles
racer goggles
swim cap
swim cap
bat
unit_price
adj_price
$250.00
$800.00
$450.00
$126.00
$240.00
$480.00
$960.00
$262.5000
$840.0000
$472.5000
$132.3000
$252.0000
$504.0000
$1008.0000
$190.00
$250.00
$280.00
$40.00
$40.00
$84.00
$80.00
$48.00
$72.00
$96.00
$60.00
$72.00
$199.5000
$262.5000
$294.0000
$42.0000
$42.0000
$88.2000
$84.0000
$50.4000
$75.6000
$100.8000
$63.0000
$75.6000
.
.
.
306
307
308
309
309
310
310
311
312
312
313
313
図 126. 問合せ結果
これで、この表の問合せを行い、他の表と結合することができます。その結果、複数ソ
ートが回避され、データベース内をより短時間で移動することができます。一時表の詳
細については、「IBM Informix: SQL ガイド: 構文」および「IBM Informix: Dynamic
Server 管理者ガイド」を参照してください。
第 2 章 SELECT 文の作成
79
サマリ
この章では、リレーショナル データベースへの問合せで使用する基本的な種類の
SELECT 文の構文例とその出力結果を紹介しました。24 ページの『単一表 SELECT
文』には、以下のアクションを実行する方法について記載しています。
v Projection 節および FROM 節を使用して、表内の列および行を選択する。
v Projection 節、FROM 節、および WHERE 節を使用して、表内の行を選択する。
v Projection 節でキーワード DISTINCT または UNIQUE を使用して、問合せ結果から
重複行を除去する。
v ORDER BY 節およびキーワード DESC を使用して、抽出したデータをソートする。
v 英語以外の文字を含むデータ値の選択と順序付けを行う。
v WHERE 節に キーワード BETWEEN、IN、MATCHES、LIKE、およびさまざまな関
係演算子を使用して、比較条件を作成する。
v 値を含む、値を除外する、値の範囲を (キーワード、関係演算子、サブスクリプト付
けで) 検索する、値のサブセットを検索するなどの比較条件を作成する。
v テキストの比較照合、可変長のワイルドカード、および制限付きと制限なしのワイル
ドカードを使用して、変数テキストの検索を実行する。
v 論理演算子 AND、OR、および NOT を使用して、WHERE 節の検索条件またはブー
ル (BOOLEAN) 式を結合する。
v ESCAPE キーワードを使用して、問合せの特殊文字をプロテクトする。
v WHERE 節にキーワード IS NULL や IS NOT NULL を指定して、NULL 値を検索
する。
v FIRST 節を使用して、問合せが SELECT 文の条件に一致する行を指定した数のみ戻
すように指定する。
v Projection 節で算術演算子を使用して、数値フィールドの計算を実行し、抽出したデ
ータを表示する。
v サブ文字列とサブスクリプトで、ユーザの問合せを調整する。
v レポート用のフォーマット手段として、表示ラベルを計算済みの列に設定する。
この章では、複数の表のデータを選択して表示できる簡単な結合条件の概要についても
説明しました。66 ページの『複数表の SELECT 文』には、以下のアクションを実行す
る方法について記載しています。
v デカルト積を作成する。
v デカルト積を作成する交差結合を作成する。
v 有効な結合条件を指定した WHERE 節をユーザの問合せに含めて、デカルト積に制
約条件を設定する。
v 自然結合と等結合を定義して作成する。
v 1 つ以上の列で複数の表を結合する。
80
IBM Informix SQL ガイド: チュートリアル
v 複数表の問合せで短縮形として別名を使用する。
v 選択したデータを INTO TEMP 節で個別の一時表内に抽出し、データベースの外部
で計算を行う。
第 2 章 SELECT 文の作成
81
82
IBM Informix SQL ガイド: チュートリアル
第 3 章 複合型データの選択 (IDS)
行 (ROW) 型データの選択 . . . . . . . . . . . . . . . . . .
型付き表の列の選択 . . . . . . . . . . . . . . . . . . .
行 (ROW) 型データが格納されている列の選択 . . . . . . . . . .
フィールド射影 . . . . . . . . . . . . . . . . . . . .
フィールド射影を使用した、入れ子になったフィールドの選択 . . . .
アスタリスク表記による行 (ROW) 型のすべてのフィールドへのアクセス
コレクション (COLLECTION) 型の選択 . . . . . . . . . . . . .
入れ子コレクション (COLLECTION) 型の選択 . . . . . . . . . .
キーワード IN でコレクション (COLLECTION) 型データ内の要素を検索 .
表階層にある行の選択 . . . . . . . . . . . . . . . . . . .
キーワード ONLY を使用しない上位表の行の選択 . . . . . . . . .
キーワード ONLY を使用した上位表の行の選択. . . . . . . . . .
上位表に別名を使用 . . . . . . . . . . . . . . . . . . .
サマリ . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
84
85
86
87
88
89
90
91
92
94
96
97
97
97
本章について
この章では、複合データ型 に対する問合せを行う方法について説明します。複合データ
型は、SQL 型のコンストラクタと他のデータ型の組合せで構成されます。SQL 文で、
複合データ型内の個々のコンポーネントにアクセスできます。複合データ型は、行
(ROW) 型 またはコレクション (COLLECTION) 型 のいずれかです。
行 (ROW) 型。この型は、関連する 1 つ以上のデータ フィールドを結合するインスタ
ンスを持ちます。行 (ROW) 型には、名前付き 行型と名前なし 行型の 2 種類がありま
す。
コレクション (COLLECTION) 型。この型のインスタンスにおける各コレクション
(COLLECTION) 型値には、基本データ型または複合データ型のどちらか同じ型を持つ要
素のグループが含まれています。コレクションは、リスト (LIST) 型、セット (SET)
型、またはマルチセット (MULTISET) 型で構成できます。
注: 複合データ型のクロス データベース サポートはありません。複合データ型は、ロ
ーカル データベースでのみ操作できます。
データベース サーバがサポートするデータ型の詳細説明については、「IBM Informix:
SQL ガイド: 参照」のデータ型に関する章を参照してください。
複合データ型の作成および使用方法については、「IBM Informix: データベース設計およ
び実装 ガイド」、「IBM Informix: SQL ガイド: 参照」、および「IBM Informix: SQL
ガイド: 構文」を参照してください。
© Copyright IBM Corp. 1996, 2004
83
行 (ROW) 型データの選択
ここでは、行 (ROW) 型データとして定義されたデータの問合せ方法について説明しま
す。行 (ROW) 型は、1 つ以上の関連データ フィールドを結合する複合データ型です。
行 (ROW) 型には、次の 2 種類があります。
v 名前付き行型。名前付き行型では、表、列、他の行 (ROW) 型列のフィールド、プロ
グラム変数、文の局所変数、およびルーチンの戻り値を定義できます。
v 名前なし行型。名前なし行型では、列、他の行 (ROW) 型列のフィールド、プログラ
ム変数、文の局所変数、ルーチンの戻り値、および定数を定義できます。
このセクションに記載する例は、表 employee を定義する名前付き行型 zip_t、
address_t、および employee_t を使用します。図 127 に、行 (ROW) 型および表を作成
する SQL 構文を示します。
CREATE ROW TYPE zip_t
(
z_code
CHAR(5),
z_suffix CHAR(4)
)
CREATE ROW TYPE address_t
(
street
VARCHAR(20),
city
VARCHAR(20),
state
CHAR(2),
zip
zip_t
)
CREATE ROW TYPE employee_t
(
name
VARCHAR(30),
address
address_t,
salary
INTEGER
)
CREATE TABLE employee OF TYPE employee_t
図 127.
名前付き行型の zip_t、address_t、および employee_t は、型付き表 employee のフィー
ルドと列に対するテンプレートの役割を果たします。型付き表 とは、名前付き行型で定
義される表のことです。表 employee のテンプレートとなっている型 employee_t で
は、フィールド address のデータ型として型 address_t が使用されています。型
address_t では、フィールド zip のデータ型として型 zip_t が使用されています。
84
IBM Informix SQL ガイド: チュートリアル
図 128 に、student 表を作成する SQL 構文を示します。student 表の s_address 列
は、名前なし行型で定義されています。ただし、s_address 列は、名前付き行型として
定義されている可能性もあります。
CREATE TABLE student
(
s_name
VARCHAR(30),
s_address
ROW(street VARCHAR (20), city VARCHAR(20),
state CHAR(2), zip VARCHAR(9)),
grade_point_avg DECIMAL(3,2)
)
図 128.
型付き表の列の選択
型付き表での問合せには、他の表での問合せと特に異なる点はありません。例えば、図
129 では、アスタリスク記号 (*) を使用して、employee 表のすべての列を戻す
SELECT 文を指定しています。
SELECT * FROM employee
図 129. 問合せ
employee 表に対する SELECT 文は、図 130 に示すように、すべての列のすべての行を
戻します。
name
address
salary
Paul, J.
ROW(102 Ruby, Belmont, CA, 49932, 1000)
78000
name
address
salary
..
.
Davis, J.
ROW(133 First, San Jose, CA, 85744, 4900)
75000
図 130. 問合せ結果
図 131 に、表 employee の列 name および列 address に含まれる行を戻す問合せを示
します。
第 3 章 複合型データの選択 (IDS)
85
SELECT name, address FROM employee
図 131. 問合せ
name
address
Paul, J.
ROW(102 Ruby, Belmont, CA, 49932, 1000)
name
address
..
.
Davis, J.
ROW(133 First, San Jose, CA, 85744, 4900)
図 132. 問合せ結果
行 (ROW) 型データが格納されている列の選択
行 (ROW) 型列 とは、名前付き行型または名前なし行型で定義される列のことです。名
前付き行型と名前なし行型に対する問合せには、同じ SQL 構文を使用します。
行 (ROW) 型列に対する問合せでは、行 (ROW) 型のすべてのフィールドにあるデータ
が戻されます。フィールド は、行 (ROW) 型内のコンポーネント データ型です。例え
ば、表 employee の列 address には、street、city、state、および zip というフィールド
が含まれています。図 133 に、列 address のすべてのフィールドを戻す問合せを構成す
る方法を示します。
SELECT address FROM employee
図 133. 問合せ
address
address
address
..
.
ROW(102 Ruby, Belmont, CA, 49932, 1000)
ROW(133 First, San Jose, CA, 85744, 4900)
ROW(152 Topaz, Willits, CA, 69445, 1000))
図 134. 問合せ結果
1 つの列に含まれる個々のフィールドにアクセスするには、単一ピリオド表記を使用し
て、列の個々のフィールドを射影します。例えば、表 employee の列 address にある特
定のフィールドにアクセスすると仮定します。その場合には、次の SELECT 文を実行
して、列 address にあるフィールド city とフィールド state を射影します。
86
IBM Informix SQL ガイド: チュートリアル
SELECT address.city, address.state FROM employee
図 135. 問合せ
city
state
Belmont
San Jose
Willits
..
.
CA
CA
CA
図 136. 問合せ結果
名前なし行型列に対する問合せも、名前付き行型列への問合せと同じ方法で作成しま
す。例えば、図 128 に示す表 student の列 s_address にあるデータにアクセスすると
仮定します。名前なし行型で定義された列の個々のフィールドに対して問合せを行うに
は、ピリオド表記 を使用します。図 137 に、表 student に関して列 s_address の city
および state フィールドに関する行を戻す SELECT 文を示します。
SELECT s_address.city, s_address.state FROM student
図 137. 問合せ
city
state
Belmont
Mount Prospect
Greeley
..
.
CA
IL
CO
図 138. 問合せ結果
フィールド射影
フィールドと列を混同しないようにしてください。列は表に関連付けられており、列の
射影には name_1.name_2 というフォーム (それぞれ表と列を示す) の標準的なピリオド
表記が使用されます。フィールド は、行 (ROW) 型内のコンポーネント データ型で
す。行 (ROW) 型では、単一の列に行 (ROW) 型を割り当てる機能を使用し、
第 3 章 複合型データの選択 (IDS)
87
name_a.name_b.name_c.name_d という単一ピリオド表記を使用することで、列の個々の
フィールドを射影できます。Informix データベース サーバでは、ピリオド表記は次の優
先順位に従って解釈されます。
1. table_name_a . column_name_b . field_name_c . field_name_d
2. column_name_a . field_name_b . field_name_c . field_name_d
ある識別子の意味があいまいな場合、データベース サーバでは、上記の優先順位のルー
ルにより、その識別子で指定するデータベース オブジェクトがどれであるかが決定され
ます。次の 2 つの文を検討してみてください。
CREATE TABLE b (c ROW(d INTEGER, e CHAR(2)))
CREATE TABLE c (d INTEGER)
次の SELECT 文では、表の識別子の方が列の識別子より優先順位が高いため、式 c.d
は、表 c の列 d を参照します。表 b にある列 c のフィールド d を参照するのではあ
りません。
SELECT * FROM b,c WHERE c.d = 10
間違ったデータベース オブジェクトを参照するのを防ぐには、完全な表記で指定して、
フィールドを射影します。例えば、表 c の列 d ではなく、表 b にある列 c のフィー
ルド d を参照する必要があると仮定します。次の文では、参照するオブジェクトの
表、列、およびフィールドの識別子を指定しています。
SELECT * FROM b,c WHERE b.c.d = 10
重要: 優先順位規則により、データベース サーバでフィールド投影が誤って解釈される
危険性は減少しますが、表、列、フィールドの識別子にはすべて一意の名前を使
用することをお勧めします。
フィールド射影を使用した、入れ子になったフィールドの選択
通常、行 (ROW) 型は 1 つの列ですが、任意の行 (ROW) 型式を使用してフィールドを
射影することができます。行 (ROW) 型式が他の行 (ROW) 型を含む場合、その式には
入れ子になったフィールド が含まれます。式内の入れ子になったフィールドや個々のフ
ィールドにアクセスするには、ピリオド表記を使用します。行 (ROW) 型のすべてのフ
ィールドにアクセスするには、アスタリスク (*) を使用します。ここでは、両方の行
(ROW) 型へのアクセス方法について説明します。
行 (ROW) 型式でピリオド表記やアスタリスク表記を使用する方法については、
「IBM Informix: SQL ガイド: 構文」の式セグメントを参照してください。
行 (ROW) 型の個々のフィールドの選択: 表 employee の列 address について考
えてみましょう。この中には、street、city、state、および zip というフィールドが含ま
れています。また、フィールド zip には、z_code と z_suffix という入れ子になったフ
ィールドが含まれています。84 ページの図 127 の行 (ROW) 型と表の定義を再確認し
てください。フィールド zip で問合せを行うと、フィールド z_code とフィールド
88
IBM Informix SQL ガイド: チュートリアル
z_suffix の行が戻されます。ただし、特定の入れ子になったフィールドのみを戻すよう
に指定することも可能です。図 139 に、ピリオド表記を使用して、列 address の
z_code フィールドの行のみを戻す SELECT 文の構成方法を示します。
SELECT address.zip.z_code FROM employee
図 139. 問合せ
z_code
39444
6500
76055
19004
..
.
図 140. 問合せ結果
アスタリスク表記による行 (ROW) 型のすべてのフィールドへのアクセス
アスタリスク表記は、SELECT 文の選択対象リスト内でのみサポートされます。射影リ
ストで行 (ROW) 型列に列名を指定すると、データベース サーバはその列にあるすべて
のフィールドの値を戻します。行 (ROW) 型にあるフィールドすべてを射影する場合に
も、アスタリスク表記を使用できます。
図 141 では、アスタリスク表記が使用され、表 employee の列 address にあるすべての
フィールドが戻されています。
SELECT address.* FROM employee
図 141. 問合せ
address
address
address
..
.
ROW(102 Ruby, Belmont, CA, 49932, 1000)
ROW(133 First, San Jose, CA, 85744, 4900)
ROW(152 Topaz, Willits, CA, 69445, 1000))
図 142. 問合せ結果
第 3 章 複合型データの選択 (IDS)
89
SQL タスクの中には、アスタリスク表記を使用すると簡単に実行できるようになるもの
があります。行 (ROW) 型の値を戻す関数 new_row() を作成し、この関数を呼び出し
て、戻された行を表に挿入すると仮定します。こういった操作を簡単に処理する方法
は、データベース サーバでは提供されていません。しかし、図 143 では、アスタリス
ク表記を使用して、new_row() のフィールドすべてを戻し、その戻されたフィールドを
表 tab_2 に挿入しています。
INSERT INTO tab_2 SELECT new_row(exp).* FROM tab_1
図 143. 問合せ
INSERT 文の使用方法については、 183 ページの『第 6 章 データの変更』を参照して
ください。
重要: .* 表記を使用する式が評価されるのは 1 回のみです。
コレクション (COLLECTION) 型の選択
ここでは、コレクション (COLLECTION) 型で定義されている列への問合せ方法を説明
します。コレクション (COLLECTION) 型 とは、コレクション (COLLECTION) 型のど
の値にも、同じデータ型の要素のグループが格納されている複合データ型のことです。
コレクション (COLLECTION) 型の詳細については、「IBM Informix: データベース設計
および実装 ガイド」を参照してください。コレクション (COLLECTION) 型に格納され
ている個々の要素へアクセスする方法については、167 ページの『SELECT 文でのコレ
クションの処理 (IDS)』を参照してください。
ここでは、図 144 に示す表 manager を例として使用します。表 manager には、単純
コレクション (COLLECTION) 型と、入れ子コレクション (COLLECTION) 型が含まれ
ています。単純コレクション (COLLECTION) 型 とは、それ自体がコレクション
(COLLECTION) 型であるフィールドを 1 つも含まないコレクション (COLLECTION)
型のことです。この例では、表 manager の列 direct_reports が単純コレクション
(COLLECTION) 型です。入れ子コレクション (COLLECTION) 型 は、他のコレクショ
ン (COLLECTION) 型を含むコレクション (COLLECTION) 型です。この例では、表
manager の列 projects が入れ子コレクション (COLLECTION) 型です。
90
IBM Informix SQL ガイド: チュートリアル
CREATE TABLE manager
(
mgr_name
VARCHAR(30),
department
VARCHAR(12),
direct_reports SET(VARCHAR(30) NOT NULL),
projects
LIST(ROW(pro_name VARCHAR(15),
pro_members SET(VARCHAR(20) NOT NULL)
) NOT NULL)
)
図 144.
コレクション (COLLECTION) 型の列への問合せを実行すると、表の行ごとに、特定の
コレクション (COLLECTION) 型が含む要素がすべて戻されます。例えば、列
department にあるデータおよび列 direct_reports にある要素すべてが表 manager の行
ごとに戻される問合せを、図 145 に示します。
SELECT department, direct_reports FROM manager
図 145. 問合せ
department
marketing
direct_reports SET {Smith, Waters, Adams, Davis, Kurasawa}
department
engineering
ddirect_reports SET {Joshi, Davis, Smith, Waters, Fosmire, Evans, Jones}
department
publications
direct_reports SET {Walker, Fremont, Porat, Johnson}
department
accounting
direct_reports
SET {Baker, Freeman, Jacobs}
.
.
.
図 146. 問合せ結果
コレクション (COLLECTION) 型に対する問合せの出力には必ず、そのコレクションが
セット (SET) 型、マルチセット (MULTISET) 型、およびリスト (LIST) 型のいずれで
あるかを示すコンストラクタが含まれます。例えば、図 146 では、各コレクションの要
素よりも SET コンストラクタが優先されます。コレクション (COLLECTION) 型の要
素は中括弧 ({}) で囲まれ、コレクション (COLLECTION) 型の各要素はコンマで区切
られています。
入れ子コレクション (COLLECTION) 型の選択
91 ページの図 144 では、表 manager の列 projects が入れ子コレクション
(COLLECTION) 型です。入れ子コレクション (COLLECTION) 型へ問合せると、特定の
第 3 章 複合型データの選択 (IDS)
91
コレクション (COLLECTION) 型データがもつすべての要素が戻されます。図 147 は、
指定した行に対して列 projects にある要素がすべて戻される問合せです。この例では、
列 mgr_name に格納されている値が Sayles である単一の行へ問合せるように、
WHERE 節を使用して制限を設けています。
SELECT projects
FROM manager
WHERE mgr_name = ’Sayles’
図 147. 問合せ
図 148 は、表 manager の単一行に対する列 project のコレクション (COLLECTION)
型データの表示結果です。この問合せでは、Sayles というマネージャが管理しているプ
ロジェクトの名前が戻されます。このコレクション (COLLECTION) 型データには、リ
スト (LIST) 型の各要素に対して、プロジェクト名 (pro_name)、およびセット (SET)
型になっている各プロジェクトを担当するメンバ (pro_members) が格納されていま
す。
projects
LIST {ROW(voyager_project, SET{Simonian, Waters, Adams, Davis})}
projects
LIST {ROW(horizon_project, SET{Freeman, Jacobs, Walker, Cannan})}
projects
.
.
.
LIST {ROW(sapphire_project, SET{Villers, Reeves, Doyle, Strongin})}
図 148. 問合せ結果
キーワード IN でコレクション (COLLECTION) 型データ内の要素を検索
SQL 文の WHERE 節にキーワード IN を使用し、コレクションが特定の要素を含んで
いるか判別できます。例えば、図 149 に、列 direct_reports のコレクション
(COLLECTION) 型データに Adams という要素が格納されている mgr_name と
department の値を戻す問合せを示します。
SELECT mgr_name, department
FROM manager
WHERE ’Adams’ IN direct_reports
図 149. 問合せ
92
IBM Informix SQL ガイド: チュートリアル
mgr_name
department
Sayles
marketing
図 150. 問合せ結果
WHERE 節でキーワード IN を指定して単純コレクション (COLLECTION) 型データに
格納されている特定の要素を検索することができますが、この問合せではすべてのコレ
クション (COLLECTION) 型データが必ず戻されます。例えば、図 151 では、列
direct_reports のコレクション (COLLECTION) 型の要素が Adams であるコレクション
型の要素すべてが戻されています。
SELECT mgr_name, direct_reports
FROM manager
WHERE ’Adams’ IN direct_reports
図 151. 問合せ
mgr_name
direct_reports
Sayles
SET {Smith, Waters, Adams, Davis, Kurasawa}
図 152. 問合せ結果
図 152 に示すように、コレクション (COLLECTION) 型列への問合せでは、コレクショ
ン (COLLECTION) 型データに含まれている特定の要素ではなく、コレクション
(COLLECTION) 型データ全体が戻されます。
WHERE 節にキーワード IN を使用し、単純コレクションのみ参照できます。コレクシ
ョン (COLLECTION) 型のフィールドを含むコレクション (COLLECTION) 型を参照す
る場合には、キーワード IN は使用できません。例えば、表 manager の列 projects は
入れ子コレクション (COLLECTION) 型のため、キーワード IN を指定してこの列
projects を参照することはできません。
SELECT 文の WHERE 節でキーワード NOT と IN を結合させ、特定の要素を含まな
いコレクションを検索できます。例えば、図 153 に、列 direct_reports のコレクション
に Adams という要素が格納されていない mgr_name と department の値を戻す問合せ
を示します。
第 3 章 複合型データの選択 (IDS)
93
SELECT mgr_name, department
FROM manager
WHERE ’Adams’ NOT IN direct_reports
図 153. 問合せ
mgr_name
department
Williams
engineering
mgr_name
department
Lyman
publications
mgr_name
department
Cole
accounting
図 154. 問合せ結果
コレクション (COLLECTION) 型列の要素数のカウント方法については、115 ページの
『計数関数 (IDS)』を参照してください。
表階層にある行の選択
ここでは、表階層内の表に含まれている行へ問合せを行う方法について説明します。表
階層の作成および使用方法の詳細については、「IBM Informix: データベース設計および
実装 ガイド」を参照してください。
このセクションで例として使用している型と表の階層を作成する文を、図 155 に示しま
す。
94
IBM Informix SQL ガイド: チュートリアル
CREATE ROW
(
street
city
state
zip
)
TYPE address_t
VARCHAR (20),
VARCHAR(20),
CHAR(2),
VARCHAR(9)
CREATE ROW TYPE person_t
(
name
VARCHAR(30),
address address_t,
soc_sec CHAR(9)
)
CREATE ROW TYPE employee_t
(
salary
INTEGER
)
UNDER person_t
CREATE ROW TYPE sales_rep_t
(
rep_num
SERIAL8,
region_num INTEGER
)
UNDER employee_t
CREATE TABLE person OF TYPE person_t
CREATE TABLE employee OF TYPE employee_t
UNDER person
CREATE TABLE sales_rep OF TYPE sales_rep_t
UNDER employee
図 155.
図 156 に、図 155 内の行 (ROW) 型と表の階層関係を示します。
第 3 章 複合型データの選択 (IDS)
95
person_t
person
employee_t
employee
sales_rep_t
sales_rep
図 156. 型と表の階層
キーワード ONLY を使用しない上位表の行の選択
表階層を使用することで、1 つの SQL 文で、問合せ範囲を上位表とその副表とする問
合せを作成することができます。上位表に対する問合せでは、上位表とその副表の両方
から行が戻されます。図 157 に、表階層の最上位表である表 person に対する問合せを
示します。
SELECT * FROM person
図 157. 問合せ
図 35 では、上位表に格納されている列すべてと、その上位表から継承を行う副表
(employee と sales_rep) の列が戻されます。ただし、上位表に対する問合せは、上位表
にない副表の列を戻しません。図 158 では、表 person、employee、および sales_rep
内の列 name、address、および soc_sec を戻します。
name
address
soc_sec
Rogers, J.
ROW(102 Ruby Ave, Belmont, CA, 69055)
454849344
name
address
soc_sec
..
.
Sallie, A.
ROW(134 Rose St, San Carlos, CA, 69025)
348441214
図 158. 問合せ結果
96
IBM Informix SQL ガイド: チュートリアル
キーワード ONLY を使用した上位表の行の選択
上位表に対する SELECT 文では上位表とその副表の両方から行が戻されますが、上位
表から選択された行と副表から選択された行を見分けることはできません。上位表の行
のみを出力するように問合せ結果を制限するには、SELECT 文にキーワード ONLY を
追加する必要があります。例えば、図 159 は、表 person のみの行を戻します。
SELECT * FROM ONLY(person)
図 159. 問合せ
name
address
soc_sec
..
.
Rogers, J.
ROW(102 Ruby Ave, Belmont, CA, 69055)
454849344
図 160. 問合せ結果
上位表に別名を使用
別名 は、FROM 節で表名の直後に指定されます。SELECT 文や UPDATE 文で型付き
表に別名を指定し、その別名そのものを式として使用することができます。上位表の別
名を作成すると、その上位表、またはその上位表から継承を行う副表にある値をその別
名で表すことができます。DB–Access では、図 161 は person 表、employee 表、およ
び sales_rep 表のすべてのインスタンスの行の値を戻します。
SELECT p FROM person p
図 161. 問合せ
ESQL/C では、この構成を認識しません。ESQL/C プログラムでは、図 161 でエラーが
戻されます。
サマリ
この章では、リレーショナル データベースへの問合せにおいて、SELECT 文を使用し
て複合型のデータを選択する場合の構文例とその実行結果を紹介しました。84 ページの
『行 (ROW) 型データの選択』には、以下のアクションを実行する方法について記載し
ています。
v 型付き表および列からの行 (ROW) 型データの選択
v 行 (ROW) 型式を使用した、フィールドの射影
第 3 章 複合型データの選択 (IDS)
97
90 ページの『コレクション (COLLECTION) 型の選択』には、以下のアクションを実行
する方法について記載しています。
v コレクション (COLLECTION) 型で定義された列への問合せ
v コレクション (COLLECTION) 型データ内の要素の検索
v 入れ子コレクション (COLLECTION) 型で定義された列への問合せ
94 ページの『表階層にある行の選択』には、以下のアクションを実行する方法について
記載しています。
v 上位表に対するキーワード ONLY を使用または使用しない問合せ
v 上位表に対する別名の指定
98
IBM Informix SQL ガイド: チュートリアル
第 4 章 SELECT 文での関数の使用
SELECT 文での関数の使用 . . . . . . . . . .
集計関数 . . . . . . . . . . . . . . .
COUNT 関数の使用 . . . . . . . . . . .
AVG 関数の使用 . . . . . . . . . . . .
MAX 関数と MIN 関数の使用 . . . . . . .
SUM 関数の使用 . . . . . . . . . . . .
RANGE 関数の使用 . . . . . . . . . . .
STDEV 関数の使用 . . . . . . . . . . .
VARIANCE 関数の使用 . . . . . . . . .
式への関数の適用 . . . . . . . . . . .
時刻関数 . . . . . . . . . . . . . . .
DAY 関数と CURRENT 関数の使用 . . . . .
MONTH 関数の使用 . . . . . . . . . . .
WEEKDAY 関数の使用. . . . . . . . . .
YEAR 関数の使用 . . . . . . . . . . .
日時 (DATETIME) 型値の形式 . . . . . . .
日付変換関数 (IDS) . . . . . . . . . . . .
DATE 関数の使用 . . . . . . . . . . .
TO_CHAR 関数の使用 . . . . . . . . . .
TO_DATE 関数の使用 . . . . . . . . . .
計数関数 (IDS) . . . . . . . . . . . . .
スマート ラージ オブジェクト関数 (IDS) . . . .
文字列操作関数 (IDS) . . . . . . . . . . .
LOWER 関数の使用 . . . . . . . . . . .
UPPER 関数の使用 . . . . . . . . . . .
INITCAP 関数の使用 . . . . . . . . . .
REPLACE 関数の使用 . . . . . . . . . .
SUBSTRING 関数と SUBSTR 関数の使用 . . .
SUBSTRING 関数の使用 . . . . . . . . .
SUBSTR 関数の使用. . . . . . . . . . .
LPAD 関数の使用 . . . . . . . . . . .
RPAD 関数の使用 . . . . . . . . . . .
その他の関数 . . . . . . . . . . . . . .
LENGTH 関数の使用 . . . . . . . . . .
USER 関数の使用 . . . . . . . . . . .
TODAY 関数の使用 . . . . . . . . . . .
DBSERVERNAME 関数と SITENAME 関数の使用
HEX 関数の使用 . . . . . . . . . . . .
DBINFO 関数の使用. . . . . . . . . . .
DECODE 関数の使用 . . . . . . . . . .
© Copyright IBM Corp. 1996, 2004
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
100
100
101
102
103
103
104
105
105
106
106
107
108
109
110
111
112
112
113
114
115
116
118
118
119
120
120
121
121
123
124
124
125
125
126
127
128
129
129
130
99
NVL 関数の使用 (IDS) . . .
SELECT 文での SPL ルーチンの使用
データ暗号化関数の使用 (IDS) . .
サマリ . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
131
132
134
136
本章について
列名と演算子と同様に、式には、1 つ以上の関数を含むことができます。この章では、
SELECT 文の中で関数を使用して、さらに複雑なデータベースへの問合せとデータ操作
を実行する方法を説明します。この章では、集計関数、時刻関数、日付変換関数、計数
関数、スマート ラージ オブジェクト関数、文字列操作関数、データ暗号化関数などの
関数について説明します。
以下の SQL 関数およびその他の SQL 関数については、「IBM Informix: SQL ガイド:
構文」の式セグメントを参照してください。
ヒント: ユーザ独自の関数を使用することもできます。ユーザ定義関数については、305
ページの『第 11 章 SPL ルーチンの作成と使用』および「IBM Informix: ユー
ザ定義ルーチンおよびデータ タイプ 開発者ガイド」を参照してください。
SELECT 文での関数の使用
選択リストの中では、列、定数、関数、集計関数、およびプロシジャという基本的なタ
イプの式のどれでも使用することができます。また、それらの式を組み合わせたものも
使用できます。
関数式では、問合せにおいて行ごとに評価される関数が使用されます。すべての関数式
には引数が必要です。引数に列名を指定してこれらの式を使用する場合には、式の中に
時刻関数と長さ関数が含まれます。
集計関数
Informix データベース サーバはすべて、以下の集計 関数をサポートします。
v AVG
v COUNT
v MAX
v MIN
v RANGE
v STDEV
v SUM
v VARIANCE
100
IBM Informix SQL ガイド: チュートリアル
集計関数は、問合せ対象行の集合に対して値を 1 つ戻します。集計関数は、SELECT
文の WHERE 節から戻される行の集合に依存する値をとります。WHERE 節を指定し
ない場合、集計関数は、FROM 節で形成されるすべての行に依存する値をとります。
次のデータ型が含まれている式では、集計関数を使用できません。
v テキスト (TEXT) 型
v バイト (BYTE) 型
Dynamic Server
v CLOB 型
v BLOB 型
v 不透明 (OPAQUE) 型 (ユーザ定義集計関数でない場合)
v コレクション (COLLECTION) 型
v 行 (ROW) 型
Dynamic Server の終り
集計関数は、表内のグループ行についての情報をまとめるために多く使用されます。こ
の使用方法については、第 5 章で説明しています。集計関数を表全体に適用する場合に
は、選択対象行をすべて集計した結果が単一行に格納されます。
COUNT 関数の使用
図 162 では、表 stock 内の行の合計数をカウントして表示します。
SELECT COUNT(*) FROM stock
図 162. 問合せ
(count(*))
73
図 163. 問合せ結果
図 164 は、表 stock の特定の行 (この場合は、SHM の manu_code を持つ行のみ) をカ
ウントする WHERE 節を含みます。
第 4 章 SELECT 文での関数の使用
101
SELECT COUNT (*) FROM stock WHERE manu_code = ’SHM’
図 164. 問合せ
(count(*))
17
図 165. 問合せ結果
キーワード DISTINCT (またはキーワード UNIQUE) と図 166 に示されている列名を含
めると、表 stock 内の別のメーカー コード数を計算することができます。
SELECT COUNT (DISTINCT manu_code) FROM stock
図 166. 問合せ
(count)
9
図 167. 問合せ結果
AVG 関数の使用
図 168 は、表 stock のすべての行の平均 unit_price を計算します。
SELECT AVG (unit_price) FROM stock
図 168. 問合せ
(avg)
$197.14
図 169. 問合せ結果
102
IBM Informix SQL ガイド: チュートリアル
図 170 では、SHM という manu_code を持つ表 stock 内の行の平均 unit_price を計算
します。
SELECT AVG (unit_price) FROM stock WHERE manu_code = ’SHM’
図 170. 問合せ
(avg)
$204.93
図 171. 問合せ結果
MAX 関数と MIN 関数の使用
同じ SELECT 文の中で、集計関数を組み合わせて使用することができます。例えば、
図 172 に示すように、MAX 関数と MIN 関数を両方選択リストに含めることができま
す。
SELECT MAX (ship_charge), MIN (ship_charge) FROM orders
図 172. 問合せ
図 172 では、図 173 で示されているように、表 orders 内の ship_charge の最大値およ
び最小値を検索して表示します。
(max)
(min)
$25.20
$5.00
図 173. 問合せ結果
SUM 関数の使用
図 174 では、1998 年 7 月 13 日に出荷した注文合計 ship_weight を計算します。
第 4 章 SELECT 文での関数の使用
103
SELECT SUM (ship_weight) FROM orders
WHERE ship_date = ’07/13/1998’
図 174.
(sum)
130.5
図 175. 問合せ結果
RANGE 関数の使用
RANGE 関数は、選択対象行の最大値と最小値の差を計算します。
RANGE 関数は数値型列にのみ適用できます。図 176 は、表 stock の商品価格の範囲
を検出します。
SELECT RANGE(unit_price) FROM stock
図 176. 問合せ
(range)
955.50
図 177. 問合せ結果
図 178 に示すように、GROUP BY 節を含む問合せでは、RANGE 関数は他の集計関数
と同様にグループ内の行に適用されます。
SELECT RANGE(unit_price) FROM stock
GROUP BY manu_code
図 178. 問合せ
104
IBM Informix SQL ガイド: チュートリアル
(range)
820.20
595.50
720.00
225.00
632.50
0.00
460.00
645.90
425.00
図 179. 問合せ結果
STDEV 関数の使用
STDEV 関数は、選択された行の標準偏差を計算します。これは、VARIANCE 関数の
平方根にあたります。
STDEV 関数は数値型列にのみ適用できます。次の問合せでは、母集団の標準偏差を表
示します。
SELECT STDEV(age) FROM u_pop WHERE age > 21
次の例に示すように、GROUP BY 節を含む問合せでは、STDEV 関数は他の集計関数
と同様にグループ内の行に適用されます。
SELECT STDEV(age) FROM u_pop
GROUP BY state
WHERE STDEV(age) > 21
指定された列のすべての値が NULL である場合を除いて、NULL 値は無視されます。
すべての列の値が NULL の場合、STDEV 関数はその列には NULL を戻します。
STDEV 関数の詳細については、「IBM Informix: SQL ガイド: 構文」の式セグメントを
参照してください。
VARIANCE 関数の使用
VARIANCE 関数は、選択対象行すべてに対して、値のサンプルの分散を母集団の分散
の不偏推定値として戻します。この関数は、次の値を計算します。
(SUM(Xi**2) - (SUM(Xi)**2)/N)/(N-1)
この例では、Xi は列の各値を示し、N は列の値の総数を示します。VARIANCE 関数
は、数値型列のみに適用できます。次の問合せでは、母集団の分散を表示します。
SELECT VARIANCE(age) FROM u_pop WHERE age > 21
第 4 章 SELECT 文での関数の使用
105
次の例に示すように、GROUP BY 節を含む問合せでは、VARIANCE 関数は他の集計
関数と同様にグループ内の行に適用されます。
SELECT VARIANCE(age) FROM u_pop
GROUP BY birth
WHERE VARIANCE(age) > 21
指定された列のすべての値が NULL である場合を除いて、NULL 値は無視されます。
すべての列の値が NULL の場合、VARIANCE 関数はその列には NULL を戻します。
VARIANCE 関数の詳細については、「IBM Informix: SQL ガイド: 構文」の式セグメン
トを参照してください。
式への関数の適用
図 180 は、関数を式の中で使用し、その結果に表示ラベルを付ける方法を示していま
す。
SELECT MAX (res_dtime - call_dtime) maximum,
MIN (res_dtime - call_dtime) minimum,
AVG (res_dtime - call_dtime) average
FROM cust_calls
図 180. 問合せ
図 180 は、顧客の注文を受け取ってから処理するまでの時間 (日、時間、分の単位) の
最大値、最小値、および平均値を計算して表示し、さらにその値に適切なラベルを付け
ます。図 181 に、この 3 種類の時間を示します。
maximum
minimum
average
5 20:55
0 00:01
1 02:56
図 181. 問合せ結果
時刻関数
問合せの Projection 節または WHERE 節で、時刻 関数 DAY、MDY、MONTH、
WEEKDAY、および YEAR を使用できます。これらの時刻関数は、関数の呼出しに使
用する式または引数に対応する値を戻します。CURRENT 関数を使用して、現在の日付
と時刻をもつ値を戻し、EXTEND 関数を使用して日付 (DATE) 型または日時
(DATETIME) 型値の精度を調整できます。
106
IBM Informix SQL ガイド: チュートリアル
DAY 関数と CURRENT 関数の使用
図 182 では、2 つの expression という列に列 call_dtime および res_dtime の日付を戻
します。
SELECT customer_num, DAY (call_dtime), DAY (res_dtime)
FROM cust_calls
図 182. 問合せ
customer_num
(expression) (expression)
106
110
119
121
127
116
116
12
7
1
10
31
28
21
12
7
2
10
28
27
図 183. 問合せ結果
図 184 では、DAY 関数および CURRENT 関数を使用して、列の値を月の現在の日付
と比較します。この問合せでは、現在の日付より以前の日付が含まれている行のみを選
択します。この例では、CURRENT 日付を 15 としています。
SELECT customer_num, DAY (call_dtime), DAY (res_dtime)
FROM cust_calls
WHERE DAY (call_dtime) < DAY (CURRENT)
図 184. 問合せ
customer_num
106
110
119
121
(expression) (expression)
12
12
7
7
1
2
10
10
図 185. 問合せ結果
図 186 では、CURRENT 関数を使用して、今日受け取った注文を除く、すべての注文
を選択します。
第 4 章 SELECT 文での関数の使用
107
SELECT customer_num, call_code, call_descr
FROM cust_calls
WHERE call_dtime < CURRENT YEAR TO DAY
図 186. 問合せ
customer_num 106
call_code
D
call_descr
Order was received, but two of the cans of ANZ tennis balls
within the case were empty
customer_num 110
call_code
L
call_descr
Order placed one month ago (6/7) not received.
.
.
.
customer_num 116
call_code
I
call_descr
Second complaint from this customer! Received two cases
right-handed outfielder gloves (1 HRO) instead of one case
lefties.
図 187. 問合せ結果
MONTH 関数の使用
図 188 では、MONTH 関数を使用して顧客からの請求を受け取って処理した月を抽出
して表示し、結果を示す列の表示ラベルを使用します。しかし年は区別しません。
SELECT customer_num,
MONTH (call_dtime) call_month,
MONTH (res_dtime) res_month
FROM cust_calls
図 188. 問合せ
108
IBM Informix SQL ガイド: チュートリアル
customer_num
call_month
res_month
106
110
119
121
127
116
116
6
7
7
7
7
11
12
6
7
7
7
11
12
図 189. 問合せ結果
図 190 では、MONTH 関数、DAY 関数、および CURRENT 関数を使用して、DAY
が現在の日付より前の場合、顧客注文を受けた月と納入した月を表示します。
SELECT customer_num,
MONTH (call_dtime) called,
MONTH (res_dtime) resolved
FROM cust_calls
WHERE DAY (res_dtime) < DAY (CURRENT)
図 190. 問合せ
customer_num
called
resolved
106
119
121
6
7
7
6
7
7
図 191. 問合せ結果
WEEKDAY 関数の使用
図 192 では、WEEKDAY 関数を使用して、注文を受けた曜日と納入した曜日を示し (0
は日曜、1 は月曜を表す) 、式列にラベルを付けます。
第 4 章 SELECT 文での関数の使用
109
SELECT customer_num,
WEEKDAY (call_dtime) called,
WEEKDAY (res_dtime) resolved
FROM cust_calls
ORDER BY resolved
図 192. 問合せ
customer_num
called
resolved
127
110
119
121
116
106
116
3
0
1
3
3
3
5
0
2
3
3
3
4
図 193. 問合せ結果
図 194 では、COUNT 関数および WEEKDAY 関数を使用して、週末に受けた注文数
をカウントします。この種の SELECT 文を使用すると、顧客からの請求パターンがど
のようなものか、または時間外手当が必要かどうかを示すことができます。
SELECT COUNT(*)
FROM cust_calls
WHERE WEEKDAY (call_dtime) IN (0,6)
図 194. 問合せ
(count(*))
4
図 195. 問合せ結果
YEAR 関数の使用
図 196 では、call_dtime が今年の 1 月 1 日より以前の日付が含まれている行を抽出し
ます。
110
IBM Informix SQL ガイド: チュートリアル
SELECT customer_num, call_code,
YEAR (call_dtime) call_year,
YEAR (res_dtime) res_year
FROM cust_calls
WHERE YEAR (call_dtime) < YEAR (TODAY)
図 196. 問合せ
customer_num call_code call_year res_year
116 I
116 I
1997
1997
1997
1997
図 197. 問合せ結果
日時 (DATETIME) 型値の形式
図 198 では、EXTEND 関数は、指定されたサブフィールドのみを表示することによ
り、2 つの日時 (DATETIME) 型値を制限します。
SELECT customer_num,
EXTEND (call_dtime, month to minute) call_time,
EXTEND (res_dtime, month to minute) res_time
FROM cust_calls
ORDER BY res_time
図 198. 問合せ
図 199 では、列 call_time および res_time の月から分までの範囲を戻して、作業負荷
を示します。
customer_num call_time
127
106
119
110
121
116
116
07-31
06-12
07-01
07-07
07-10
11-28
12-21
14:30
08:20
15:00
10:24
14:05
13:34
11:24
res_time
06-12
07-02
07-07
07-10
11-28
12-27
08:25
08:21
10:30
14:06
16:47
08:19
図 199. 問合せ結果
第 4 章 SELECT 文での関数の使用
111
日付変換関数 (IDS)
次の変換関数は、日付 (DATE) 型と文字 (CHAR) 型値との間で変換処理を行います。
v DATE
v TO_CHAR
v TO_DATE
日付変換関数は、式を使用する部分ならどこででも使用することができます。
DATE 関数の使用
DATE 関数は、文字列を日付 (DATE) 型値に変換します。図 200 では、DATE 関数で
文字列を日付 (DATE) 型値に変換し、日時 (DATETIME) 型値と比較します。この問合
せでは、call_dtime が指定された 日付 (DATE) 型よりも後である場合のみ、日時
(DATETIME) 型値を抽出します。
SELECT customer_num, call_dtime, res_dtime
FROM cust_calls
WHERE call_dtime > DATE (’12/31/97’)
図 200. 問合せ
customer_num call_dtime
106
110
119
121
127
1998-06-12
1998-07-07
1998-07-01
1998-07-10
1998-07-31
res_dtime
08:20
10:24
15:00
14:05
14:30
1998-06-12
1998-07-07
1998-07-02
1998-07-10
08:25
10:30
08:21
14:06
図 201. 問合せ結果
図 202 では、call_dtime が指定された日付以上の値である場合、日時 (DATETIME) 型
値を日付 (DATE) 型に変換してラベルを付けて表示します。
SELECT customer_num,
DATE (call_dtime) called,
DATE (res_dtime) resolved
FROM cust_calls
WHERE call_dtime >= DATE (’1/1/98’)
図 202. 問合せ
112
IBM Informix SQL ガイド: チュートリアル
customer_num called
106
110
119
121
127
06/12/1998
07/07/1998
07/01/1998
07/10/1998
07/31/1998
resolved
06/12/1998
07/07/1998
07/02/1998
07/10/1998
図 203. 問合せ結果
TO_CHAR 関数の使用
TO_CHAR 関数は、日時 (DATETIME) 型値または日付 (DATE) 型値を文字列に変換し
ます。TO_CHAR 関数は、指定したデータの形式ディレクティブに従って日時
(DATETIME) 型値を評価し、各国語可変長文字 (NVARCHAR) 型値を戻します。サポー
トされるデータの形式ディレクティブのリストが必要な場合は、「IBM Informix: GLS
ユーザーズ ガイド」の GL_DATETIME 環境変数の説明を参照してください。
TO_CHAR 関数を使用して、日時 (DATETIME) 型値または日付 (DATE) 型値をラージ
可変長文字 (LVARCHAR) 型値に変換することもできます。
図 204 では、TO_CHAR 関数を使用して、日時 (DATETIME) 型値をより読みやすい文
字列に変換します。
SELECT customer_num,
TO_CHAR(call_dtime, "%A %B %d %Y") call_date
FROM cust_calls
WHERE call_code = "B"
図 204. 問合せ
customer_num 119
call_date
Friday July 01 1998
図 205. 問合せ結果
図 206 では、TO_CHAR 関数を使用して、日付 (DATE) 型値をより読みやすい文字列
に変換します。
第 4 章 SELECT 文での関数の使用
113
SELECT order_num,
TO_CHAR(ship_date,"%A %B %d %Y") date_shipped
FROM orders
WHERE paid_date IS NULL
図 206. 問合せ
order_num
date_shipped
1004
Monday May 30 1998
order_num
date_shipped
1006
order_num
date_shipped
1007
Sunday June 05 1998
order_num
date_shipped
1012
Wednesday June 29 1998
order_num
date_shipped
1016
Tuesday July 12 1998
order_num
date_shipped
1017
Wednesday July 13 1998
図 207. 問合せ結果
TO_DATE 関数の使用
TO_DATE 関数は、文字 (CHAR) 型データの引数を受け入れ、この値を日時
(DATETIME) 型値に変換します。TO_DATE 関数は、指定された日付形式に従って文字
列を評価し、日時 (DATETIME) 型値を戻します。サポートされるデータの形式ディレ
クティブのリストが必要な場合は、「IBM Informix: GLS ユーザーズ ガイド」の
GL_DATETIME 環境変数の説明を参照してください。
TO_DATE 関数を使用して、ラージ可変長文字 (LVARCHAR) 型値を日時
(DATETIME) 型値に変換することもできます。
図 208 では、TO_DATE 関数を使用して、文字列値を、形式を指定した日時
(DATETIME) 型値に変換します。
114
IBM Informix SQL ガイド: チュートリアル
SELECT customer_num, call_descr
FROM cust_calls
WHERE call_dtime = TO_DATE("1998-07-07 10:24",
"%Y-%m-%d %H:%M").
図 208. 問合せ
customer_num
110
call_descr
Order placed one month ago (6/7) not received.
図 209. 問合せ結果
DATE または TO_DATE 関数を使用して、文字列を日付 (DATE) 型値に変換できま
す。TO_DATE 関数を使用する利点の 1 つは、戻される値の形式を指定できることで
す。(常に日時 (DATETIME) 型値を戻す TO_DATE 関数を使用し、文字列を日付
(DATE) 型値に変換できます。これは、日付 (DATE) 型値と日時 (DATETIME) 型値間
の変換を、データベース サーバが暗黙的に処理しているためです。)
図 210 では、TO_DATE 関数を使用して、文字列値を、形式を指定した日付 (DATE)
型値に変換します。
SELECT order_num, paid_date
FROM orders
WHERE order_date = TO_DATE("6/7/98", "%m/%d/%iY")
図 210. 問合せ
order_num
paid_date
1008
07/21/1998
図 211. 問合せ結果
計数関数 (IDS)
CARDINALITY 関数は、コレクション (COLLECTION) 型の要素数をカウントしま
す。CARDINALITY 関数は、単純コレクション (COLLECTION) 型または入れ子コレ
クション (COLLECTION) 型に使用できます。コレクション (COLLECTION) 型データ
内に重複している要素がある場合、それらは別々の要素としてカウントされます。図
第 4 章 SELECT 文での関数の使用
115
212 では、表 manager の行ごとに、department の値と各コレクション
(COLLECTION) 型 direct_reports に含まれる要素数が戻されます。
SELECT department, CARDINALITY(direct_reports) FROM manager
図 212. 問合せ
department
marketing 5
department
engineering 7
department
publications 4
department
accounting 3
図 213. 問合せ結果
図 214 に示すように、述部式の中からコレクション (COLLECTION) 型に含まれている
要素数を評価することもできます。
SELECT department, CARDINALITY(direct_reports) FROM manager
WHERE CARDINALITY(direct_reports) < 6
GROUP BY department
図 214. 問合せ
department
accounting 3
department
marketing 5
department
publications 4
図 215. 問合せ結果
スマート ラージ オブジェクト関数 (IDS)
データベース サーバには、SQL 文の中から呼び出せ、スマート ラージ オブジェクト
をインポートまたはエクスポートすることができる 4 つの SQL 関数があります。 117
ページの表 4 にスマート ラージ オブジェクト関数を示します。
116
IBM Informix SQL ガイド: チュートリアル
表 4. スマート ラージ オブジェクト用の SQL 関数
関数名
内容
FILETOBLOB()
ファイルを BLOB 型列にコピーする
FILETOCLOB()
ファイルを CLOB 型列にコピーする
LOCOPY()
BLOB 型または CLOB 型データを他の BLOB 型または CLOB 型
列にコピーする
LOTOFILE()
BLOB 型データまたは CLOB 型データをファイルにコピーする
スマート ラージ オブジェクト関数の詳細および構文については、「IBM Informix: SQL
ガイド: 構文」の式セグメントを参照してください。
表 4 に示す関数はいずれも、SELECT、UPDATE、および INSERT 文で使用できます。
これらの関数を INSERT 文および UPDATE 文で使用する例は、 183 ページの『第 6
章 データの変更』に記載されています。
図 216 に示すように、表 inmate と表 fbi_list を作成すると仮定します。
CREATE TABLE inmate
(
id_num
INT,
picture BLOB,
felony
CLOB
)
CREATE TABLE fbi_list
(
id
INTEGER,
mugshot BLOB
) PUT mugshot IN (sbspace1)
図 216.
次の SELECT 文では、LOTOFILE() 関数を使用して、クライアント コンピュータにあ
るファイル felon_322.txt に列 felony のデータをコピーします。
SELECT id_num, LOTOFILE(felony, ’felon_322.txt’, ’client’)
FROM inmate
WHERE id = 322
LOTOFILE() の 1 つ目の引数には、データのエクスポート元である列の名前を指定し
ます。2 つ目の引数は、データのコピー先のファイル名にします。3 つ目の引数では、
コピー先ファイルがクライアント コンピュータ (’client’) とサーバ コンピュータ
(’server’) のどちらに置かれているのかを指定します。
第 4 章 SELECT 文での関数の使用
117
関数の引数でファイル名のパス指定をする場合、クライアント コンピュータとサーバ
コンピュータのどちらにそのファイルがあるかによって、次のいずれかのルールが適用
されます。
v ソース ファイルがサーバ コンピュータに存在する場合は、現在の作業ディレクトリ
への相対パス名ではなく、そのファイルへのフルパス名を指定する必要があります。
v ソース ファイルがクライアント コンピュータに存在する場合は、そのファイルへの
フルパス名または相対パス名のどちらでも指定することができます。
文字列操作関数 (IDS)
文字列操作関数は、文字 (CHAR) 型、各国語文字 (NCHAR) 型、可変長文字
(VARCHAR) 型、各国語可変長文字 (NVARCHAR) 型、およびラージ可変長文字
(LVARCHAR) 型の引数を受け入れます。文字列操作関数は、式を使用する部分ならど
こででも使用することができます。
次の関数を使用すると、文字列の大文字と小文字の間の変換が行われます。
v LOWER
v UPPER
v INITCAP
次の関数は、いろいろな方法で文字列を操作します。
v REPLACE
v SUBSTR
v SUBSTRING
v LPAD
v RPAD
文字列操作関数をオーバーロードして、拡張データ型を処理することはできません。
LOWER 関数の使用
LOWER 関数を使用すると、文字列内にある大文字がすべて小文字に置き換えられま
す。LOWER 関数は文字 (CHAR) 型データの引数を受け入れ、指定された引数と同じ
データ型の値を戻します。
図 217 では、LOWER 関数を使用して、文字列内のすべての大文字を小文字に変換し
ます。
118
IBM Informix SQL ガイド: チュートリアル
SELECT manu_code, LOWER(manu_code)
FROM items
WHERE order_num = 1018
図 217. 問合せ
manu_code
PRC
KAR
PRC
SMT
HRO
(expression)
prc
kar
prc
smt
hro
図 218. 問合せ結果
UPPER 関数の使用
UPPER 関数を使用すると、文字列内にある小文字がすべて大文字に置き換えられま
す。UPPER 関数は文字 (CHAR) 型データの引数を受け入れ、指定された引数と同じデ
ータ型の値を戻します。
図 219 では、UPPER 関数を使用して、文字列内のすべての小文字を大文字に変換しま
す。
SELECT call_code, UPPER(code_descr) FROM call_type
図 219. 問合せ
call_code
(expression)
B
D
I
L
O
BILLING ERROR
DAMAGED GOODS
INCORRECT MERCHANDISE SENT
LATE SHIPMENT
OTHER
図 220. 問合せ結果
第 4 章 SELECT 文での関数の使用
119
INITCAP 関数の使用
INITCAP 関数を使用すると、文字列にあるすべての語の先頭文字が大文字に置き換え
られます。INITCAP 関数は、英文字以外の文字が前にある文字を検出すると、これを
新しい語であるとみなします。INITCAP 関数は文字 (CHAR) 型データの引数を受け入
れ、指定された引数と同じデータ型の値を戻します。
図 221 では、INITCAP 関数を使用して、文字列内のすべての語の先頭文字を大文字に
変換します。
SELECT INITCAP(description) FROM stock
WHERE manu_code = "ANZ"
図 221. 問合せ
(expression)
Tennis Racquet
Tennis Ball
Volleyball
Volleyball Net
Helmet
Golf Shoes
3 Golf Balls
Running Shoes
Watch
Kick Board
Swim Cap
図 222. 問合せ結果
REPLACE 関数の使用
REPLACE 関数を使用すると、文字列にある特定の文字の集合が別の文字に置き換えら
れます。
図 223 では、REPLACE 関数を使用して、問合せで戻されるすべての行に関して、unit
列の値 each を item に置き換えます。REPLACE 関数の最初の引数は、評価する式で
す。2 番目の引数は、他のものに置き換えられる文字列を指定します。3 番目の引数
は、置き換えられる文字列に代わる新しい文字列を指定します。
120
IBM Informix SQL ガイド: チュートリアル
SELECT stock_num, REPLACE(unit,"each", "item") cost_per,
unit_price
FROM stock
WHERE manu_code = "HRO"
図 223. 問合せ
stock_num
cost_per
1
2
4
7
110
205
301
302
304
305
309
312
case
case
case
case
case
case
item
item
box
case
case
box
unit_price
$250.00
$126.00
$480.00
$600.00
$260.00
$312.00
$42.50
$4.50
$280.00
$48.00
$40.00
$72.00
図 224. 問合せ結果
SUBSTRING 関数と SUBSTR 関数の使用
SUBSTRING 関数および SUBSTR 関数を使用して、文字列の一部を戻すことができま
す。文字列の中でこの関数が戻す部分を示すため、開始位置 と長さ (オプション) を指
定します。
SUBSTRING 関数の使用
SUBSTRING 関数を使用して、文字列の一部を戻すことができます。文字列の中でこの
関数が戻す部分を示すため、開始位置 と長さ (オプション) を指定します。開始位置
は、正数または負数で指定できます。開始位置 1 は、SUBSTRING 関数が文字列の最
初から戻し始めることを示します。開始位置がゼロ (0) または負数の場合は、
SUBSTRING 関数は文字列の先頭から後方に数えます。
図 225 に、SUBSTRING 関数の例を示します。ここでは、問合せが戻すすべての列
sname の値の先頭 4 文字が戻されます。この例では、SUBSTRING 関数は文字列の先
頭から開始し、開始位置から数えて 4 文字を戻します。
第 4 章 SELECT 文での関数の使用
121
SELECT sname, SUBSTRING(sname FROM 1 FOR 4) FROM state
WHERE code = "AZ"
図 225. 問合せ
sname
(expression)
Arizona
Ariz
図 226. 問合せ結果
図 227 では、SUBSTRING 関数に、開始位置 6 が指定されていますが、長さは指定さ
れていません。この関数は、6 番目の位置からその文字列の最後までの文字列を戻しま
す。
SELECT sname, SUBSTRING(sname FROM 6) FROM state
WHERE code = "WV"
図 227. 問合せ
sname
(expression)
West Virginia
Virginia
図 228. 問合せ結果
図 229 では、SUBSTRING 関数により、問合せが戻したすべての sname 列値につい
て、最初の文字のみが戻されます。SUBSTRING 関数では、開始位置が -2 のときは、
文字列の開始位置から位置が 3 つ (0、-1、-2) 後方に戻されます。開始位置が 0 のと
きは、文字列の先頭から位置が 1 つだけ戻されます。
SELECT sname, SUBSTRING(sname FROM -2 FOR 4) FROM state
WHERE code = "AZ"
図 229. 問合せ
122
IBM Informix SQL ガイド: チュートリアル
sname
(expression)
Arizona
A
図 230. 問合せ結果
SUBSTR 関数の使用
SUBSTR 関数は、SUBSTRING 関数を同じ機能を持ちますが、構文に違いがありま
す。
文字列の中で SUBSTR 関数が戻す部分を示すため、開始位置 と長さ (オプション) を
指定します。SUBSTR 関数の開始位置は、正数または負数で指定できます。ただし、開
始位置に負数が指定された場合、SUBSTR 関数はそれを SUBSTRING 関数とは異なる
方法で扱います。開始位置が負数の場合、SUBSTR 関数は文字列の最後から先頭に向か
ってカウントします。これは文字列の長さに依存し、語の文字の長さ、または文字列に
含まれている目に見える文字の長さには影響されません。SUBSTR 関数は、ゼロ (0) ま
たは 1 が開始位置に指定された場合、文字列の最初から戻し始めます。
図 231 に、開始位置に負数を指定した場合の SUBSTR 関数の例を示します。開始位置
が -15 なので、SUBSTR 関数は文字列の最後から先頭方向に 15 カウントして開始位
置を検出し、そこから 5 文字を戻します。
SELECT sname, SUBSTR(sname, -15, 5) FROM state
WHERE code = "CA"
図 231. 問合せ
sname
(expression)
California
Calif
図 232. 問合せ結果
開始位置に負数を使用するには、評価される値の長さを知っている必要があります。列
sname は CHAR(15) として定義されているため、sname の型の引数をとる SUBSTR
関数では、文字列の先頭から始まる文字列を戻すには、関数の開始位置に 0、1、または
-15 を使用します。
第 4 章 SELECT 文での関数の使用
123
図 233 は、図 231 と同じ結果を戻します。
SELECT sname, SUBSTR(sname, 1, 5) FROM state
WHERE code = "CA
図 233. 問合せ
LPAD 関数の使用
LPAD 関数を使用すると、ある文字の連続を左にパッドした文字列のコピーが戻されま
す。この文字の連続は、文字列のパッド部分の指定された長さに応じて、必要な回数だ
け反復されるか、または切り捨てられます。ソース文字列、戻される文字列の長さ、お
よびパッドする文字列を指定してください。
ソース文字列およびパッドする文字列のデータ型は、可変長文字 (VARCHAR) 型または
各国語可変長文字 (NVARCHAR) 型に変換できるデータ型ならどれでも構いません。
図 234 に、長さを 21 バイトに指定した場合の LPAD 関数の例を示します。sname が
CHAR(15) として定義されており、ソース文字列の長さが 15 バイトになるため、
LPAD 関数はソース文字列の左側へ先頭から 6 バイト分だけパッドを行います。
SELECT sname, LPAD(sname, 21, "-")
FROM state
WHERE code = "CA" OR code = "AZ"
図 234. 問合せ
sname
(expression)
California
Arizona
------California
------Arizona
図 235. 問合せ結果
RPAD 関数の使用
RPAD 関数を使用すると、ある文字の連続を右にパッドした文字列のコピーが戻されま
す。この文字の連続は、文字列のパッド部分の指定された長さに応じて、必要な回数だ
け反復されるか、または切り捨てられます。ソース文字列、戻される文字列の長さ、お
よびパッドする文字列を指定してください。
124
IBM Informix SQL ガイド: チュートリアル
ソース文字列およびパッドする文字列のデータ型は、可変長文字 (VARCHAR) 型または
各国語可変長文字 (NVARCHAR) 型に変換できるデータ型ならどれでも構いません。
図 236 に、長さを 21 バイトに指定した場合の RPAD 関数の例を示します。sname が
CHAR(15) として定義されており、ソース文字列の長さが 15 バイトになるため、
RPAD 関数はソース文字列の右側へ先頭から 6 バイト分だけパッドします。
SELECT sname, RPAD(sname, 21, "-")
FROM state
WHERE code = "WV" OR code = "AZ"
図 236. 問合せ
sname
West Virginia
Arizona
(expression)
West Virginia -----Arizona
------
図 237. 問合せ結果
その他の関数
LENGTH、USER、CURRENT、および TODAY 関数を、定数を使用する SQL 式の任
意の位置に使用できます。また、DBSERVERNAME 関数を SELECT 文に含めて、現
行データベースが常駐するデータベース サーバの名前を表示することができます。
これらの関数を使用すると、定数値から構成されている関数式または列データを含む関
数式を選択することができます。最初の例では、すべての行において同じ結果が出力さ
れます。
また、HEX 関数で関数式を 16 進数に符号化した結果を戻したり、ROUND 関数で四
捨五入した関数式の値を戻したり、TRUNC 関数で切り詰めた関数式の値を戻すことが
できます。これらの関数の詳細については、「IBM Informix: SQL ガイド: 構文」を参
照してください。
LENGTH 関数の使用
図 238 では、company の長さが 15 より長い場合、LENGTH 関数で各行において
fname と lname を結合した列のバイト数を計算します。
第 4 章 SELECT 文での関数の使用
125
SELECT customer_num,
LENGTH (fname) + LENGTH (lname) namelength
FROM customer
WHERE LENGTH (company) > 15
図 238. 問合せ
customer_num
namelength
101
105
107
112
115
118
119
120
122
124
125
126
127
128
11
13
11
14
11
10
10
10
12
11
10
12
10
11
図 239. 問合せ結果
DB–Access 使用する場合はあまり役立ちませんが、LENGTH 関数は、プログラムおよ
びレポートの文字列の長さを決定するときに重要な役割を果たす場合があります。
LENGTH 関数は、文字 (CHARACTER) 型または可変長文字 (VARCHAR) 型文字列の
クリップされた長さを戻し、テキスト (TEXT) 型またはバイト (BYTE) 型文字列の完全
なバイト数を戻します。
USER 関数の使用
USER 関数を使用して、ユーザのユーザ ID を含む行のみで構成された表の制限付きビ
ューを定義できます。ビューの作成方法については、「IBM Informix: データベース設計
および実装 ガイド」と、「IBM Informix: SQL ガイド: 構文」の GRANT および
CREATE VIEW 文を参照してください。
図 240 では、問合せを実行するユーザのユーザ名 (ログイン アカウント名) を戻しま
す。この問合せは、表内の各行に対して 1 回行われます。
126
IBM Informix SQL ガイド: チュートリアル
SELECT * FROM cust_calls
WHERE user_id = USER
図 240. 問合せ
現行ユーザのユーザ名が richc の場合、図 240 は、表 cust_calls 内で user_id = richc
である行のみを抽出します。結果を 図 241 に示します。
customer_num
call_dtime
user_id
call_code
call_descr
res_dtime
res_descr
110
1998-07-07 10:24
richc
L
Order placed one month ago (6/7) not received.
1998-07-07 10:30
Checked with shipping (Ed Smith). Order sent yesterday-we
were waiting for goods from ANZ. Next time will call with
delay if necessary
customer_num
call_dtime
user_id
call_code
call_descr
res_dtime
res_descr
119
1998-07-01 15:00
richc
B
Bill does not reflect credit from previous order
1998-07-02 08:21
Spoke with Jane Akant in Finance. She found the error and is
sending new bill to customer
図 241. 問合せ結果
TODAY 関数の使用
TODAY 関数は、現行システム日付を戻します。現在のシステム日付が 1998 年 7 月
10 日の場合に図 242 を使用すると、次の 1 行が戻されます。
SELECT * FROM orders WHERE order_date = TODAY
図 242. 問合せ
第 4 章 SELECT 文での関数の使用
127
order_num
order_date
customer_num
ship_instruct
backlog
po_num
ship_date
ship_weight
ship_charge
paid_date
1018
07/10/1998
121
SW corner of Biltmore Mall
n
S22942
07/13/1998
70.50
$20.00
08/06/1998
図 243. 問合せ結果
DBSERVERNAME 関数と SITENAME 関数の使用
DBSERVERNAME 関数 (またはそのシノニムである SITENAME 関数) を SELECT 文
で使用し、データベース サーバの名前を検索できます。行を持つ表 (システム カタロ
グ表など) の DBSERVERNAME について問合せを実行することができます。
図 244 では、ラベル server を DBSERVERNAME 関数式に設定し、列 tabid をシステ
ム カタログ表 systables から選択します。この表がデータベース表であり、tabid はこ
の表の識別子です。
SELECT DBSERVERNAME server, tabid
FROM systables
WHERE tabid <= 4
図 244. 問合せ
server
montague
montague
montague
montague
tabid
1
2
3
4
図 245. 問合せ結果
WHERE 節では、表示する行数を制限します。制限をしない場合には、データベース サ
ーバ名が表 systables の行ごとに 1 回ずつ表示されます。
128
IBM Informix SQL ガイド: チュートリアル
HEX 関数の使用
図 246 では、HEX 関数を使用して、表 customer の 2 つの列の 16 進形式を戻しま
す。この結果を図 247 に示します。
SELECT HEX (customer_num) hexnum, HEX (zipcode) hexzip
FROM customer
図 246. 問合せ
hexnum
hexzip
0x00000065
0x00000066
0x00000067
0x00000068
0x00000069
0x0000006A
..
.
0x00016F86
0x00016FA5
0x0001705F
0x00016F4A
0x00016F46
0x00016F6F
図 247. 問合せ結果
DBINFO 関数の使用
DBINFO 関数を SELECT 文で使用し、以下の情報を検索できます。
v 表領域番号または式に対応する DB 領域の名前
v 表に挿入された最新のシリアル値
v 選択、挿入、削除、更新、および実行のルーチン文により処理された行の数
v 現行セッションのセッション ID
v データベース サーバを実行しているホスト コンピュータの名前
v クライアント アプリケーションの接続先となるデータベース サーバの正確なバージ
ョン
DBINFO 関数は、SQL 文および SPL ルーチン内の任意の位置で使用できます。
図 248 に、DBINFO 関数を使用して、データベース サーバを実行しているホスト コ
ンピュータの名前を抽出する方法を示します。
SELECT FIRST 1 DBINFO(’dbhostname’) FROM systables
図 248. 問合せ
第 4 章 SELECT 文での関数の使用
129
(constant)
lyceum
図 249. 問合せ結果
tabid の値を制約する FIRST 1 節がない場合、表 systables の行ごとにデータベース サ
ーバが稼動するコンピュータのホスト名が繰り返されます。図 250 では、DBINFO 関数
を使用して、現行データベース サーバの完全なバージョン番号および型を検出します。
SELECT FIRST 1 DBINFO(’version’,’full’) FROM systables
図 250. 問合せ
DBINFO 関数を使用して、現行データベース サーバ、データベース セッション、また
はデータベースに関する情報を検出する方法の詳細については、「IBM Informix: SQL
ガイド: 構文」を参照してください。
DECODE 関数の使用
DECODE 関数は、式の 1 つの値を別の値に変換します。DECODE 関数には、以下の
フォームがあります。
DECODE(test, a, a_value, b, b_value, ..., n, n_value, exp_m )
DECODE は、a が test と等しい場合 a_value を戻し、b が test と等しい場合 b_value
を戻し、n が test と等しい場合に n_value を戻します。
複数の式が test と一致した場合は、DECODE は最初に一致した式に対して n_value を
戻します。test と一致する式がない場合は、DECODE は exp_m を戻します。test と一
致する式がなく、exp_m がない場合は、DECODE は NULL を戻します。
DECODE 関数は、テキスト (TEXT) 型とバイト (BYTE) 型の引数を受け入れません。
列 emp_id と列 evaluation を含む表 employee があるとします。表 employee に対し
て図 251 を実行したところ、図 252 に示す行が戻されたと仮定します。
SELECT emp_id, evaluation FROM employee
図 251. 問合せ
130
IBM Informix SQL ガイド: チュートリアル
emp_id
evaluation
012233
012344
012677
012288
012555
great
poor
NULL
good
very good
図 252. 問合せ結果
場合によっては、値のセットの変換が必要になります。例えば、前の例の列 evaluation
の記述値を、対応する数値に変換する必要があるとします。図 253 に、DECODE 関数
を使用して列 evaluation の値を、表 employee の各行について、数値に変換する方法を
示します。
SELECT emp_id, DECODE(evaluation, "poor", 0, "fair", 25, "good",
50, "very good", 75, "great", 100, -1) AS evaluation
FROM employee
図 253. 問合せ
emp_id
evaluation
012233
012344
012677
012288
012555
..
.
100
0
-1
50
75
図 254. 問合せ結果
DECODE 関数の引数は、次の要件を満たす場合は任意のデータ型を指定できます。
v 引数 test, a,b, ..., n はすべて同じデータ型を持ち、共通互換データ型として評価され
ます。
v 引数 a_value, b_value, ..., n_value はすべて同じデータ型を持ち、共通互換データ型
として評価されます。
NVL 関数の使用 (IDS)
NVL 関数は、NULL と評価された式を、ユーザが指定する値に変換します。NVL 関数
は、2 種類の引数を受け入れます。最初の引数は、評価される式の名前です。2 番目の
引数は、最初の引数が NULL と評価されたときに関数が戻す値です。最初の引数が
NULL と評価されない場合、関数は最初の引数の値を戻します。例えば列 name と列
第 4 章 SELECT 文での関数の使用
131
address を含む表 student があるとします。また、表 student に対して図 255 を実行し
た場合、図 256 に示す行が戻されるとします。
SELECT name, address FROM student
図 255. 問合せ
name
address
John Smith
Lauren Collier
Fred Frith
Susan Jordan
333 Vista Drive
1129 Greenridge Street
NULL
NULL
図 256. 問合せ結果
図 257 には NVL 関数が含まれています。これにより、列 address に NULL 値が含ま
れる表の各行について新しい値が戻されます。
SELECT name, NVL(address, "address is unknown") AS address
FROM student
図 257. 問合せ
name
address
John Smith
Lauren Collier
Fred Frith
Susan Jordan
333 Vista Drive
1129 Greenridge Street
address is unknown
address is unknown
図 258. 問合せ結果
NVL 関数の 2 つの引数が共通互換データ型であると評価するなら、これらの引数に任
意のデータ型を指定できます。
NVL 関数の両方の引数が NULL と評価される場合、NULL が戻されます。
SELECT 文での SPL ルーチンの使用
この章では、列名、演算子、および SQL 関数で構成される SELECT 文式に関する例を
示してきました。ここでは、SPL ルーチン呼出しを含む式について説明します。
132
IBM Informix SQL ガイド: チュートリアル
SPL ルーチンは、SQL 文とともに、特殊なストアド プロシジャ言語 (SPL) 文を含みま
す。SPL ルーチンの詳細については、第 11 章を参照してください。
Dynamic Server
Dynamic Server では、C 言語および Java 言語で外部ルーチンを作成できます。詳しく
は、「IBM Informix: ユーザ定義ルーチンおよびデータ タイプ 開発者ガイド」を参照し
てください。
Dynamic Server の終り
SPL ルーチン式を射影リストに含める場合は、単一値 (1 行で 1 列) を戻す SPL ルー
チンでなければなりません。例えば、次の文は、test_func() が単一値を戻す場合にのみ
有効です。
SELECT col_a, test_func(col_b) FROM tab1
WHERE col_c = "Davis"
複数の値を戻す SPL ルーチンは、SELECT 文の Projection 節でサポートされません。
上記の例では、test_func() が複数の値を戻すと、データベース サーバからエラー メッ
セージが戻されます。
SPL ルーチンを使用すると、関数の使用範囲を拡張できます。すなわち選択する各行に
ついて副問合せを実行することができます。
例えば、顧客番号、顧客の姓、顧客からの注文数をリストすると仮定します。図 259
は、この情報を抽出する方法の 1 つを示しています。表 customer には、列
customer_num と lname がありますが、各顧客の注文数の記録はありません。各
customer_num について表 orders に問合せを行い、 n_orders というラベルが付いた対
応する注文の数を戻す get_orders というルーチンを作成することができます。
SELECT customer_num, lname, get_orders(customer_num) n_orders
FROM customer
図 259. 問合せ
図 260 に、この SPL ルーチンの結果を示します。
第 4 章 SELECT 文での関数の使用
133
customer_num
lname
n_orders
101
102
103
104
Pauli
Sadler
Currie
Higgins
1
9
9
4
123
124
125
126
127
128
Hanlon
Putnum
Henry
Neelie
Satifer
Lessor
1
1
0
1
1
0
..
.
図 260. 問合せ結果
SPL ルーチンを使用して、問合せの中で実行回数の多い演算をカプセル化します。例え
ば、図 261 の条件には、在庫品の単価を別の通貨に換算し、輸入関税を加えるルーチン
conv_price が含まれています。
SELECT stock_num, manu_code, description FROM stock
WHERE conv_price(unit_price, ex_rate = 1.50,
tariff = 50.00) < 1000
図 261. 問合せ
データ暗号化関数の使用 (IDS)
Advanced Encryption Standard (AES) および Triple DES (3DES) 暗号化を使用する組込
み SQL 暗号化関数を SET ENCRYPTION PASSWORD 文で使用して、機密データを保
護できます。暗号化を使用すると、正しいパスワードを知るユーザのみがデータの読取
り、コピー、または変更を実行できます。
SET ENCRYPTION PASSWORD 文で、次の組込み暗号化関数および復号化関数を使用
します。
v ENCRYPT_AES
ENCRYPT_AES(data-string-expression
[, password-string-expression [, hint-string-expression ]])
v ENCRYPT_TDES
ENCRYPT_TDES (data-string-expression
[, password-string-expression [, hint-string-expression ]])
134
IBM Informix SQL ガイド: チュートリアル
v DECRYPT_CHAR
DECRYPT_CHAR(EncryptedData [, PasswordOrPhrase])
v DECRYPT_BINARY
DECRYPT_BINARY(EncryptedData [, PasswordOrPhrase])
v GETHINT
GETHINT(EncryptedData)
ENCRYPT_AES と ENCRYPT_TDES は、暗号化されたデータの定義に使用し、
DECRYPT_CHAR と DECRYPT_BINARY は、暗号化されたデータの問合せに使用し
ます。GETHINT は、サーバ上でパスワード ヒント文字列の表示に使用します (設定さ
れている場合)。
これらの SQL 組込み関数を使用して、列レベルまたはセル レベルの暗号化を実装でき
ます。
v 列レベルの暗号化は、指定された列内のすべての値を同じパスワードを使用して暗号
化する場合に使用します。
v セル レベルの暗号化は、列内のデータを異なるパスワードを使用して暗号化する場
合に使用します。
次の例では、列レベルの暗号化を使用してクレジット カードのデータを保護していま
す。
列レベルのデータ暗号化を使用してクレジット カードのデータを保護するには:
1. 表を作成します。
create table customer (id char(30), creditcard lvarchar(67));
2. 暗号化データを挿入します。
a. セッション パスワードを設定します。
SET ENCRYPTION PASSWORD "credit card number is encrypted";
b. データを暗号化します。
INSERT INTO customer VALUES
("Alice", encrypt_aes("1234567890123456"));
INSERT INTO customer VALUES
("Bob", encrypt_aes("2345678901234567"));
3. 復号化関数を使用して、暗号化データを問合せます。
SET ENCRYPTION PASSWORD "credit card number is encrypted";
SELECT id FROM customer
WHERE DECRYPT_CHAR(creditcard) = "2345678901234567"
暗号化によるセキュリティの詳細については、「IBM Informix: Dynamic Server 管理者
ガイド」を参照してください。
第 4 章 SELECT 文での関数の使用
135
組込み暗号化関数および組込み復号化関数の詳細については、「IBM Informix: SQL ガ
イド: 構文」を参照してください。
サマリ
この章では、リレーショナル データベースへの問合せ、および戻されたデータの操作に
使用する、基本的な SELECT 文内の関数の構文例と、その出力結果を紹介しました。
100 ページの『SELECT 文での関数の使用』には、以下のアクションを実行する方法に
ついて記載しています。
v Projection 節で集計関数を使用して、特定のデータの計算と検索を行う。
v SELECT 文で、時刻関数 DATE、DAY、MDY、MONTH、WEEKDAY、YEAR、
CURRENT、および EXTEND のほかに TODAY、LENGTH、および USER を使用
する。
v SELECT 節で変換関数を使用して、日付値と文字値との間で変換を行う。
v SELECT 節で文字列操作関数を使用して、大文字と小文字の変換や文字列に対してさ
まざまな操作を行う。
132 ページの『SELECT 文での SPL ルーチンの使用』には、SELECT 文に SPL ルー
チンを含める方法を記載しています。
134 ページの『データ暗号化関数の使用 (IDS)』は、SET ENCRYPTION 文、組込み暗
号化関数、および復号化関数を使用することで、パスワードを付与されていないユーザ
による機密データの表示または変更を防ぐ方法について示しています。
136
IBM Informix SQL ガイド: チュートリアル
第 5 章 高度な SELECT 文の作成
GROUP BY 節と HAVING 節の使用 . . . . . . . . . . . . . . .
GROUP BY 節の使用方法 . . . . . . . . . . . . . . . . . .
HAVING 節の使用方法 . . . . . . . . . . . . . . . . . . .
高度な結合の作成 . . . . . . . . . . . . . . . . . . . . .
セルフ結合 . . . . . . . . . . . . . . . . . . . . . . .
外部結合 . . . . . . . . . . . . . . . . . . . . . . .
外部結合構文の Informix 拡張 . . . . . . . . . . . . . . .
ANSI 結合構文 . . . . . . . . . . . . . . . . . . . .
左外部結合 . . . . . . . . . . . . . . . . . . . . . .
右外部結合 (IDS) . . . . . . . . . . . . . . . . . . . .
単純結合 . . . . . . . . . . . . . . . . . . . . . .
2 つの表の単純な外部結合 . . . . . . . . . . . . . . . .
第 3 の表に対する単純結合との外部結合 . . . . . . . . . . . .
第 3 の表に対する 2 つの表の外部結合 . . . . . . . . . . . .
外部結合を組み合わせる結合 . . . . . . . . . . . . . . . .
SELECT 文の副問合せ . . . . . . . . . . . . . . . . . . . .
相関副問合せ . . . . . . . . . . . . . . . . . . . . . .
SELECT 文の副問合せ . . . . . . . . . . . . . . . . . . .
Projection 節での副問合せ . . . . . . . . . . . . . . . . . .
WHERE 節の中の副問合せ . . . . . . . . . . . . . . . . .
ALL の使用 . . . . . . . . . . . . . . . . . . . . .
ANY の使用 . . . . . . . . . . . . . . . . . . . . .
一価副問合せ . . . . . . . . . . . . . . . . . . . . .
相関副問合せ . . . . . . . . . . . . . . . . . . . . .
EXISTS の使用 . . . . . . . . . . . . . . . . . . . .
SELECT 文でのコレクションの処理 (IDS) . . . . . . . . . . . . .
コレクション (COLLECTION) 型副問合せ . . . . . . . . . . . .
コレクション (COLLECTION) 型の副問合せでのキーワード ITEM の省略
コレクション (COLLECTION) 型の副問合せでのキーワード ITEM の指定
コレクション (COLLECTION) 型導出表 . . . . . . . . . . . . .
集合演算 . . . . . . . . . . . . . . . . . . . . . . . .
和集合 . . . . . . . . . . . . . . . . . . . . . . . .
UNION と ORDER BY の使用 . . . . . . . . . . . . . . .
UNION ALL の使用 . . . . . . . . . . . . . . . . . . .
異なる列名の使用 . . . . . . . . . . . . . . . . . . .
複数の表に対する UNION の使用 . . . . . . . . . . . . . .
Projection 節でのリテラルの使用. . . . . . . . . . . . . . .
FIRST 節の使用 . . . . . . . . . . . . . . . . . . . .
積. . . . . . . . . . . . . . . . . . . . . . . . . .
差. . . . . . . . . . . . . . . . . . . . . . . . . .
© Copyright IBM Corp. 1996, 2004
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
138
139
142
145
145
148
149
150
150
152
152
153
154
155
156
157
157
158
158
159
160
161
161
162
164
167
167
168
168
169
171
171
173
174
175
176
177
178
179
180
137
サマリ .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 181
本章について
この章では、SELECT 文の範囲を広げて、さらに複雑なデータベースの問合せとデータ
操作を実行できるようにします。17 ページの『第 2 章 SELECT 文の作成』では、
SELECT 構文で使用する 5 つの節について説明しましたが、この章では、さらに
GROUP BY 節と HAVING 節について説明します。GROUP BY 節は、集計関数ととも
に使用することで、FROM 節に戻された行を編成することができます。また、HAVING
節を使用して、GROUP BY 節が戻した値に条件を設定することができます。
この章では、結合についての説明の範囲を前よりも広げます。表をその表自体に結合で
きるようにするセルフ結合、および複数の結合された表を平等に扱わないようにキーワ
ード OUTER を使用する 4 種類の外部結合 について、例をあげて説明します。また、
その他にも、相関/非相関副問合せとその操作キーワード、演算子 UNION を使用して問
合せを結合する方法を説明し、集合演算の和、積、差を定義します。
この章では例を使用して、問合せのときの一部またはすべての SELECT 文の節の使用
方法を説明します。各節は必ず次の順序で指定してください。
1. FROM
2. WHERE
3. GROUP BY
4. HAVING
5. ORDER BY
6. INTO TEMP
これらすべての節を正しい順序で使用した SELECT 文の例を、144 ページの図 276に示
します。
もう 1 つの SELECT 文節 INTO では、SQL API でプログラムとホスト変数を指定で
きます。この節については、235 ページの『第 8 章 SQL を使用したプログラミング』
と、製品に付属した資料を参照してください。
GROUP BY 節と HAVING 節の使用
オプションの GROUP BY 節および HAVING 節を使用することで、SELECT 文に機能
を加えることができます。どちらか一方または両方を SELECT 文に記述すると、集計
関数をより高度に活用できます。
GROUP BY 節は、類似行を結合して、Projection 節内にリストされた各列について、同
じ値を持つ行のグループ ごとに結果行を 1 つ作成します。HAVING 節はこれらのグル
ープが形成された後に、条件を設定します。GROUP BY を使用して HAVING 節を省
略したり、HAVING 節を使用して GROUP BY 節を省略したりできます。
138
IBM Informix SQL ガイド: チュートリアル
GROUP BY 節の使用方法
GROUP BY 節は、表をいくつかのセットに分割します。この節は、それらのセットの
それぞれに対して要約値を作成する集計関数と組み合わせて使用されることが多くなっ
ています。第 2 章では、表全体に適用される集計関数の使用方法を例を用いて説明しま
した。この章では、行グループに適用される集計関数について説明します。
集計関数を使用しないで GROUP BY を使用した場合は、SELECT 節内でキーワード
DISTINCT (または UNIQUE) を使用した場合とほぼ同じことを意味します。図 262 の
説明は、30 ページの『特定の列の選択』に記載されています。
SELECT DISTINCT customer_num FROM orders
図 262. 問合せ
図 263 のように記述することもできます。
SELECT customer_num FROM orders
GROUP BY customer_num
図 263. 問合せ
図 262 と図 263 は、図 264 に示す行を戻します。
customer_num
101
104
106
110
..
.
124
126
127
図 264. 問合せ結果
GROUP BY 節は、収集した行をいくつかのセットにまとめて、各セット内のすべての
行で顧客番号が同じになるようにしています。何も列が選択されていないと、結果は一
意の customer_num の値のリストとして取り出されます。
GROUP BY 節は集計関数と一緒に使用するとその機能がよくわかります。
図 265 は、各注文についての品目数と各品目の合計金額を抽出します。
第 5 章 高度な SELECT 文の作成
139
SELECT order_num, COUNT (*) number, SUM (total_price) price
FROM items
GROUP BY order_num
図 265. 問合せ
GROUP BY 節を使用すると、表 items (注文品目) の行で、列 order_num (注文番号)
に同じ値を持つものを 1 つのグループとしてまとめます。つまり、各注文を構成する品
目を 1 グループとしてまとめます。データベース サーバがグループを形成した後で、
集計関数 COUNT および SUM が各グループに適用されます。
図 265 は、それぞれのグループごとに 1 行を戻します。COUNT および SUM 式の結
果に名前を付けるために、図 266 のようなラベルが使用されます。
order_num
number
price
1001
1002
1003
1004
1
2
3
4
$250.00
$1200.00
$959.00
$1416.00
1021
1022
1023
4
3
6
$1614.00
$232.00
$824.00
..
.
図 266. 問合せ結果
図 266 は items 表の行を注文番号が同じグループにまとめて、各グループの行の
COUNT および価格の合計金額を計算します。
GROUP BY 節には、テキスト (TEXT) 型、バイト (BYTE) 型、CLOB 型、および
BLOB 型列を指定できません。グループ化 するにはソート 可能である必要があります
が、これらのデータ型には、自然なソート順がありません。
ORDER BY 節とは異なり、GROUP BY 節はデータの並び替えを行いません。データを
特定の順序でソートするか、または射影リスト内の集合に基づいてソートする場合は、
ORDER BY 節を GROUP BY 節の後 に指定します。
図 267 は、ORDER BY 節を追加し、抽出した行を price に基づいて昇順にソートする
点以外は、図 265 と同じです。
140
IBM Informix SQL ガイド: チュートリアル
SELECT order_num, COUNT(*) number, SUM (total_price) price
FROM items
GROUP BY order_num
ORDER BY price
図 267. 問合せ
order_num
number
price
1010
1011
1013
1022
1001
1020
1006
2
1
4
3
1
2
5
$84.00
$99.00
$143.80
$232.00
$250.00
$438.00
$448.00
1002
1004
1014
1019
1021
1007
2
4
2
1
4
5
$1200.00
$1416.00
$1440.00
$1499.97
$1614.00
$1696.00
..
.
図 268. 問合せ結果
30 ページの『特定の列の選択』のセクションで説明しているように、ORDERBY 節で
整数を使用して、射影リスト内の列の位置を指定できます。GROUP BY 節でも同様
に、GROUP BY リスト内の列名や表示ラベルの位置を示すために整数を使用できま
す。
図 269 は、図 267 と同じ行を戻します。
SELECT order_num, COUNT(*) number, SUM (total_price) price
FROM items
GROUP BY 1
ORDER BY 3
図 269. 問合せ
問合せを作成する場合、Projection 節の射影リスト内にある集合以外のすべての列を
GROUP BY 節にも含める必要があります。SELECT 文で GROUP BY 節を使用する場
合は、グループあたり 1 行のみが戻される必要があるためです。GROUP BY節の後に
第 5 章 高度な SELECT 文の作成
141
指定されている行は、必ずグループ内の別個の値を 1 つのみ反映し、その値を戻すこと
ができます。ただし、GROUP BY の後に指定されていない列の値は、グループ内の各
行で異なる場合があります。
図 270 に示すように、表を結合する SELECT 文で GROUP BY 節を使用できます。
SELECT o.order_num, SUM (i.total_price)
FROM orders o, items i
WHERE o.order_date > ’01/01/98’
AND o.customer_num = 110
AND o.order_num = i.order_num
GROUP BY o.order_num
図 270. 問合せ
図 270 は、orders 表と items 表を結合して、これらに表の別名を付け、図 271 に示す
行を戻します。
order_num
(sum)
1008
1015
$940.00
$450.00
図 271. 問合せ結果
HAVING 節の使用方法
HAVING 節は、通常 GROUP BY 節を補足するために使用し、行がグループ化された
後で、グループに対し選択のための 1 つ以上の条件を適用します。HAVING 節がグル
ープに与える影響は、WHERE 節が各行を修飾する場合と似ています。HAVING 節の利
点はその探索条件に集計関数を記述できる点です。WHERE 節の探索条件には集計関数
を記述できません。
それぞれの HAVING 節の条件では、1 つの列やグループに適用された集計関数の値
が、グループの別の集計関数の値や定数と比較されます。HAVING 節を使用して、グル
ープの並びの列の値と集計関数の値の両方に条件を設定することができます。
図 272 は、品目が 3 つ以上のすべての注文について品目ごとの平均合計金額を戻しま
す。HAVING 節は、作成された各グループをテストし、複数の行で構成されたグループ
を選択します。
142
IBM Informix SQL ガイド: チュートリアル
SELECT order_num, COUNT(*) number, AVG (total_price) average
FROM items
GROUP BY order_num
HAVING COUNT(*) > 2
図 272. 問合せ
order_num
number
average
1003
1004
1005
1006
1007
1013
1016
1017
1018
1021
1022
1023
3
4
4
5
5
4
4
3
5
4
3
6
$319.67
$354.00
$140.50
$89.60
$339.20
$35.95
$163.50
$194.67
$226.20
$403.50
$77.33
$137.33
図 273. 問合せ結果
HAVING 節を指定し、GROUP BY 節を指定しない場合、HAVING 条件は検索条件を
満たす行すべてに適用されます。つまり、探索条件を満たすすべての行が 1 つのグルー
プを構成します。
図 274 は図 272 を書き直したもので、図 275 で示すように 1 行の結果、つまり表のす
べての列 total_price (合計価格) の平均を戻します。
SELECT AVG (total_price) average
FROM items
HAVING count(*) > 2
図 274. 問合せ
average
$270.97
図 275. 問合せ結果
第 5 章 高度な SELECT 文の作成
143
図 272 と同様、図 274 では、Projection 節内に集合でない列 order_ num が含まれてい
る場合、GROUP BY 節を追加し、グループ リストにこの列を指定する必要がありま
す。また、HAVING 節での条件が満たされていない場合は、列見出しが表示され、該当
する行を検出できなかったことを示すメッセージが表示されます。
図 276 には、対話型 SQL の Informix バージョンで使用できる SELECT 文の節がすべ
て含まれています (ホスト変数を命名する INTO 節は、SQL API でのみ使用できま
す)。
SELECT o.order_num, SUM (i.total_price) price,
paid_date - order_date span
FROM orders o, items i
WHERE o.order_date > ’01/01/98’
AND o.customer_num > 110
AND o.order_num = i.order_num
GROUP BY 1, 3
HAVING COUNT (*) < 5
ORDER BY 3
INTO TEMP temptab1
図 276. 問合せ
図 276 は、表 orders と表 items を結合し、表示ラベル、表の別名、列標識として使用
されている整数を使用し、データのグループ化と順序付けを行い、また、図 277 が示し
ているように結果を一時表に入れます。
order_num
price
span
1017
1016
1012
1019
1005
1021
1022
1010
1009
1020
$584.00
$654.00
$1040.00
$1499.97
$562.00
$1614.00
$232.00
$84.00
$450.00
$438.00
26
28
30
40
66
68
71
図 277. 問合せ結果
144
IBM Informix SQL ガイド: チュートリアル
高度な結合の作成
68 ページの『結合の作成』では、SELECT 文に WHERE 文を指定して、1 つ以上の列
に関して複数の表を結合する方法について説明しました。そこで説明した結合は、自然
結合と等結合の 2 種類でした。
この章では、2 種類の結合よりもさらに複雑な、セルフ結合と外部結合の使用について
説明します。表セルフ結合やアウター結合においても、第 2 章で説明した単純な結合と
同じように、表の別名や表示ラベルを使用することができます。表に別名を定義した
り、式に表示ラベルを割り当てると、複数表からなる問合せの記述を簡略化することが
できます。また、ORDER BY を使用した SELECT 文を発行してデータをソートし、一
時表に格納することもできます。
セルフ結合
結合では必ずしも 2 つの異なる表を結合させる必要はありません。表をそれ自体に結合
させて、セルフ結合 とすることができます。列内の値を同じ列内の別の値と比較すると
きには、表をその表自体と結合すると便利な場合があります。
セルフ結合を作成するには、FROM 節から表を 2 回リストして、これに 1 回ごとに異
なる別名を指定します。Projection 節と WHERE 節ではこれらの別名を使用して、2 つ
の別の表があるかのように参照します (SELECT 文の別名については、76 ページの『別
名の使用』および「IBM Informix: SQL ガイド: 構文」を参照してください)。
異なる表の結合の場合と同様に、セルフ結合でも算術式を使用できます。NULL をテス
トすることも、ORDER BY 節を使用して、指定した列の値を昇順または降順にソート
することもできます。
図 278 は、ship_weight が 5 倍以上異なり、ship_date が NULL ではない注文のペア
を探索します。その後、問合せではデータを ship_date 順に並び替えます。
SELECT x.order_num, x.ship_weight, x.ship_date,
y.order_num, y.ship_weight, y.ship_date
FROM orders x, orders y
WHERE x.ship_weight >= 5 * y.ship_weight
AND x.ship_date IS NOT NULL
AND y.ship_date IS NOT NULL
ORDER BY x.ship_date
図 278. 問合せ
第 5 章 高度な SELECT 文の作成
145
表 5. 問合せ結果
order_num
ship_weight
ship_date
order_num
ship_weight
ship_date
1004
95.80
05/30/1998
1011
10.40
07/03/1998
1004
95.80
05/30/1998
1020
14.00
07/16/1998
1004
95.80
05/30/1998
1022
15.00
07/30/1998
1007
125.90
06/05/1998
1015
20.60
07/16/1998
1007
125.90
06/05/1998
1020
14.00
07/16/1998
セルフ結合の結果を一時表に格納する場合は、SELECT 文に INTO TEMP 節を追加し
て、それらに表示ラベルを割り当てることにより、少なくとも 1 組の列を名前変更して
ください。この処置を行わないと、列名の重複が原因でエラーが発生し、一時表が作成
されません。
図 279 では図 278 と同様に、表 orders から選択されたすべての列に表示ラベルを付
け、shipping (出荷) という名前の一時表に格納します。
SELECT x.order_num orders1, x.po_num purch1,
x.ship_date ship1, y.order_num orders2,
y.po_num purch2, y.ship_date ship2
FROM orders x, orders y
WHERE x.ship_weight >= 5 * y.ship_weight
AND x.ship_date IS NOT NULL
AND y.ship_date IS NOT NULL
ORDER BY orders1, orders2
INTO TEMP shipping
図 279. 問合せ
SELECT * from table shipping という問合せを行うと、図 280 に示す行が戻されます。
orders1 purch1
1004
1004
1004
1005
8006
8006
8006
2865
ship1
orders2 purch2
ship2
05/30/1998
05/30/1998
05/30/1998
06/09/1998
1011
1020
1022
1011
B77897
W2286
W9925
B77897
07/03/1998
07/16/1998
07/30/1998
07/03/1998
07/16/1998
07/16/1998
07/30/1998
1020 W2286
1022 W9925
1011 B77897
07/16/1998
07/30/1998
07/03/1998
..
.
1019 Z55709
1019 Z55709
1023 KF2961
図 280. 問合せ結果
146
IBM Informix SQL ガイド: チュートリアル
表はその表自体と何回でも結合できます。セルフ結合できる最大回数は、利用可能なシ
ステム資源によって異なります。
図 281 のセルフ結合では、表 stock (取扱品目) の品目のうち、3 つのメーカーから提
供されるものを取り出します。セルフ結合では WHERE 節の最後の 2 つの条件を指定
することによって、重複するメーカー コードを抽出した行から除去できます。
SELECT s1.manu_code, s2.manu_code, s3.manu_code,
s1.stock_num, s1.description
FROM stock s1, stock s2, stock s3
WHERE s1.stock_num = s2.stock_num
AND s2.stock_num = s3.stock_num
AND s1.manu_code < s2.manu_code
AND s2.manu_code < s3.manu_code
ORDER BY stock_num
図 281. 問合せ
manu_code manu_code manu_code stock_num description
HRO
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
HRO
HRO
HRO
..
.
KAR
KAR
KAR
NKL
HSK
NRG
HRO
HRO
HRO
HSK
HSK
PRC
HSK
HSK
PRC
SMT
SMT
HSK
PRC
SHM
PRC
SHM
SHM
PRC
SHM
SHM
1
5
110
110
110
110
110
110
110
110
110
baseball gloves
tennis racquet
helmet
helmet
helmet
helmet
helmet
helmet
helmet
helmet
helmet
NKL
NKL
PRC
PRC
PRC
SHM
SHM
SHM
301
301
301
301
running
running
running
running
shoes
shoes
shoes
shoes
図 282. 問合せ結果
payroll 表から行を選択して、マネージャよりも所得の多い従業員を判別するとします。
この場合、次の SELECT 文のようにセルフ結合を作成できます。
SELECT emp.employee_num, emp.gross_pay, emp.level,
emp.dept_num, mgr.employee_num, mgr.gross_pay,
mgr.dept_num, mgr.level
FROM payroll emp, payroll mgr
第 5 章 高度な SELECT 文の作成
147
WHERE emp.gross_pay > mgr.gross_pay
AND emp.level < mgr.level
AND emp.dept_num = mgr.dept_num
ORDER BY 4
図 283 では、相関副問合せ を使用して、価格の高い品目を上から順に 10 個抽出して
リストします。
SELECT order_num, total_price
FROM items a
WHERE 10 >
(SELECT COUNT (*)
FROM items b
WHERE b.total_price < a.total_price)
ORDER BY total_price
図 283. 問合せ
図 283 は、図 284 に示す 10 行を戻します。
order_num
1018
1013
1003
1005
1006
1013
1010
1013
1022
1023
total_price
$15.00
$19.80
$20.00
$36.00
$36.00
$36.00
$36.00
$40.00
$40.00
$40.00
図 284. 問合せ結果
同じような問合せを作成し、社内で最も年功が高い 10 人の従業員を探して表示するこ
ともできます。
相関副問合せの詳細については、157 ページの『SELECT 文の副問合せ』を参照してく
ださい。
外部結合
ここでは、外部結合を作成し、SELECT 文で使用する方法について説明します。68 ペ
ージの『結合の作成』では、内部結合について説明しました。内部結合では、結合の対
148
IBM Informix SQL ガイド: チュートリアル
象となる 2 つ以上の表が対等に扱われますが、外部結合では非対称的に扱われます。外
部結合では、表の 1 つが主表 (または外部表)となり、他の表が従属表 (または内部表)
になります。
内部結合または単純結合では、結合条件を満たす行の組合せのみが結果に含まれます。
結合条件を満たさない行は無視されます。
外部結合では、結合条件を満たす行の組合せが結果に含まれます。また、従属表で一致
する行がないために廃棄されるはずの主表からの行も含まれます。従属表に一致する行
がない主表の行では、従属表から選択された列に NULL 値が含まれます。
外部結合を使用することで、結合条件を適用する前に、内部表に対して結合フィルタを
適用できます。
旧バージョンのデータベース サーバでは、外部結合に関して、ANSI-SQL 標準構文の
Informix 拡張のみをサポートしていました。この構文は現在でもサポートされますが、
ANSI-SQL 標準構文の方が、問合せ作成に対する柔軟性が向上しています。新しい問合
せを作成する場合は、ANSI-SQL 標準構文を使用することをお勧めします。どちらの構
文を使用する場合でも、同じ問合せブロック内で使用する構文は統一してください。
外部結合を多用する前に、1 つ以上の内部結合が機能するか判別する必要があります。
通常、他の表の補足情報が必要ない場合は、内部結合で間に合わせることができます。
重要: 同じ問合せブロック内では、Informix 外部結合構文と ANSI 外部結合構文を併用
できません。
外部結合の構文の詳細については、「IBM Informix: SQL ガイド: 構文」を参照してく
ださい。
外部結合構文の Informix 拡張
外部結合構文の Informix 拡張は、外部結合をキーワード OUTER で始めます。Informix
構文を使用する場合は、結合条件を必ず WHERE 節に含めるようにしてください。外部
結合に Informix 構文を使用する場合、データベース サーバがサポートする外部結合の
基本型は以下の 3 つです。
v 2 つの表の単純な外部結合
v 第 3 の表との単純な外部結合
v 第 3 の表に対する 2 つの表との外部結合
外部結合には、Projection 節、FROM 節、および WHERE 節がある必要があります。結
合条件は、WHERE 節に記述されます。単純結合を外部結合に変換する場合は、キーワ
ード OUTER を、FROM 節の従属表名の直前に挿入します。後述するように、キーワ
ード OUTER は問合せに何回でも指定できます。
外部結合構文の Informix 拡張は、ANSI 右外部結合と同じです。
第 5 章 高度な SELECT 文の作成
149
ANSI 結合構文
以下の ANSI 結合がサポートされます。
v 左外部結合
Dynamic Server
v 右外部結合
Dynamic Server の終り
ANSI 外部結合構文では、外部結合をキーワード LEFT JOIN、LEFT OUTER JOIN、
RIGHT JOIN、または RIGHT OUTER JOIN で開始します。キーワード OUTER はオ
プションです。問合せでは、ON 節に結合条件と結合フィルタを指定できます。WHERE
節には、ポスト結合フィルタを指定します。また、LEFT または RIGHT 節を使用し
て、結合の型を明示的に指定できます。さらに、ANSI 結合構文では、外部結合の主部
または従属部を、左括弧で始まる他の結合の結果セットとして使用しすることができま
す。
ANSI を外部結合に使用する場合は、同じ問合せブロックのすべての外部結合に ANSI
構文を使用してください。
ヒント: ここで説明する例では、記述を簡単にするために表の別名を使用しています。
表の別名については、76 ページの『別名の使用』を参照してください。
左外部結合
左外部結合の構文では、外部結合の主表が、外部結合の最初のキーワードの左に表示さ
れます。左外部結合は、結合条件を満たしたすべての行を戻します。また、主表の他の
行もすべて戻し、従表の対応する値を NULL として表示します。
次の問合せでは ANSI 構文 LEFT OUTER JOIN を使用しています。これは、Informix
外部結合構文を使用した 153 ページの図 291 と同じ結果を戻します。
SELECT c.customer_num, c.lname, c.company, c.phone,
u.call_dtime, u.call_descr
FROM customer c LEFT OUTER JOIN cust_calls u
ON c.customer_num = u.customer_num
図 285. 問合せ
この例では、ON 節を使用して、結合条件を指定できます。また、WHERE に別のフィ
ルタを追加し、結果セットを制限できます。この場合のフィルタはポスト結合フィルタ
です。
150
IBM Informix SQL ガイド: チュートリアル
次の問合せでは、カスタマ サービスに電話していない顧客の行のみを戻します。この問
合せでは、表 customer および表 cust_calls の列 customer_num を外部結合してから、
WHERE 節のフィルタを適用します。
SELECT c.customer_num, c.lname, c.company, c.phone,
u.call_dtime, u.call_descr
FROM customer c LEFT OUTER JOIN cust_calls u
ON c.customer_num = u.customer_num
WHERE u.customer_num IS NULL
図 286. 問合せ
上述の例以外にも、ANSI 結合構文を使用して、以下のような問合せを作成できます。
SELECT *
FROM (t1 LEFT OUTER JOIN (t2 LEFT OUTER JOIN t3 ON t2.c1=t3.c1)
ON t1.c1=t3.c1) JOIN (t4 LEFT OUTER JOIN t5 ON t4.c1=t5.c1)
ON t1.c1=t4.c1;
SELECT *
FROM (t1 LEFT OUTER JOIN (t2 LEFT OUTER JOIN t3 ON t2.c1=t3.c1)
ON t1.c1=t3.c1),
(t4 LEFT OUTER JOIN t5 ON t4.c1=t5.c1)
WHERE t1.c1 = t4.c1;
SELECT *
FROM (t1 LEFT OUTER JOIN (t2 LEFT OUTER JOIN t3 ON t2.c1=t3.c1)
ON t1.c1=t3.c1) LEFT OUTER JOIN (t4 JOIN t5 ON t4.c1=t5.c1)
ON t1.c1=t4.c1;
SELECT *
FROM t1 LEFT OUTER JOIN (t2 LEFT OUTER JOIN t3 ON t2.c1=t3.c1)
ON t1.c1=t2.c1;
SELECT *
FROM t1 LEFT OUTER JOIN (t2 LEFT OUTER JOIN t3 ON t2.c1=t3.c1)
ON t1.c1=t3.c1;
SELECT *
FROM (t1 LEFT OUTER JOIN t2 ON t1.c1=t2.c1)
LEFT OUTER JOIN t3 ON t2.c1=t3.c1;
SELECT *
FROM (t1 LEFT OUTER JOIN t2 ON t1.c1=t2.c1)
LEFT OUTER JOIN t3 ON t1.c1=t3.c1;
SELECT *
FROM t9, (t1 LEFT JOIN t2 ON t1.c1=t2.c1),
(t3 LEFT JOIN t4 ON t3.c1=10), t10, t11,
(t12 LEFT JOIN t14 ON t12.c1=100);
第 5 章 高度な SELECT 文の作成
151
右外部結合 (IDS)
右外部結合の構文では、外部結合の主表が、外部結合の最初のキーワードの右に表示さ
れます。右外部結合は、結合条件を満たしたすべての行を戻します。また、主表の他の
行もすべて戻し、従表の対応する値を NULL として表示します。
図 287 は、表 customer と表 orders の右外部結合の例です。
SELECT c.customer_num, c.fname, c.lname, o.order_num,
o.order_date, o.customer_num
FROM customer c RIGHT OUTER JOIN orders o
ON (c.customer_num = o.customer_num);
図 287. 問合せ
図 287 は、主表 orders のすべての行を戻し、従表 customer の対応する値を NULL
として表示します。
customer_num
fname
lname order_num
104 Anthony Wiggins
1001
101 Ludwig
Pauli
1002
104 Anthony
Wiggins
1003
<NULL> <NULL>
<NULL>
1004
order_date
05/30/1998
05/30/1998
05/30/1998
06/05/1998
customer_num
104
101
104
106
図 288. 問合せ結果
単純結合
図 289 は、表 customer と表 cust_calls の単純結合の例です。
SELECT c.customer_num, c.lname, c.company,
c.phone, u.call_dtime, u.call_descr
FROM customer c, cust_calls u
WHERE c.customer_num = u.customer_num
図 289. 問合せ
図 289 は、図 290 が示しているように、カスタマ サービスに顧客が電話した行のみを
戻します。
152
IBM Informix SQL ガイド: チュートリアル
customer_num
lname
company
phone
call_dtime
call_descr
..
.
customer_num
lname
company
phone
call_dtime
call_descr
106
Watson
Watson & Son
415-389-8789
1998-06-12 08:20
Order was received, but two of the cans of
ANZ tennis balls within the case were empty
116
Parmelee
Olympic City
415-534-8822
1997-12-21 11:24
Second complaint from this customer! Received
two cases right-handed outfielder gloves (1 HRO)
instead of one case lefties.
図 290. 問合せ結果
2 つの表の単純な外部結合
図 291 は、前の例と同じ Projection 節、表、および比較条件を使用していますが、今度
は単純な外部結合を Informix 拡張構文で作成します。
SELECT c.customer_num, c.lname, c.company,
c.phone, u.call_dtime, u.call_descr
FROM customer c, OUTER cust_calls u
WHERE c.customer_num = u.customer_num
図 291. 問合せ
表 cust_calls の前にキーワード OUTER を挿入することで、これが従表になります。外
部結合にすると、カスタマ サービスに電話したかどうかに関係なく、顧客全員 に関す
る情報が戻されます。図 292 に示すように、主表 customer のすべての行が抽出され、
従表 cust_calls の列に NULL 値が割り当てられます。
第 5 章 高度な SELECT 文の作成
153
customer_num 101
lname
Pauli
company
All Sports Supplies
phone
408-789-8075
call_dtime
call_descr
customer_num
lname
company
phone
call_dtime
call_descr
..
.
customer_num
lname
company
phone
call_dtime
call_descr
102
Sadler
Sports Spot
415-822-1289
107
Ream
Athletic Supplies
415-356-9876
customer_num 108
lname
Quinn
company
Quinn’s Sports
phone
415-544-8729
call_dtime
call_descr
図 292. 問合せ結果
第 3 の表に対する単純結合との外部結合
ANSI 構文を使用した図 293 には、第 3 の表に対する単純結合の結果としての外部結
合を示します。この第 2 のタイプの外部結合は、入れ子になった単純結合 と呼ばれて
います。
SELECT c.customer_num, c.lname, o.order_num,
i.stock_num, i.manu_code, i.quantity
FROM customer c, LEFT OUTER JOIN (orders o, items i)
WHERE c.customer_num = o.customer_num
AND o.order_num = i.order_num
AND manu_code IN (’KAR’, ’SHM’)
ORDER BY lname
図 293. 問合せ
図 293 は、最初に表 orders と表 items に対して単純結合を実行して、列 manu_code
(メーカー コード) の値が KAR または SHM である品目のすべての注文についての情
154
IBM Informix SQL ガイド: チュートリアル
報を抽出します。次に外部結合を実行して、この情報を主表 customer のデータと結合
します。オプションの ORDER BY 節を使用して、データを図 294 に示す形に再編成し
ます。
customer_num lname
order_num stock_num manu_code quantity
114 Albertson
118 Baxter
113 Beatty
.
.
.
105 Vector
121 Wallack
106 Watson
1018
302 KAR
3
図 294. 問合せ結果
第 3 の表に対する 2 つの表の外部結合
Informix 構文を使用した図 295 には、第 3 の表に対する 2 つの表それぞれの外部結合
の結果を示します。この第 3 のタイプの外部結合では、結合関係は主表と従表との間で
のみ 成立します。
SELECT c.customer_num, c.lname, o.order_num,
order_date, call_dtime
FROM customer c, OUTER orders o, OUTER cust_calls x
WHERE c.customer_num = o.customer_num
AND c.customer_num = x.customer_num
ORDER BY lname
INTO TEMP service
図 295. 問合せ
図 295 は、従表 orders と cust_calls を主表 customer に個別に結合します。2 つの従
表同士は結合しません。INTO TEMP 節は、結果を一時表に格納し、さらに操作または
問合せを実行できるようにします。図 296 に例を示します。
第 5 章 高度な SELECT 文の作成
155
customer_num lname
114
118
113
103
115
Albertson
Baxter
Beatty
Currie
Grant
117
105
121
106
106
Sipes
Vector
Wallack
Watson
Watson
order_num order_date call_dtime
1010 06/17/1998
.
.
.
1012 06/18/1998
1018 07/10/1998 1998-07-10 14:05
1004 05/22/1998 1998-06-12 08:20
1014 06/25/1998 1998-06-12 08:20
図 296. 問合せ結果
図 297 が示すように、図 295 で 2 つの従表 o と x の間に結合条件を作成しようとす
ると、エラー メッセージが戻されて、両面外部結合の作成が示されます。
WHERE o.customer_num = x.customer_num
図 297. 問合せ
外部結合を組み合わせる結合
複数レベルの入れ子を達成するために、3 種類の外部結合のどの組合せの結合も作成で
きます。図 298 では、ANSI を使用して、2 つの表の単純な外部結合と 2 番目の外部
結合の組合せの結果である結合を作成しています。
SELECT c.customer_num, c.lname, o.order_num,
stock_num, manu_code, quantity
FROM customer c, OUTER (orders o, OUTER items i)
WHERE c.customer_num = o.customer_num
AND o.order_num = i.order_num
AND manu_code IN (’KAR’, ’SHM’)
ORDER BY lname
図 298. 問合せ
図 298 は、最初に表 orders と表 items に対して外部結合を実行して、列 manu_code
の値が KAR または SHM である品目のすべての注文についての情報を抽出します。次
に 2 番目の外部結合を実行して、この情報を主表 customer のデータと結合します。
156
IBM Informix SQL ガイド: チュートリアル
customer_num lname
114
118
113
103
115
Albertson
Baxter
Beatty
Currie
Grant
117
117
105
121
106
106
Sipes
Sipes
Vector
Wallack
Watson
Watson
order_num stock_num manu_code quantity
1010
.
.
.
1012
1007
1018
1014
1004
302 KAR
3
図 299. 問合せ結果
外部結合を第 3 の表との外部結合の結果に適用する場合、結合条件を 2 つの方法で指
定できます。2 つの従表が結合されますが、主表と従表が共通列を共有している場合、
その結果に影響を与えることなくどちらの従表にも主表を結合することができます。
SELECT 文の副問合せ
データベース サーバでサポートされる副問合せの種類は、次の状況で定義されます。
v 別の SELECT 文の射影リストに入れ子になった SELECT 文
v 別の SELECT 文の WHERE 節 (または INSERT、DELETE、または UPDATE 文)
に入れ子になった SELECT 文
各副問合せには、Projection 節および FROM 節を指定する必要があります。副問合せ
は、相関 である場合と、無相関 である場合があります。副問合せ (または内部
SELECT 文) によって生成される値が、この値を囲む外部 SELECT 文の値によって決
定される場合、この副問合せは相関です。詳しくは、『相関副問合せ』を参照してくだ
さい。それ以外の副問合せは、すべて非相関副問合せと見なされます。
相関副問合せ
相関副問合せとは、FROM 節内に存在しない表の列を参照する副問合せです。Projection
節内と WHERE 節内の列を参照できます。問合せで参照する表を検索する場合は、相関
が検出されるまで非相関列を検索します。
通常、相関副問合せはパフォーマンスを低下させます。副問合せに表名または別名を使
用して、列が存在する表を明確にしてください。
データベース サーバは、外部問合せを使用して値を取得します。例えば、表 taba に列
col1 があり、表 tabb に列 col2 があり、それぞれに以下が含まれるとします。
第 5 章 高度な SELECT 文の作成
157
taba.col1
tabb.col2
aa,bb,null
bb, null
次の問合せを実行します。
select * from taba where col1 in (select col1 from tabb);
この場合、結果は無意味なものになります。データベース サーバは、taba.col1 内のす
べての値を提供し、それらを taba.col1 と比較します (外部問合せの WHERE 節)。こ
れにより、すべての行が戻されます。通常、副問合せは内部表から列値を戻すために使
用します。例えば次のような問合せを実行します。
select * from taba where col1 in (select tabb.col1 from tabb);
この場合、error -217 column not found という結果になります。
相関副問合せの重要な特徴は、相関副問合せは外側の SELECT 文の値に依存している
ため、外側の SELECT 文が作成するすべての値に対して 1 回ずつ、繰り返し実行しな
ければならないという点です。非相関副問合せは 1 回しか実行されません。
SELECT 文の副問合せ
2 つの異なる SELECT 文の代わりに、副問合せを含む SELECT 文を構築することがで
きます。
SELECT 文内で副問合せを使用することで、以下のアクションを実行できます。
v 式を、別の SELECT 文の結果と比較する。
v 他の SELECT 文の結果に式が含まれるかどうか判別する。
v 他の SELECT 文が行を選択するかどうか判別する。
オプションの WHERE 節は、探索条件を狭めるために使用されることがよくあります。
副問合せは値を取り出して、その値を最初の SELECT 文か外側の SELECT 文に戻しま
す。副問合せには、値を 1 つも戻さない、1 つの値を戻す、または、1 組の値を戻す場
合があります。以下にそれぞれの場合を説明します。
v 副問合せが値を戻さない 場合、その問合せでは行を戻しません。このような副問合
せは NULL 値と同等です。
v 副問合せが値を 1 つ戻す場合、値のフォームは 1 つの集計式または 1 つの行と 1
つの列になります。このような副問合せは単一の数値か文字値と同じです。
v 副問合せが値のリストまたはセット を戻す場合、それらの値は 1 つの行または 1
つの列を表します。
Projection 節での副問合せ
副問合せは別の SELECT 文の射影リストで使用できます。図 300 では、Projection 節の
中で副問合せを使用して、customer 表の各顧客について (orders 表から) 合計出荷費用
158
IBM Informix SQL ガイド: チュートリアル
を戻す方法を示しています。この問合せは、3 つの表の結合として作成することもでき
ます。
SELECT customer.customer_num,
(SELECT SUM(ship_charge)
FROM orders
WHERE customer.customer_num = orders.customer_num)
AS total_ship_chg
FROM customer
図 300. 問合せ
customer_num total_ship_chg
101
102
103
104
105
$15.30
123
124
125
126
127
128
$8.50
$12.00
$38.00
..
.
$13.00
$18.00
図 301. 問合せ結果
WHERE 節の中の副問合せ
ここでは、別の SELECT 文の WHERE 節に入れ子 になった SELECT 文として実行さ
れる副問合せについて説明します。
次のキーワードは、SELECT 文内の WHERE 節内に副問合せを導入します。
v ALL
v ANY
v IN
v EXISTS
ALL および ANY に任意の関係演算子を使用すると、特定の値を、副問合せが生成す
るすべての値と比較したり (ALL)、副問合せが生成するいずれかの値と比較する (ANY)
第 5 章 高度な SELECT 文の作成
159
ことができます。ANY の代わりにキーワード SOME を使用することができます。演算
子 IN は = ANY と同等です。反対の探索条件を作成するには、キーワード NOT か他
の関係演算子を使用してください。
演算子 EXISTS は、副問合せをテストして、何らかの値が戻されたかを確認します。つ
まり、副問合せの結果が NULL でないかどうかを調べます。テキスト (TEXT) 型また
はバイト (BYTE) 型の列を含む副問合せには、キーワード EXISTS を使用できませ
ん。
副問合せでの条件の作成に使用する構文については、「IBM Informix: SQL ガイド: 構
文」を参照してください。
ALL の使用
副問合せが戻すどの値についても比較が TRUE であるかどうかを判定するには、副問
合せの前にキーワード ALL を指定します。副問合せが値を戻さない場合の探索条件は
TRUE です。副問合せが値を戻さない場合は、条件は、すべてのゼロ値に関して TRUE
になります。
図 302 は、注文番号が 1023 である注文に含まれる全品目の合計金額よりも合計金額が
少ない品目を検出して、その品目を含むすべての注文についての情報を取り出します。
SELECT order_num, stock_num, manu_code, total_price
FROM items
WHERE total_price < ALL
(SELECT total_price FROM items
WHERE order_num = 1023)
図 302. 問合せ
order_num stock_num manu_code total_price
1003
1005
1006
1010
1013
1013
1018
9
6
6
6
5
6
302
ANZ
SMT
SMT
SMT
ANZ
SMT
KAR
図 303. 問合せ結果
160
IBM Informix SQL ガイド: チュートリアル
$20.00
$36.00
$36.00
$36.00
$19.80
$36.00
$15.00
ANY の使用
副問合せが戻す値の少なくとも 1 つについて比較条件が TRUE であることを判定する
には、副問合せの前にキーワード ANY (またはそのシノニム SOME) を指定します。
副問合せが値を戻さない場合の探索条件は、FALSE です。値がなにも存在しないため、
その値の 1 つについて条件が TRUE になることはありません。
図 304 は、注文番号が 1005 である品目のいずれか 1 つ の合計価格よりも合計価格が
大きい品目を含む、すべての注文の注文番号を検索します。
SELECT DISTINCT order_num
FROM items
WHERE total_price > ANY
(SELECT total_price
FROM items
WHERE order_num = 1005)
図 304. 問合せ
order_num
1001
1002
1003
1004
.
.
.
1020
1021
1022
1023
図 305. 問合せ結果
一価副問合せ
副問合せが外部レベルの問合せに必ず 1 つ の値を戻すことがわかっている場合は、キ
ーワード ALL または ANY を指定する必要はありません。値を 1 つだけ戻す副問合
せは、関数として扱うことができます。このような副問合せでは、集計関数を使用して
値を 1 つ戻す副問合せが作成されます。
図 306 は、副問合せ内で集計関数 MAX を使用して、最大のバレーボール ネット数を
持つ注文の order_num を検索します。
第 5 章 高度な SELECT 文の作成
161
SELECT order_num FROM items
WHERE stock_num = 9
AND quantity =
(SELECT MAX (quantity)
FROM items
WHERE stock_num = 9)
図 306. 問合せ
order_num
1012
図 307. 問合せ結果
図 308 は、副問合せに集計関数 MIN を使用して、合計金額がその最小価格の 10 倍よ
りも多い品目を取り出します。
SELECT order_num, stock_num, manu_code, total_price
FROM items x
WHERE total_price >
(SELECT 10 * MIN (total_price)
FROM items
WHERE order_num = x.order_num)
図 308. 問合せ
order_num stock_num manu_code
1003
1018
1018
1018
8
307
110
304
ANZ
PRC
PRC
HRO
total_price
$840.00
$500.00
$236.00
$280.00
図 309. 問合せ結果
相関副問合せ
図 310 は、表 orders から出荷日を日付の新しい順に 10 番目まで検出して戻す相関副
問合せの例です。副問合せ内には ORDER BY を指定することができないため、この例
では、副問合せの後に ORDER BY 節を配置して結果を並べ替えています。
162
IBM Informix SQL ガイド: チュートリアル
SELECT po_num, ship_date FROM orders main
WHERE 10 >
(SELECT COUNT (DISTINCT ship_date)
FROM orders sub
WHERE sub.ship_date < main.ship_date)
AND ship_date IS NOT NULL
ORDER BY ship_date, po_num
図 310. 問合せ
この副問合せが作成する数値は、外側の SELECT 文が作成する値 main.ship_date によ
って異なるため、これは相関副問合せです。したがって、この副問合せは外側の
SELECT 文が調べる各行について、1 回ずつ実行されなければなりません。
図 310 では、COUNT 関数を使用して、メインの問合せに値を戻しています。次に、
ORDER BY 節を使用してデータを並べ替えます。この問合せは、最新の 10 の出荷日
から 16 の行を検索して戻します。結果を図 311 に示します。
po_num
ship_date
4745
278701
429Q
8052
B77897
LZ230
B77930
PC6782
DM354331
S22942
MA003
W2286
Z55709
C3288
KF2961
W9925
06/21/1998
06/29/1998
06/29/1998
07/03/1998
07/03/1998
07/06/1998
07/10/1998
07/12/1998
07/13/1998
07/13/1998
07/16/1998
07/16/1998
07/16/1998
07/25/1998
07/30/1998
07/30/1998
図 311. 問合せ結果
図 310 のような相関副問合せを大規模な表に使用する場合は、列 ship_date にインデッ
クスを付けて効率を向上させる必要があります。これを行わない場合、この SELECT
文は、表の各行ごとに副問合せを 1 回ずつ実行するため、効率が低下する可能性があり
ます。インデックス付けとパフォーマンスに関する情報については、「IBM Informix:
Dynamic Server 管理者ガイド」と「IBM Informix: Dynamic Server パフォーマンス ガイ
ド」を参照してください。
第 5 章 高度な SELECT 文の作成
163
EXISTS の使用
キーワード EXISTS は存在作用素 と呼ばれます。これは、図 312 に示すように、外部
SELECT 文が行を少なくとも 1 つ検索した場合にのみ副問合せが TRUE になるためで
す。
SELECT UNIQUE manu_name, lead_time
FROM manufact
WHERE EXISTS
(SELECT * FROM stock
WHERE description MATCHES ’*shoe*’
AND manufact.manu_code = stock.manu_code)
図 312. 問合せ
通常、IN を使用する問合せと同等の問合せを、EXISTS を使用して構築することができ
ます。図 313 では、IN 述部を使用して、図 312 と同じ結果を戻す問合せを構築してい
ます。
SELECT UNIQUE manu_name, lead_time
FROM stock, manufact
WHERE manufact.manu_code IN
(SELECT manu_code FROM stock
WHERE description MATCHES ’*shoe*’)
AND stock.manu_code = manufact.manu_code
図 313. 問合せ
図 312 と図 313 は両方とも、特定の種類の靴を製造するメーカーおよびこの製品の注文
に関するリード タイムの行を戻します。図 314 に戻される値を示します。
manu_name
Anza
Hero
Karsten
Nikolus
ProCycle
Shimara
lead_time
5
4
21
8
9
30
図 314. 問合せ結果
上述の問合せのいずれかと反対の検索条件を作成するには、キーワード NOT を IN ま
たは EXISTS に追加します。また、NOT IN の代わりに !=ALL を使用することもでき
ます。
164
IBM Informix SQL ガイド: チュートリアル
図 315 で示すように、同じ操作を 2 つの方法で行うことができます。データベースの
設計と表のサイズによって、一方の方法が他方よりもデータベース サーバに対する負担
が少ない場合があります。どちらの問合せが適切かを知るには、SET EXPLAIN コマン
ドを使用して問合せ予定のリストを表示してください。SET EXPLAIN の説明は、
「IBM Informix: Dynamic Server パフォーマンス ガイド」と「IBM Informix: SQL ガイ
ド: 構文」に記載されています。
SELECT customer_num, company FROM customer
WHERE customer_num NOT IN
(SELECT customer_num FROM orders
WHERE customer.customer_num = orders.customer_num)
SELECT customer_num, company FROM customer
WHERE NOT EXISTS
(SELECT * FROM orders
WHERE customer.customer_num = orders.customer_num)
図 315. 問合せ
図 315 の文は両方とも、図 316 の結果を戻します。これは、注文をまだ行っていない顧
客を示します。
customer_num company
102
103
105
107
108
109
113
114
118
125
128
Sports Spot
Phil’s Sports
Los Altos Sports
Athletic Supplies
Quinn’s Sports
Sport Stuff
Sportstown
Sporting Place
Blue Ribbon Sports
Total Fitness Sports
Phoenix University
図 316. 問合せ結果
キーワード EXISTS および IN は、積 と呼ばれる集合演算に使用され、キーワード
NOT EXISTS および NOT IN は、差 と呼ばれる集合演算に使用されます。これらの概
念については、171 ページの『集合演算』で説明しています。
図 317 は、表 items に対して副問合せを実行し、まだ注文されていない表 stock 内の
すべての品目を示します。
第 5 章 高度な SELECT 文の作成
165
SELECT * FROM stock
WHERE NOT EXISTS
(SELECT * FROM items
WHERE stock.stock_num = items.stock_num
AND stock.manu_code = items.manu_code)
図 317. 問合せ
図 317 は、図 318 に示す行を戻します。
stock_num manu_code description unit_price unit unit_descr
101
102
102
105
PRC
SHM
PRC
PRC
bicycle
bicycle
bicycle
bicycle
tires
brakes
brakes
wheels
312
313
313
HRO
SHM
ANZ
racer goggles
swim cap
swim cap
$88.00
$220.00
$480.00
$53.00
box
case
case
pair
4/box
4 sets/case
4 sets/case
pair
.
.
.
$72.00 box
$72.00 box
$60.00 box
12/box
12/box
12/box
図 318. 問合せ結果
SELECT 文が持つことができる副問合せの数に論理的な制限はありませんが、どんな文
のサイズも、文字列と見なされる場合には物理的に制限されます。ただし、この制限は
実際によく作成される大半の文の長さよりも長く設定されています。
データベースに情報が正しく入力されたか確認が必要な場合があります。データベース
内のエラーを検出する方法の 1 つは、エラーが存在するときにのみ出力を戻す問合せを
作成することです。このタイプの副問合せは、一種の監査問合せ として機能します。例
を図 319 に示します。
SELECT * FROM items
WHERE total_price != quantity *
(SELECT unit_price FROM stock
WHERE stock.stock_num = items.stock_num
AND stock.manu_code = items.manu_code)
図 319. 問合せ
図 319 は、注文された品目の合計金額がその品目の単価と数量を掛けたものと一致しな
い行のみを戻します。値引きが適用されていない場合、それらの戻された行は、データ
ベースに正しく入力されなかったと考えられます。この問合せでは、エラーが発生した
ときにのみ行を戻します。情報が正しくデータベースに挿入されていれば、行は戻され
ません。
166
IBM Informix SQL ガイド: チュートリアル
item_num order_num stock_num manu_code quantity total_price
1
2
1004
1006
1 HRO
5 NRG
1
5
$960.00
$190.00
図 320. 問合せ結果
SELECT 文でのコレクションの処理 (IDS)
データベース サーバでは、コレクション (COLLECTION) 型の式を処理するために、次
の SQL 機能が提供されています。
v コレクション (COLLECTION) 型の副問合せ を実行すると、副問合せの結果である仮
想表がコレクション (COLLECTION) 型に変換されます。
コレクション (COLLECTION) 型の副問合せは、常にマルチセット (MULTISET) 型
のコレクション (COLLECTION) 型データを戻します。コレクション (COLLECTION)
型の副問合せを使用すると、リレーショナル データの問合せ結果をマルチセット
(MULTISET) 型のコレクション (COLLECTION) 型データに変換できます。コレクシ
ョン (COLLECTION) 型の詳細については、「IBM Informix: データベース設計およ
び実装 ガイド」を参照してください。
v コレクション (COLLECTION) 型導出表 は、コレクションを仮想表に変換します。
コレクション (COLLECTION) 型の各要素は、コレクション (COLLECTION) 型導出
表の行として構築されます。コレクション (COLLECTION) 型導出表を使用すると、
個々のコレクション (COLLECTION) 型の要素にアクセスできます。
コレクション (COLLECTION) 型副問合せとコレクション (COLLECTION) 型導出表
は、反対の操作を行います。コレクション (COLLECTION) 型副問合せでは、関係表の
行の値をコレクション (COLLECTION) 型に変換しますが、コレクション
(COLLECTION) 型導出表では、コレクション (COLLECTION) 型の要素を関係表の行に
変換します。
コレクション (COLLECTION) 型副問合せ
コレクション (COLLECTION) 型の副問合せを使用すれば、副問合せの式からコレクシ
ョン (COLLECTION) 型の式を構築できます。コレクション (COLLECTION) 型の副問
合せでは、キーワード MULTISET を副問合せの直前に指定し、マルチセット
(MULTISET) 型コレクションに戻された値を変換します。ただし、キーワード
MULTISET を副問合せ式の前で指定すると、基礎表の行は変更されずに、表の行のコピ
ーのみが修正されます。例えば、コレクション (COLLECTION) 型を修正するユーザ定
第 5 章 高度な SELECT 文の作成
167
義ルーチンにコレクション (COLLECTION) 型の副問合せを渡すと、コレクション
(COLLECTION) 型データのコピーは修正されますが基礎表は修正されません。
コレクション (COLLECTION) 型の副問合せ式は次のどのフォームでも使用できます。
MULTISET(SELECT expression1, expression2... FROM tab_name...)
または
MULTISET(SELECT ITEM expression FROM tab_name...)
コレクション (COLLECTION) 型の副問合せでのキーワード ITEM の省略
コレクション (COLLECTION) 型の副問合せの式でキーワード ITEM を省略すると、コ
レクション (COLLECTION) 型の副問合せはマルチセット (MULTISET) 型になり、その
要素の型は常に名前なし行型になります。名前なし行型のフィールドは、副問合せの射
影リストに指定されている式と一致します。
マルチセット (MULTISET) 型の列を含む次の表を作成すると仮定します。
CREATE TABLE tab2
(
id_num INT,
ms_col MULTISET(ROW(a INT) NOT NULL)
)
図 321 では、WHERE 節でコレクション (COLLECTION) 型副問合せを使用し、副問合
せが マルチセット (MULTISET) 型コレクションに戻す値 INT の行を変換します。こ
の例では、表 tab2 の列 ms_col がコレクション (COLLECTION) 型副問合せ式の結果
に等しい場合に、行が戻されます。
SELECT id_num FROM tab2
WHERE ms_col = (MULTISET(SELECT int_col FROM tab1))
図 321. 問合せ
図 321 では、コレクション (COLLECTION) 型副問合せのキーワード ITEM を省略
し、副問合せが戻す INT 値がマルチセット (MULTISET) 型 (ROW(a INT) NOT
NULL) であり、tab2 の列 ms_col のデータ型と一致するようにします。
コレクション (COLLECTION) 型の副問合せでのキーワード ITEM の指定
副問合せの射影リストに 1 つの式が含まれている場合は、副問合せの射影リストの前に
キーワード ITEM を置いて、マルチセット (MULTISET) 型の要素の型が副問合せの結
果のデータ型と一致するよう指定できます。つまり、キーワード ITEM を指定すると、
射影リストの周囲に行ラッパが置かれません。例えば、(キーワード MULTISET の直後
に続く) 副問合せが INT 値を戻す場合、そのコレクション (COLLECTION) 型副問合せ
はマルチセット (MULTISET) 型 (INT NOT NULL) です。
168
IBM Informix SQL ガイド: チュートリアル
マルチセット (MULTISET) 型 (INT NOT NULL) の引数を受け入れる関数int_func() を
作成すると仮定します。図 322 に示すコレクション (COLLECTION) 型副問合せは、整
数 (INT) 型値をマルチセット (MULTISET) 型に変換し、int_func() の引数として使用
されます。
EXECUTE FUNCTION int_func(MULTISET(SELECT ITEM int_col
FROM tab1
WHERE int_col BETWEEN 1 AND 10))
図 322. 問合せ
図 322 では、キーワード ITEM が副問合せで指定されているため、問合せが戻す値
int_col はコレクション (COLLECTION) 型の MULTISET (INT NOT NULL) に変換さ
れます。キーワード ITEM が指定されない場合、コレクション (COLLECTION) 型副問
合せは マルチセット (MULTISET) 型 (ROW(a INT) NOT NULL) のコレクションを戻
します。
コレクション (COLLECTION) 型副問合せの構文および制約事項の詳細については、
「IBM Informix: SQL ガイド: 構文」を参照してください。
コレクション (COLLECTION) 型導出表
コレクション (COLLECTION) 型導出表 を使用すると、コレクション (COLLECTION)
型の式の要素を仮想表の行として処理することができます。SELECT 文の FROM 節で
キーワード TABLE を使用し、コレクション (COLLECTION) 型導出表を作成できま
す。データベース サーバは、SELECT、INSERT、UPDATE、および DELETE 文でのコ
レクション (COLLECTION) 型導出表の使用をサポートします。
図 323 では、c_table という名前のコレクション (COLLECTION) 型導出表を使用し
て、データベース superstores_demo の表 sales_rep の列 sales にある要素にアクセス
しています。列 sales は、売上情報を格納する month および amount フィールドを持
つ、名前なし行型のコレクションです。図 323 では、sales.amount が 98-03 の場合、
sales.amount の要素を戻します。内部選択は、それ自体が式であるため、外部問合せの
反復ごとに 1 つの列の値以外戻すことができません。外側の SELECT 文は、表
sales_rep で評価する行数を指定します。
SELECT (SELECT c_table.amount FROM TABLE (sales_rep.sales) c_table
WHERE c_table.month = ’98-03’)
FROM sales_rep
図 323. 問合せ
第 5 章 高度な SELECT 文の作成
169
(expression)
$47.22
$53.22
図 324. 問合せ結果
図 325 では、コレクション (COLLECTION) 型導出表を使用して、列 rep_num が 102
である sales コレクション型列の要素にアクセスします。コレクション (COLLECTION)
型導出表を使用して、表および列の別名を指定できます。コレクション (COLLECTION)
型導出表で表の名前が指定されていない場合は、データベース サーバによって自動的に
作成されます。この例では、コレクション (COLLECTION) 型導出表 c_table につい
て、導出列のリスト s_month および s_amount を指定します。
SELECT * FROM TABLE((SELECT sales FROM sales_rep
WHERE sales_rep.rep_num = 102)) c_table(s_month, s_amount)
図 325. 問合せ
s_month
s_amount
1998-03
1998-04
$53.22
$18.22
図 326. 問合せ結果
図 327 では、コレクション (COLLECTION) 型導出表を作成しますが、導出表や導出列
の名前は指定していません。図 327 は、図 325 と同じ結果を戻します。ただし、導出列
が表 sales_rep の列 sales のデフォルト フィールド名を想定しているという点が異なり
ます。
SELECT * FROM TABLE((SELECT sales FROM sales_rep
WHERE sales_rep.rep_num = 102))
図 327. 問合せ
170
IBM Informix SQL ガイド: チュートリアル
month
amount
1998-03
1998-04
$53.22
$18.22
図 328. 問合せ結果
重要: コレクション (COLLECTION) 型導出表は読取り専用であるため、
INSERT、UPDATE、DELETE 文、あるいは更新可能なカーソルまたはビューの基
礎表のターゲット表としては指定できません。
コレクション (COLLECTION) 型導出表の構文および制約事項の説明は、
「IBM Informix: SQL ガイド: 構文」に記載されています。
集合演算
標準の集合演算である和集合、積、差 を使用することで、データベース情報を操作する
ことができます。この 3 つの演算では、更新、挿入または削除を実行した後にデータベ
ースの整合性をテストするために SELECT 文を使用します。これらの演算は、例えば
データを履歴表に転送して、元の表からデータを削除する前に履歴表に正しいデータが
入っていることを確認する場合に便利です。
和集合
和集合は、キーワード UNION または演算子 を使用して、2 つの問合せを 1 つの複合
問合せ に結合します。キーワード UNION を複数の SELECT 文の間に使用すれば、そ
れらを結合して 元の表の一部または全部に存在する行を含む一時表を作成できます。ビ
ューの定義の中で UNION 演算子を使用することもできます。
Dynamic Server
副問合せ内では、UNION 演算子を使用できません。
Dynamic Server では行 (ROW) 型のソートがサポートされていません。UNION 演算で
は重複した値を削除するのにソートを必要とするため、UNION 演算のいずれかの問合
せに行 (ROW) 型データが含まれていると UNION 演算子を使用できません。ただし、
データベース サーバでは、行 (ROW) 型データに対してキーワード UNION ALL がサ
ポートされています。このデータ型の演算にはソートが不要であるためです。
Dynamic Server の終り
図 329 に、和集合演算を図解します。
第 5 章 高度な SELECT 文の作成
171
図 329. 和集合演算
キーワード UNION は、2 つの問合せが取り出す行をすべて結合し、重複行を削除し
て、残った行を戻します。問合せの結果は単一の結果に結合されるため、各問合せ内の
射影リストは、同じ列数でなければなりません。また、各表から選択される対応列には
互換データ型が含まれている必要があり (文字 (CHARACTER) 型の列は同じ長さである
必要があります)、これらの対応列では、すべてにおいて NULL が許可されるか、ある
いはすべてにおいて NULL が許可されないかのいずれかでなければなりません。
SELECT 文の構文と UNION 演算子については、「IBM Informix: SQL ガイド: 構文」
を参照してください。IBM Informix ESQL/C 製品固有の情報、および INTO 節と複合
問合せに関する制約事項については、「IBM Informix: ESQL/C Programmer’s Manual」
を参照してください。
図 330 は、表 stock と表 items の列 stock_num と列 manu_code に対して和集合演算
を実行します。
SELECT DISTINCT stock_num, manu_code FROM stock
WHERE unit_price < 25.00
UNION
SELECT stock_num, manu_code FROM items
WHERE quantity > 3
図 330. 問合せ
図 330 は、単価が $25.00 未満の品目、または注文数量が 4 以上の品目を選択して、こ
れらの品目の stock_num および manu_code をリストします。結果を図 331 に示しま
す。
172
IBM Informix SQL ガイド: チュートリアル
stock_num manu_code
5
5
5
9
103
106
201
301
302
302
ANZ
NRG
SMT
ANZ
PRC
PRC
NKL
KAR
HRO
KAR
図 331. 問合せ結果
UNION と ORDER BY の使用
図 332 に示すように、ORDER BY 節を記述する場合は、最後の SELECT 文の後に指
定してください。また、ソートする列の参照には、識別子ではなく整数を使用してくだ
さい。ソートは集合演算が完了した後で行われます。
SELECT DISTINCT stock_num, manu_code FROM stock
WHERE unit_price < 25.00
UNION
SELECT stock_num, manu_code FROM items
WHERE quantity > 3
ORDER BY 2
図 332. 問合せ
図 332 の複合問合せは、図 330 と同じ行を選択しますが、表示される行は 図 333 に示
すように製造者コード順に並べ替えられています。
第 5 章 高度な SELECT 文の作成
173
stock_num manu_code
5
9
302
301
302
201
5
103
106
5
ANZ
ANZ
HRO
KAR
KAR
NKL
NRG
PRC
PRC
SMT
図 333. 問合せ結果
UNION ALL の使用
キーワード UNION は、重複する行をデフォルトで除外します。重複した値を残す場合
は、オプションのキーワード ALL を図 334 に示すように追加します。
SELECT stock_num, manu_code FROM stock
WHERE unit_price < 25.00
UNION ALL
SELECT stock_num, manu_code FROM items
WHERE quantity > 3
ORDER BY 2
INTO TEMP stock item
図 334. 問合せ
図 334 は、キーワード UNION ALL を使用して 2 つ の SELECT文の和をとり、最後
の SELECT の後に INTO TEMP 節を追加して結果を一時表に格納します。これは図
332 と同じ行を戻しますが、重複値も含みます。
174
IBM Informix SQL ガイド: チュートリアル
stock_num manu_code
9
5
9
5
9
ANZ
ANZ
ANZ
ANZ
ANZ
5
5
103
106
5
5
NRG
NRG
PRC
PRC
SMT
SMT
..
.
図 335. 問合せ結果
異なる列名の使用
複合問合せの場合、Projection 節内の対応列はそれぞれ互換データ型でなければなりま
せんが、同じ列名を使用する必要はありません。
図 336 は、表 customer から列 state を選択して、表 state から対応する列 code を選
択します。
SELECT DISTINCT state FROM customer
WHERE customer_num BETWEEN 120 AND 125
UNION
SELECT DISTINCT code FROM state
WHERE sname MATCHES ’*a’
図 336. 問合せ
図 337 は、顧客番号が 120 から 125、または sname の末尾が a である州の州コード
の省略形が戻されます。
第 5 章 高度な SELECT 文の作成
175
state
AK
AL
AZ
CA
DE
..
.
SD
VA
WV
図 337. 問合せ結果
複合問合せでは、最初の SELECT 文に含まれる列名または表示ラベルが、問合せ結果
に使用されます。したがって、図 336 では、2 番目の SELECT 文からの列名 code の
代わりに、最初の SELECT 文からの列名 state が使用されます。
複数の表に対する UNION の使用
図 338 は、3 つの表に関して和集合を実行します。結合できる表の最大数は、実際に使
用するアプリケーションやメモリ制限によって異なります。
SELECT stock_num, manu_code FROM stock
WHERE unit_price > 600.00
UNION ALL
SELECT stock_num, manu_code FROM catalog
WHERE catalog_num = 10025
UNION ALL
SELECT stock_num, manu_code FROM items
WHERE quantity = 10
ORDER BY 2
図 338. 問合せ
図 338 は、表 stock 内の unit_price が $600 より大きいか、表 catalog 内の
catalog_num が 10025 であるか、または表 items 内の quantity が 10 である品目を選
択して、manu_code 順に並べ替えます。図 339 に、戻される値を示します。
176
IBM Informix SQL ガイド: チュートリアル
stock_num manu_code
5
9
8
4
1
203
5
106
113
ANZ
ANZ
ANZ
HSK
HSK
NKL
NRG
PRC
SHM
図 339. 問合せ結果
Projection 節でのリテラルの使用
図 340 では、射影リスト内でリテラルを使用し、和集合の一部の出力にタグを付けて、
後で区別できるようにしています。タグには sortkey というラベルが与えられていま
す。問合せは sortkey を使用して抽出された行を並び替えます。
SELECT ’1’ sortkey, lname, fname, company,
city, state, phone
FROM customer x
WHERE state = ’CA’
UNION
SELECT ’2’ sortkey, lname, fname, company,
city, state, phone
FROM customer y
WHERE state <> ’CA’
INTO TEMP calcust;
SELECT * FROM calcust
ORDER BY 1
図 340. 問合せ
図 340 は、カリフォルニアからの顧客を最初に並べた図 341 のようなリストを戻しま
す。
第 5 章 高度な SELECT 文の作成
177
sortkey
lname
fname
company
city
state
phone
1
Baxter
Dick
Blue Ribbon Sports
Oakland
CA
415-655-0011
sortkey
lname
fname
company
city
state
phone
..
.
sortkey
lname
fname
company
city
state
phone
1
Beatty
Lana
Sportstown
Menlo Park
CA
415-356-9982
2
Wallack
Jason
City Sports
Wilmington
DE
302-366-7511
図 341. 問合せ結果
FIRST 節の使用
Extended Parallel Server では FIRST 節を使用して、ユニオン問合せに戻された最初の
行を選択できます。図 342 では、FIRST 節を使用して、表 stock および表 items の和
集合の最初の 5 行を戻します。
SELECT FIRST 5 DISTINCT stock_num, manu_code
FROM stock
WHERE unit_price < 55.00
UNION
SELECT stock_num, manu_code
FROM items
WHERE quantity > 3
図 342. 問合せ
178
IBM Informix SQL ガイド: チュートリアル
stock_num manu_code
5
5
6
6
9
NRG
ANZ
SMT
ANZ
ANZ
図 343. 問合せ結果
積
2 つの行のセットの積 をとると、元の表の両方に存在する行を含む表が作成されます。
2 つのセットの積を示す副問合せを導入するには、キーワード EXISTS または IN を使
用します。図 344 に、積集合演算を図解します。
SELECT stock_num, manu_code,
unit_price
FROM stock
WHERE stock_num IN
(SELECT stock_num FROM items)
ORDER BY stock_num
stock_num
items
items
stock
stock
stock_num
items
stock
図 344. 積集合演算
図 345 は、表 stock と表 items の積を示す入れ子になった SELECT 文の例です。図
346 には両方のセットに含まれるすべての要素が含まれており、以下の行を戻します。
SELECT stock_num, manu_code, unit_price FROM stock
WHERE stock_num IN
(SELECT stock_num FROM items)
ORDER BY stock_num
図 345. 問合せ
第 5 章 高度な SELECT 文の作成
179
stock_num manu_code unit_price
1
1
1
2
3
3
HRO
HSK
SMT
HRO
HSK
SHM
$250.00
$800.00
$450.00
$126.00
$240.00
$280.00
306
307
309
309
SHM
PRC
HRO
SHM
$190.00
$250.00
$40.00
$40.00
..
.
図 346. 問合せ結果
差
2 つの行セット間の差 をとると、最初のセットには存在するが 2 番目のセットには存
在しない行からなる表が生成されます。2 つの集合間の差を示す副問合せを導入するに
は、キーワード NOT EXISTS または NOT IN を使用します。図 347 に、差集合演算
を図解します。
SELECT stock_num, manu_code,
unit_price
FROM stock
WHERE stock_num NOT IN
(SELECT stock_num
FROM items)
ORDER BY stock_num
stock_num
items
items
stock
stock
stock_num
items
stock
図 347. 差集合演算
図 348 に示す入れ子になった SELECT 文は、表 stock と表 items の差を示します。
180
IBM Informix SQL ガイド: チュートリアル
SELECT stock_num, manu_code, unit_price FROM stock
WHERE stock_num NOT IN
(SELECT stock_num FROM items)
ORDER BY stock_num
図 348. 問合せ
図 349 には、17 行を戻す最初のセットのみのすべての要素が含まれています。
stock_num manu_code unit_price
102 PRC
102 SHM
106 PRC
$480.00
$220.00
$23.00
..
.
312
312
313
313
HRO
SHM
ANZ
SHM
$72.00
$96.00
$60.00
$72.00
図 349. 問合せ結果
サマリ
この章は、第 2 章で紹介した概念に基づいて書かれたものです。リレーショナル デー
タベースに対して問合せを行うためのより高度な SELECT 文について、構文と結果の
例を示しています。以下に、この章で説明した内容をまとめます。
v 集計関数とともに使用して行のグループを戻し、これらのグループに条件を適用する
GROUP BY 節および HAVING 節の紹介
v セルフ結合で表をそれ自体に結合し、同じ列内の他の値と比較して、重複行を識別す
る方法についての説明
v 外部結合が複数の表を非対称に扱う方法に関する説明、および Informix 拡張と ANSI
結合構文を使用した 4 種類の外部結合の例示
v 他の SELECT 文の WHERE 節内で SELECT 文を入れ子にして相関および無相関副
問合せを作成する方法、および副問合せでの集計関数の使用方法の説明
v キーワード ALL、ANY、EXISTS、IN、および SOME を使用した副問合せの作成、
およびキーワード NOT または関係演算子を使用した場合の影響の説明
v リレーショナル データをコレクション (COLLECTION) 型のマルチセット
(MULTISET) 型に変換するのに使用するコレクション (COLLECTION) 型副問合せの
第 5 章 高度な SELECT 文の作成
181
使用方法、およびコレクション (COLLECTION) 型内の要素にアクセスするためのコ
レクション (COLLECTION) 型導出表の使用方法についての説明
v 和、積、および差などの集合演算についての説明
v キーワード UNION および UNION ALL を使用して複数の SELECT 文から構成さ
れる複合問合せを作成する方法の説明
182
IBM Informix SQL ガイド: チュートリアル
第 6 章 データの変更
データベースの変更 . . . . . . . . . . . . . . . . . . . . . . .
行の削除 . . . . . . . . . . . . . . . . . . . . . . . . . .
表のすべての行の削除 . . . . . . . . . . . . . . . . . . . . .
TRUNCATE TABLE を使用したすべての行の削除. . . . . . . . . . . .
TRUNCATE TABLE を使用した上位表からの行の削除 . . . . . . . . .
指定された行の削除 . . . . . . . . . . . . . . . . . . . . . .
選択された行の削除 . . . . . . . . . . . . . . . . . . . . . .
行 (ROW) 型を含む行の削除 (IDS) . . . . . . . . . . . . . . . . .
コレクション (COLLECTION) 型を含む行の削除 (IDS) . . . . . . . . . .
上位表からの行の削除 (IDS) . . . . . . . . . . . . . . . . . . .
複雑な削除条件 . . . . . . . . . . . . . . . . . . . . . . .
削除結合の使用 (XPS) . . . . . . . . . . . . . . . . . . . . .
行の挿入 . . . . . . . . . . . . . . . . . . . . . . . . . .
単一行 . . . . . . . . . . . . . . . . . . . . . . . . . .
VALUES 節に指定できる値 . . . . . . . . . . . . . . . . . .
列値の制約事項 . . . . . . . . . . . . . . . . . . . . . .
シリアル (SERIAL) 型 . . . . . . . . . . . . . . . . . . . .
特定の列名と値の指定 . . . . . . . . . . . . . . . . . . . .
型付き表への行の挿入 (IDS) . . . . . . . . . . . . . . . . . . .
行 (ROW) 型列への挿入 (IDS) . . . . . . . . . . . . . . . . . .
名前付き行型を含む行 . . . . . . . . . . . . . . . . . . . .
名前なし行型を含む行 . . . . . . . . . . . . . . . . . . . .
行 (ROW) 型への NULL 値の指定 . . . . . . . . . . . . . . . .
上位表への行の挿入 (IDS) . . . . . . . . . . . . . . . . . . . .
列へのコレクション (COLLECTION) 型値の挿入 (IDS) . . . . . . . . . .
単純コレクション (COLLECTION) 型および入れ子コレクション (COLLECTION)
行 (ROW) 型を含むコレクション (COLLECTION) 型への NULL 値の挿入 . .
スマート ラージ オブジェクトの挿入 (IDS) . . . . . . . . . . . . . .
複数の行の挿入および式の使用 . . . . . . . . . . . . . . . . . .
INSERT 文に SELECT 文を使用する場合の制約 . . . . . . . . . . . .
行の更新 . . . . . . . . . . . . . . . . . . . . . . . . . .
更新対象の行の選択 . . . . . . . . . . . . . . . . . . . . . .
一様値を使用する更新 . . . . . . . . . . . . . . . . . . . . .
更新の制限 . . . . . . . . . . . . . . . . . . . . . . . . .
選択値を使用する更新 . . . . . . . . . . . . . . . . . . . . .
行 (ROW) 型の更新 (IDS) . . . . . . . . . . . . . . . . . . . .
名前付き行型を含む行の更新 . . . . . . . . . . . . . . . . . .
名前なし行型を含む行の更新 . . . . . . . . . . . . . . . . . .
行 (ROW) 型のフィールドに対する NULL 値の指定 . . . . . . . . . .
コレクション (COLLECTION) 型の更新 (IDS) . . . . . . . . . . . . .
© Copyright IBM Corp. 1996, 2004
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
型への挿入
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
184
185
185
186
186
187
187
188
188
188
189
189
190
190
190
191
191
191
192
193
193
194
194
195
195
196
196
197
198
198
200
200
200
201
202
203
203
203
203
204
183
上位表の行の更新 (IDS) . . . . . . . . . . . . . .
CASE 式による列の更新 . . . . . . . . . . . . . .
SQL 関数を使用したスマート ラージ オブジェクトの更新 (IDS) .
結合を使用した列の更新 . . . . . . . . . . . . . .
データベースとそのオブジェクトに対するアクセス権 . . . . .
データベース レベル アクセス権 . . . . . . . . . . .
表レベル アクセス権 . . . . . . . . . . . . . . .
表アクセス権の表示 . . . . . . . . . . . . . . . .
ロールへのアクセス権の付与 . . . . . . . . . . . . .
データ整合性 . . . . . . . . . . . . . . . . . . .
エンティティ保全性 . . . . . . . . . . . . . . . .
意味整合性 . . . . . . . . . . . . . . . . . . .
参照整合性 . . . . . . . . . . . . . . . . . . .
ON DELETE CASCADE オプションの使用 . . . . . . .
カスケード削除の例 . . . . . . . . . . . . . . .
カスケード削除に対する制約 . . . . . . . . . . . .
オブジェクト モードと違反の検出 . . . . . . . . . . .
オブジェクト モードの定義 . . . . . . . . . . . .
データ操作ステートメントのモード例 . . . . . . . . .
違反表と診断表 . . . . . . . . . . . . . . . .
中断された変更 . . . . . . . . . . . . . . . . . .
トランザクション . . . . . . . . . . . . . . . .
トランザクション ログ . . . . . . . . . . . . . . .
Extended Parallel Server のトランザクション ログ機能 . . .
ロギングおよびカスケード削除 . . . . . . . . . . .
トランザクションの指定 . . . . . . . . . . . . . .
Informix データベース サーバを使用したバックアップとログ . . .
並行性およびロック . . . . . . . . . . . . . . . . .
IBM Informix データ レプリケーション (IDS) . . . . . . . .
サマリ . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
204
205
206
206
207
207
207
208
209
209
210
210
211
212
213
213
214
214
215
217
221
222
222
223
224
224
225
227
227
228
本章について
この章では、データベース内のデータを変更する方法について説明します。データの変
更は、データの問合せとは基本的に異なるものです。データを問合せる場合は、表の内
容を調査しますが、データを変更する場合は、表の内容を変更 します。
データベースの変更
データを変更する文は、次のとおりです。
v DELETE
v INSERT
v UPDATE
184
IBM Informix SQL ガイド: チュートリアル
これらの SQL 文は、より高度な SELECT 文と比べると比較的単純ですが、データベー
スの内容を変更する文であるため、注意して使用してください。
問合せ中にシステムのハードウェアやソフトウェアに障害が発生した場合を考えてみま
す。この場合、アプリケーションには非常に大きい影響がありますが、データベース自
体は被害を受けません。ただし、変更を行っている最中にシステムに障害が発生する
と、データベースの状態は不確かなものとなります。不確かな状態にあるデータベース
が、広範囲に影響を与えることは明らかです。データベースの行を削除、挿入、または
更新する前に、次の点を確認してください。
v データベースや表に対するユーザアクセス権の設定は適切か。つまり、特定のユーザ
に対してデータベースや表レベルのアクセス権が制限されているか。
v 変更されたデータは、データベースの既存の整合性を維持しているか。
v データベースを構築しているシステムは、システムやハードウェアの障害の原因とな
り得る外部のイベントから十分保護されているか。
上記のそれぞれの項目に当てはまらなくても、問題ではありません。Informix データベ
ース サーバの機能を上手に利用すれば、これらの問題のすべてを解決することができま
す。この章では、データを変更する文を紹介した後、その解決策について解説します。
より詳細な説明は、「IBM Informix: データベース設計および実装 ガイド」に記載され
ています。
行の削除
DELETE 文は、任意の行や行の組合せを表から削除します。トランザクションがコミッ
トされた後は、削除した行は復旧できません。(トランザクションについては、221 ペー
ジの『中断された変更』を参照してください。ここでは、トランザクションは文と同じ
ものとみなすことができます。) from という表から行を削除する場合は、まず
DELIMIDENT 環境変数を設定します。
行を削除する場合は、その削除する行に値が依存している他の表の行に対しても、細心
の注意を払って削除の操作を行わなければなりません。データベースが参照制約を強制
する場合は、CREATE TABLE 文または ALTER TABLE 文の ON DELETE CASCADE
オプションを使用して、ある表から別の表への関係によって、カスケード削除すること
ができます。参照制約と ON DELETE CASCADE オプションについては、211 ページ
の『参照整合性』を参照してください。
表のすべての行の削除
DELETE 文を使用するときは通常、表のどの行を削除するかを WHERE 節で指定しま
す。WHERE 節を指定しない場合、すべての行が削除されます。次の文は実行しないで
ください。
DELETE FROM customer
第 6 章 データの変更
185
DELETE 節には、FROM キーワードを含めずに使用することもできます。
DELETE customer
これらの DELETE 文には WHERE 節が含まれていないため、表 customer 内のすべて
の行が削除されます。DB–Access メニュー オプションを使用して無条件に削除する場
合は、警告および確認メッセージが表示されます。ただし、プログラム中で無条件削除
が指定されている場合は、この警告なしに削除が実行される場合があります。
TRUNCATE TABLE を使用したすべての行の削除
TRUNCATE TABLE 文を使用すると、表からすべての行を素早く削除できます。また、
対応するインデックス データもすべて削除されます。トランザクションがコミットされ
た後は、削除した行を復旧できません。TRUNCATE TABLE 文は、スマート ラージ オ
ブジェクトを含む、いかなる型の列を含む表に対しても使用できます。
TRUNCATE TABLE 文は、以下の理由で、DELETE 文よりも速く行を削除できます。
v 表の切捨てでは、表の DELETE トリガを実行しない。トリガの使用に関しては、
395 ページの『第 12 章 トリガの作成と使用』を参照してください。
v 切捨てを行う表の行ごとに論理ログを行わない。ロギングに関しては、222 ページの
『トランザクション ログ』を参照してください。
TRUNCATE TABLE 文を使用した場合の、パフォーマンスに対する影響については、
「IBM Informix: Dynamic Server パフォーマンス ガイド」を参照してください。構文の
詳細は、「IBM Informix: SQL ガイド: 構文」を参照してください。
TRUNCATE TABLE を使用した上位表からの行の削除
階層の上位表に対して TRUNCATE TABLE 文を使用する場合は、キーワード ONLY
により、その上位表のみに切捨てを実行するか、上位表とその副表に切捨てを実行する
か指定できます。デフォルト (ONLY を使用しない) では、上位表とその副表のすべて
が切捨ての対象になります。上位表 person を作成し、その下に 2 つの副表 employee
および sales_rep を定義すると仮定します。次の TRUNCATE TABLE 文では、表
person、employee、および sales_rep から行を削除します。
TRUNCATE TABLE person
上位表の行のみを削除する場合は、TRUNCATE TABLE 文でONLY キーワードを使用
します。例えば次の文では、表 person の行のみが削除されます。
TRUNCATE TABLE ONLY person
警告: TRUNCATE TABLE を使用して上位表の行を削除する場合は、ONLY キーワー
ドを使用する場合を除き、その削除範囲に上位表とそのすべての副表が含まれる
ことに注意してください。
186
IBM Informix SQL ガイド: チュートリアル
指定された行の削除
DELETE 文内の WHERE 節は、SELECT 文内の WHERE 節と同じフォームをしていま
す。WHERE 節を使用すると、どの行を削除するかを正確に指定できます。次の例が示
しているように、特定の顧客番号を持つ顧客を削除できます。
DELETE FROM customer WHERE customer_num = 175
この例では、列 customer_num が一意性制約を持っているため、複数の行が削除されな
いことを保証できます。
選択された行の削除
また、次の例が示しているように、インデックスの付いていない列をベースにしている
行を選択することもできます。
DELETE FROM customer WHERE company = ’Druid Cyclery’
テストされる列は一意性制約を持っていないため、この文は複数の行を削除する場合が
あります。Druid Cyclery は名前は同じで、顧客番号が異なる 2 つの店舗を持っている
かもしれません。
DELETE 文が影響を与える行数を知るには、Druid Cyclery の表 customer から修飾行
のカウント数を選択します。
SELECT COUNT(*) FROM customer WHERE company = ’Druid Cyclery’
また、行を選択して表示し、削除する行であることを確認することもできます。
ただし、複数のユーザが並行して使用できるデータベースの場合、SELECT 文を使用す
るテストの結果はおおよそのものでしかありません。SELECT 文を実行してから次に
DELETE 文を実行するまでの間に、行を削除しようとしている表に他のユーザが操作を
加えた可能性があるからです。この例の場合、他のユーザが次の操作をする可能性があ
ります。
v Druid Cyclery という名前で顧客番号が異なる別の顧客の行を、表に挿入する。
v 行を挿入する前に 1 つ以上の Druid Cyclery の行を削除する。
v Druid Cyclery の行を別の新しい会社名に更新したり、あるいは他の顧客の行の会社
名を Druid Cyclery に更新したりする。
この短い時間に他のユーザがこれらの操作を行う可能性は非常に低いものですが、その
可能性がまったくないわけではありません。この問題は、UPDATE 文にも影響を与えま
す。この問題に対する処置については、227 ページの『並行性およびロック』に記載し
ています。より詳細な説明が必要な場合は、 279 ページの『第 10 章 マルチユーザ環境
のためのプログラミング』を参照してください。
発生し得るもう 1 つの問題は、この文が終了する前にハードウェア障害またはソフトウ
ェア障害が発生することです。このような障害が発生すると、データベースがまったく
第 6 章 データの変更
187
行を削除しなかったか、いくつかの行を削除したか、または指定されたすべての行を削
除したかがわからなくなります。データベースの状態 は不明であり、この状況は望まし
くありません。このような状態を避けるには、221 ページの『中断された変更』で説明
されているように、トランザクション ログ機能を使用します。
行 (ROW) 型を含む行の削除 (IDS)
行 (ROW) 型で定義された列が行に含まれる場合は、ピリオド表記を使用して、特定の
フィールド値を含む行のみが削除されるように指定できます。例えば、次の文によって
削除されるのは、表 employee で、列 address のフィールド city の値が San Jose で
ある行のみです。
DELETE FROM employee
WHERE address.city = ’San Jose’
前の文では、列 address は、名前付き行型または名前なし行型です。行 (ROW) 型のフ
ィールド値を指定する構文は同じです。
コレクション (COLLECTION) 型を含む行の削除 (IDS)
コレクション (COLLECTION) 型に定義された列が行に含まれる場合は、コレクション
(COLLECTION) 型内の特定の要素を検索し、その要素を検出した行を削除することがで
きます。例えば、次の文は、Baker という要素を持つコレクションが列 direct_reports
に存在する場合、その列を含む行を削除します。
DELETE FROM manager
WHERE ’Baker’ IN direct_reports
上位表からの行の削除 (IDS)
ある上位表の行を削除する場合、削除する範囲は上位表およびその副表になります。上
位表 person を作成し、その下に 2 つの副表 employee および sales_rep を定義すると
仮定します。表 person に対する次の DELETE 文を実行すると、表 person、表
employee、および表 sales_rep のすべてから行を削除することができます。
DELETE FROM person
WHERE name =’Walker’
上位表の行のみを削除する場合は、DELETE 文で ONLY キーワードを使用します。例
えば次の文では、表 person の行のみが削除されます。
DELETE FROM ONLY(person)
WHERE name =’Walker’
警告: 上位表から行を削除する場合は、その削除範囲に上位表とそのすべての副表が含
まれることに注意してください。
188
IBM Informix SQL ガイド: チュートリアル
複雑な削除条件
DELETE 文内の WHERE 節は、SELECT 文内の場合と同じくらい複雑になることがあ
ります。この文には、複数の条件を AND および OR で接続して指定するか、副問合せ
を指定することができます。
表 stock に間違ったメーカー コードの行が含まれていることを検出した場合を考えま
す。それらの行を更新するのではなく、削除してから再入力すると仮定します。正しい
行とは異なり、これらの行は表 manufact に一致する行がありません。これらの誤った
行が表 manufact に一致する行を持っていないことから、次の例のように DELETE 文
を書くことができます。
DELETE FROM stock
WHERE 0 = (SELECT COUNT(*) FROM manufact
WHERE manufact.manu_code = stock.manu_code)
この文に含まれている副問合せ文は、表 stock のメーカー コードと一致する値を持つ
表 manufact の行の数をキーワード COUNT(*) で取り出します。副問合せは表 stock
の各行に対して行われるため、この値はメーカー コードが正しい場合は1、正しくない
場合は 0 になります。
ヒント: DELETE 文を複雑な条件で使用する方法の 1 つは、削除する行のみを正確に
戻す SELECT 文を最初に使用することです。この文は SELECT * のように記述
します。この文が目的の行セットを戻す場合は、SELECT * を DELETE に変更し
て、もう 1 度実行します。
DELETE 文の WHERE 節では、同じ表をテストする副問合せを使用することができま
せん。つまり、表 stock の行を削除する場合は、WHERE 節内で、stock の行を選択す
る副問合せを使用できません。
このルールの重要な点は FROM 節にあります。表の名前が DELETE 文の FROM 節で
指定されている場合は、この名前を DELETE 文の副問合せの FROM 節に使用するこ
とができません。
削除結合の使用 (XPS)
Extended Parallel Server では、WHERE 節に副問合せを記述する代わりに削除結合を使
用することができます。この削除結合によってさまざまな表の行を結合し、結合結果に
基づいてそれらの行をターゲット表から削除できます。
上記の例にあるように、表 stock のいくつかの行に間違ったメーカー コードが含まれ
ているのを検出した場合を考えます。それらの行を更新するのではなく、削除してから
再入力すると仮定します。その場合には、次の例にあるような削除結合問合せを使用す
ることができます。
DELETE FROM stock USING stock, manufact
WHERE stock.manu_code != manufact.manu_code
第 6 章 データの変更
189
結合される表はすべて、USING 節に表示される必要があります。ターゲット表について
は、結合に使用されない場合でも、using 節に表示される必要があります。削除結合の
詳細については、「IBM Informix: SQL ガイド: 構文」の DELETE 文の説明を参照して
ください。
行の挿入
INSERT 文は、1 つ以上の新しい行を表に追加します。この文には、2 つの基本的な機
能があります。列の値を指定して単一の新しい行を作成することができます。また、他
の表から選択したデータを使用して複数の新しい行を作成することもできます。
単一行
もっとも簡単な形式の INSERT 文は、VALUES 節に列の値の並びを 1 行記述し、それ
を表に追加するものです。次の文に、表 stock に行を追加する方法を示します。
INSERT INTO stock
VALUES (115, ’PRC’, ’tire pump’, 108, ’box’, ’6/box’)
表 stock の各列を以下に示します。
v stock_num (商品の型を示す取扱品目番号)
v manu_code (表 manufact への外部キー)
v description (商品の内容を示す品目内容)
v unit_price (商品の単価である単価)
v unit (商品の販売単位である最小販売単位)
v unit_descr (販売単位表記である単位内容)
上記の例の VALUES 節でリストされる値は、表 stock の列と 1 対 1 の対応関係を持
っています。VALUES 節は、表の各列の名前とデータ型、および順番がわかっていない
と正確に記述することはできません。
VALUES 節に指定できる値
VALUES 節では定数値のみ を受け入れ、式を受け入れません。指定できる値は以下の
とおりです。
v リテラル番号
v リテラル日時 (DATETIME) 型値
v リテラル時間隔 (INTERVAL) 型値
v 引用符付き文字列または文字
v NULL 値を表す単語 NULL
v 現在日付を表す単語 TODAY
v 現在日時を表す単語 CURRENT
v ユーザ名を表す単語 USER
190
IBM Informix SQL ガイド: チュートリアル
v データベース サーバが実行されているコンピュータ名を表す単語DBSERVERNAME
(または SITENAME)
列値の制約事項
表には、NULL が許可されない列が含まれている場合があります。このような列に
NULL を挿入すると、拒否されます。また、表の列の中には、重複値が許可されていない
ものもあります。このような列の中にすでにある値と重複する値を指定すると、その文
は拒否されます。列の中には、使用が許可されている列値でさえ制限 するものがありま
す。列を制限するには、データ整合性制約を使用します。詳しくは、209 ページの『デ
ータ整合性』を参照してください。
金額 (MONEY) 型の値を含む列には、通貨記号を指定しないでください。金額を示す数
値のみを指定してください。
データベース サーバは、数値データ型と文字 (CHARACTER) 型の変換を実行できま
す。数値データ型列の値として、数値の文字列 (’-0075.6’など) を指定することができ
ます。データベース サーバは、この数値文字列を数値に変換することができます。この
文字列が数値を表していない場合に限り、エラーが発生します。
文字 (CHARACTER) 型列の値として、数値または日付を指定できます。データベース
サーバは、その値を文字列に変換します。例えば、TODAY を文字 (CHARACTER) 型
列の値として指定すると、現在の日付を表す文字列が使用されます (使用される書式
は、DBDATE 環境変数で指定されます)。
シリアル (SERIAL) 型
シリアル (SERIAL) 型および 8 バイト シリアル (SERIAL8) 型データを設定できるの
は、それぞれ表内の 1 つの列のみです。シリアル列の値は、データベース サーバによ
って生成されます。値を挿入する時に、シリアル列に値ゼロを指定します。データベー
ス サーバは、次の実際の値を続けて生成します。シリアル (SERIAL) 型列は、NULL
値を許可しません。
シリアル (SERIAL) 型の列に対しては、その列の既存の値と同じでない限り非ゼロ値を
指定することができ、データベース サーバはその値を使用します。この非ゼロ値によっ
て、データベース サーバが生成する値に新しい開始値が設定される場合があります (デ
ータベース サーバが生成する次の値は、列内の最大値より 1 大きい値になります)。
特定の列名と値の指定
INSERT 文には、表のすべての列の値を指定する必要はありません。代わりに、表名の
後に列名をリストして、指定したそれらの列のみに値を指定することができます。次の
例では、表 stock に新しい行を挿入する文を示します。
INSERT INTO stock (stock_num, description, unit_price,
VALUES (115, ’tyre pump ’, 114, ’SHM’)
manu_code)
第 6 章 データの変更
191
在庫番号、説明、単価およびメーカー コードのデータのみが提供されています。データ
ベース サーバは次のルールに従って、残りの列に値を提供します。
v リストされていないシリアル (SERIAL) 型の列の場合は、シリアル番号を生成しま
す。
v 列に固有なデフォルト値が存在する場合は、その値を生成します。
v NULL を許可する列には NULL 値が生成されますが、デフォルト値として NULL
を指定する列にはデフォルト値の指定は行われません。
つまり、デフォルト値が指定されていない列や、NULL を許可しない列に対しては、
必ず値を指定する必要があります。
それらの列は、値が同じ順序でリストされる限りは、どんな順序でもリストできます。
列に対して NULL 値またはデフォルト値を指定する方法については、「IBM Informix:
データベース設計および実装 ガイド」を参照してください。
前例の INSERT 文が実行された後、次に示す新しい行が表 stock に挿入されます。
stock_num manu_code
115
SHM
description
tyre pump
unit_price unit unit_descr
114
unit と unit_descr はいずれも空白で、この 2 つの列に NULL 値が存在することを示
します。列 unit は NULL 値を許可するため、$114 で購入できるタイヤ ポンプの数は
不明です。もちろん、box のデフォルト値がこの列に対して指定された場合は、box が
販売単位になります。いずれにしても、表の特定の列に値を挿入する場合は、その行に
どんなデータが必要であるかに注意を払ってください。
型付き表への行の挿入 (IDS)
行 (ROW) 型に基づかない表に行を挿入する場合と同じ方法で、型付き表に行を挿入す
ることができます。
型付き表に行 (ROW) 型列が含まれる場合、(型付き表を定義する名前付き行型に入れ子
の行 (ROW) 型が含まれる)、その行 (ROW) 型列への行の挿入は、行 (ROW) 型に基づ
かない表の行 (ROW) 型列に挿入するのと同じ方法で行います。 193 ページの『行
(ROW) 型列への挿入 (IDS)』では、行 (ROW) 型列への挿入の方法を説明します。
ここでは、例に行 (ROW) 型 zip_t、address_t、および employee_t、そして型付き表
employee を使用します。図 350 に、行 (ROW) 型および表を作成する SQL 構文を示
します。
192
IBM Informix SQL ガイド: チュートリアル
CREATE ROW TYPE zip_t
(
z_code
CHAR(5),
z_suffix CHAR(4)
);
CREATE ROW TYPE address_t
(
street
VARCHAR(20),
city
VARCHAR(20),
state
CHAR(2),
zip
zip_t
);
CREATE ROW TYPE employee_t
(
name
VARCHAR(30),
address
address_t,
salary
INTEGER
);
CREATE TABLE employee OF TYPE employee_t;
図 350.
行 (ROW) 型列への挿入 (IDS)
次の構文規則は、名前付き行型または名前なし行型で定義される列への挿入に適用され
ます。
v ROW コンストラクタを挿入するフィールド値の前に指定します。
v 行 (ROW) 型のフィールド値を括弧で囲みます。
v 行式を適切な名前付き行型にキャストします (名前付き行型の場合)。
名前付き行型を含む行
次の文は、194 ページの図 351 の表 employee に行を挿入する方法を示します。
INSERT INTO employee
VALUES (’Poole, John’,
ROW(’402 High St’, ’Willits’, ’CA’,
ROW(69055,1450))::address_t, 35000 )
employee 表の address 列は名前付き行型であるため、キャスト演算子、および行
(ROW) 型の名前である address_t を使用して、address_t 型の値を挿入する必要があり
ます。
第 6 章 データの変更
193
名前なし行型を含む行
図 351 に示す表を作成すると仮定します。表 student は、列 s_address を名前なし行
型として定義します。
CREATE TABLE student
(
s_name
VARCHAR(30),
s_address ROW(street VARCHAR (20), city VARCHAR(20),
state CHAR(2), zip VARCHAR(9)),
grade_point_avg DECIMAL(3,2)
);
図 351.
次の文は、表 student に行を追加する方法を示します。名前なし行型列 s_address に挿
入するには、行 (ROW) 型コンストラクタを使用しますが、行 (ROW) 型値のキャスト
は行いません。
INSERT INTO student
VALUES (’Keene, Terry’,
ROW(’53 Terra Villa’, ’Wheeling’, ’IL’, ’45052’),
3.75)
行 (ROW) 型への NULL 値の指定
行 (ROW) 型列のフィールドには、NULL 値を含めることができます。NULL 値は、列
またはフィールドのいずれのレベルでも指定できます。
次の文では、列レベルで NULL 値を指定して、s_address 列のすべてのフィールドに
NULL 値を挿入します。列レベルで NULL 値を挿入する場合は、行 (ROW) 型コンス
トラクタを含めることができません。
INSERT INTO student VALUES (’Brauer, Howie’, NULL, 3.75)
行 (ROW) 型の特定のフィールドに NULL 値を挿入する場合は、行 (ROW) 型コンス
トラクタを含める必要があります。次の INSERT 文は、表 employee の列 address の
特定フィールドに NULL 値を挿入する方法を示しています。ここで、address 列は、名
前付き行型として定義されています。
INSERT INTO employee
VALUES (
’Singer, John’,
ROW(NULL, ’Davis’, ’CA’,
ROW(97000, 2000))::address_t, 67000
)
194
IBM Informix SQL ガイド: チュートリアル
行 (ROW) 型のフィールドに NULL 値を指定する場合、行 (ROW) 型が INSERT 文、
UPDATE 文、またはプログラム変数の代入に使用される場合は、NULL 値を明示的に
キャストする必要はありません。
次の INSERT 文は、student 表の s_address 列の street フィールドと zip フィールド
に NULL 値を挿入する方法を示しています。
INSERT INTO student
VALUES(
’Henry, John’,
ROW(NULL, ’Seattle’, ’WA’, NULL), 3.82
)
上位表への行の挿入 (IDS)
上位表に行を挿入する場合、特別な注意事項はありません。INSERT 文は、その文で指
定される表のみに適用されます。例えば次の文を実行すると、上位表に値が挿入されま
すが、副表には挿入されません。
INSERT INTO person
VALUES (
’Poole, John’,
ROW(’402 Saphire St.’, ’Elmondo’, ’CA’, ’69055’),
345605900
)
列へのコレクション (COLLECTION) 型値の挿入 (IDS)
ここでは、DB–Access で列にコレクション (COLLECTION) 型値を挿入する方法を説明
します。個々の要素をコレクション (COLLECTION) 型列に挿入する方法については説
明しません。コレクションの個々の要素にアクセスまたは修正を加える場合は、ESQL/C
プログラムまたは SPL ルーチンを使用します。ESQL/C プログラムを作成してコレク
ションに挿入する方法については、「IBM Informix: ESQL/C Programmer’s Manual」を
参照してください。SPL ルーチンを作成してコレクションに挿入する方法については、
第 11 章を参照してください。
ここで示す例は、図 352 の表 manager に基づいています。表 manager には、単純コ
レクション (COLLECTION) 型と、入れ子コレクション (COLLECTION) 型が含まれて
います。
第 6 章 データの変更
195
CREATE TABLE manager
(
mgr_name
VARCHAR(30),
department
VARCHAR(12),
direct_reports SET(VARCHAR(30) NOT NULL),
projects
LIST(ROW(pro_name VARCHAR(15),
pro_members SET(VARCHAR(20) NOT NULL))
NOT NULL)
);
図 352.
単純コレクション (COLLECTION) 型および入れ子コレクション
(COLLECTION) 型への挿入
コレクション (COLLECTION) 型列を含む行に値を挿入する場合は、そのコレクション
(COLLECTION) 型が含むすべての要素の値を、他の列の値と同様に挿入します。例えば
次の文は、単一の行を表 manager に挿入します。この表には、単純コレクション
(COLLECTION) 型列と、入れ子コレクション (COLLECTION) 型列の両方が含まれま
す。
INSERT INTO manager(mgr_name, department, direct_reports,
projects)
VALUES
(
’Sayles’, ’marketing’,
"SET{’Simonian’, ’Waters’, ’Adams’, ’Davis’, ’Jones’}",
LIST{
ROW(’voyager_project’, SET{’Simonian’, ’Waters’,
’Adams’, ’Davis’}),
ROW (’horizon_project’, SET{’Freeman’, ’Jacobs’,
’Walker’, ’Smith’, ’Cannan’}),
ROW (’saphire_project’, SET{’Villers’, ’Reeves’,
’Doyle’, ’Strongin’})
}
)
行 (ROW) 型を含むコレクション (COLLECTION) 型への NULL 値の挿入
行 (ROW) 型であるコレクション (COLLECTION) 型に値を挿入するには、行 (ROW)
型の各フィールドに対して値を指定する必要があります。
通常、コレクション (COLLECTION) 型では NULL 値は許可されません。ただし、コ
レクション (COLLECTION) 型の要素の型が行 (ROW) 型である場合は、行 (ROW) 型
の個々のフィールドに NULL 値を挿入できます。
空のコレクション (COLLECTION) 型を指定することもできます。空のコレクション
(COLLECTION) 型 は、要素を含みません。空のコレクション (COLLECTION) 型を指
196
IBM Informix SQL ガイド: チュートリアル
定するには、中括弧 ({}) を使用します。例えば次の文は、表 manager の行にデータを
挿入しますが、列 direct_reports および projects が空のコレクション (COLLECTION)
型になるように指定します。
INSERT INTO manager
VALUES (’Sayles’, ’marketing’, "SET{}",
"LIST{ROW(NULL, SET{})}"
)
コレクション (COLLECTION) 型列に NULL の要素を含めることはできません。次の
文を実行するとエラーが戻されますが、これは、コレクション (COLLECTION) 型の要
素として NULL 値が指定されているためです。
INSERT INTO manager
VALUES (’Cole’, ’accounting’, "SET{NULL}",
"LIST{ROW(NULL, ""SET{NULL}"")}"
次の構文規則は、コレクション (COLLECTION) 型に対して挿入または更新を行う場合
に適用されます。
v 中括弧 ({}) を使用して、各コレクション (COLLECTION) 型に含まれる要素を区別
します。
v コレクション (COLLECTION) 型が入れ子になっている場合は、中括弧 ({}) を使用
して、内部コレクション (COLLECTION) 型および外部コレクション (COLLECTION)
型両方の要素を区別します。
スマート ラージ オブジェクトの挿入 (IDS)
INSERT 文を使用して BLOB 型または CLOB 型列にオブジェクトを挿入する場合、
データベース サーバは表ではなく、SB 領域に、そのオブジェクトを格納します。デー
タベース サーバには、INSERT 文の中から呼び出すことができ、スマート ラージ オブ
ジェクトとして知られる BLOB 型または CLOB 型のデータをインポートまたはエクス
ポートできる 4 つの SQL 関数があります。これらの関数については、116 ページを参
照してください。
次の INSERT 文では、filetoblob() 関数および filetoclob() 関数を使用して、表 inmate
の行を挿入します (表 inmate は、117 ページの図 216 で定義しています)。
INSERT INTO inmate
VALUES (437, FILETOBLOB(’datafile’, ’client’),
FILETOCLOB(’tmp/text’, ’server’))
この例では、FILETOBLOB() 関数と FILETOCLOB() 関数の最初の引数が、それぞ
れ、表 inmate の BLOB 型および CLOB 型列にコピーされるソース ファイルのパス
を指定します。それぞれの関数の 2 番目の引数で、ソース ファイルがクライアント コ
ンピュータ (’client’) とサーバ コンピュータ (’server’) のどちらに配置されているのか
を示します。ファイル名のパスを関数の引数で指定する場合は、次のルールが適用され
ます。
第 6 章 データの変更
197
v ソース ファイルがサーバ コンピュータに存在する場合は、現在の作業ディレクトリ
への相対パス名ではなく、そのファイルへのフルパス名を指定する必要があります。
v ソース ファイルがクライアント コンピュータに存在する場合は、そのファイルへの
フルパス名または相対パス名のどちらでも指定することができます。
複数の行の挿入および式の使用
INSERT 文では、VALUES 節を SELECT 節に置き換えることもできます。この形式の
特徴は、次のようなデータを挿入できることです。
v 文が 1 つだけある複数の行。SELECT 文が 1 行を戻すたびに 1 行が挿入される
v 計算結果 (VALUES 節は定数のみを許可)。射影リストは式を含むことができる
例えば、決済は済んだが出荷が済んでいない注文について、出荷要求の電話連絡を行う
必要が生じたと仮定します。次の例の INSERT 文は、該当する注文を検出し、各注文に
対応する行を表 cust_calls に挿入します。
INSERT INTO cust_calls (customer_num, call_descr)
SELECT customer_num, order_num FROM orders
WHERE paid_date IS NOT NULL
AND ship_date IS NULL
この SELECT 文は 2 つの列を戻します。表 orders から選択された各行のこれらの列
のデータは、表 cust_calls の指定された列に挿入されます。次に、シリアル (SERIAL)
型の order_num 列からの注文番号が呼出し記述に挿入されますが、これは文字
(CHAR) 型の列です。整数値を文字 (CHAR) 型の列に挿入することは可能です。データ
ベース サーバが自動的にシリアル値を 10 進数の文字列に変換します。
INSERT 文に SELECT 文を使用する場合の制約
SELECT 文を使用して行を挿入する場合、以下の制約事項があります。
v INTO 節を使用できない。
v INTO TEMP 節を使用できない。
v ORDER BY 節を使用できない。
v 行を挿入する表を参照できない。
Extended Parallel Server
Extended Parallel Server では、INSERT SELECT 文に、ORDER BY 節を含む SELECT
文を使用できます。
Extended Parallel Server の終り
INTO、INTO TEMP、および ORDER BY 節に関する制約事項は、マイナーなもので
す。ただし、このコンテキストでは INTO 節はあまり役立ちません (詳しくは、第 8
章を参照してください)。INTO TEMP 節の制約を回避するには、まず、一時表に挿入す
198
IBM Informix SQL ガイド: チュートリアル
るデータを選択し、INSERT 文を使用して、そのデータを一時表から挿入します。同様
に、ORDER BY 節を使用できないことも大きな問題ではありません。新しい行を表内
で物理的に順序付ける必要がある場合は、まずこれらの行を選択して一時表に入れて順
序付け、次に一時表から挿入することができます。また、すべての挿入が完了した後で
クラスタ化インデックスを使用し、物理的な順序を表に適用することもできます。
重要: 最後制限により、INSERT 文の INTO 節と SELECT 文の FROM 節の両方に同
じ表を指定できなくなるため、この制限はより重要です。INSERT 文の INTO 節
と、SELECT 文の FROM 節に同じ表を指定すると、データベース サーバはエン
ドレス ループに陥り、挿入された各行の選択と挿入が繰り返されます。
しかし、データを挿入しなければならない表そのものから選択する場合もあります。例
えば、Nikolus 社が Anza 社と同じ製品を半額で提供していることがわかった場合を考
えます。この 2 つの会社の相違を反映するために、表 stock に行を追加することにな
ります。表 stock の行から Anza 社のすべてのデータを選択し、それを Nikolus 社のメ
ーカー コードで再び挿入するのが最良の方法です。しかし、挿入対象の表から選択する
ことはできません。
この制限を回避するには、一時表に挿入するデータを選択します。そして、次の例に示
すように、INSERT 文にあるその一時表から選択します。
SELECT stock_num, ’NIK’ temp_manu, description, unit_price/2
half_price, unit, unit_descr FROM stock
WHERE manu_code = ’ANZ’
AND stock_num < 110
INTO TEMP anzrows;
INSERT INTO stock SELECT * FROM anzrows;
DROP TABLE anzrows;
この SELECT 文は、表 stock から既存の行を取り出し、メーカー コードをリテラル値
で、単価を計算値で置き換えます。次に、これらの行を一時表 anzrows に保存します。
これは、ただちに表 stock に挿入されます。
複数の行を挿入する場合は、1 行でも無効なデータが含まれていると、データベース サ
ーバがエラーをレポートします。この種のエラーが発生すると、この文は早期に終了し
ます。たとえエラーが発生しない場合でも、この文の実行中にハードウェアまたはソフ
トウェアの障害が発生する危険性が、非常に低いとはいえ存在します。例えば、ディス
クがフルになる可能性があります。
いずれの場合でも、新しい行が何行挿入されたかは簡単にはわかりません。文全体を繰
り返し実行すると、行が重複して作成されてしまうことがあるかもしれません。データ
ベースの状態がわからないため、対処方法も判断できません。この問題を解決するに
は、トランザクションを使用します。221 ページの『中断された変更』で説明します。
第 6 章 データの変更
199
行の更新
表に含まれる既存の行の列の内容を変更するには、UPDATE 文を使用します。この文に
は、基本的に異なる 2 つの形式があります。1 つの形式では、特定の値を名前によって
列に割り当てることができます。もう 1 つの形式では、SELECT 文によって戻される
値の並びを列の並びに割り当てることができます。いずれの形式でも、行を更新してい
る場合にいくつかの列にデータ整合性制約が設定されていれば、変更するデータはこれ
らの制約を満たすものでなければなりません。詳しくは、209 ページの『データ整合
性』を参照してください。
更新対象の行の選択
UPDATE 文のいずれの書式も、末尾に、変更する行を決定する WHERE 節を指定でき
ます。WHERE を省略した場合、すべての行が変更されます。変更が必要な行セットを
正確に選択する場合は、WHERE 節が非常に複雑になることがあります。WHERE 節に
対する唯一の制限は、更新中の表を副問合せ文の FROM 節の中では指定できないとい
うことです。
UPDATE 文の最初の形式は、次の例が示しているように、一連の代入節を使用して新し
い列の値を指定します。
UPDATE customer
SET fname = ’Barnaby’, lname = ’Dorfler’
WHERE customer_num = 103
WHERE 節で更新する行を選択します。デモンストレーション データベースでは、列
customer.customer_num はその表の主キーであるため、この文で更新できるのは 1 行
のみです。
WHERE 節では、副問合せも使用できます。Anza 社がテニス ボールの不良品を回収す
る場合を考えます。その結果、次の例が示しているように、在庫番号 6 を含むメーカー
ANZ からの未出荷の注文は、受注残に加えられなければなりません。
UPDATE orders
SET backlog = ’y’
WHERE ship_date IS NULL
AND order_num IN
(SELECT DISTINCT items.order_num FROM items
WHERE items.stock_num = 6
AND items.manu_code = ’ANZ’)
この UPDATE 文の副問合せ文は、ゼロまたはいくつかの注文番号を戻します。
UPDATE 文は、表 orders の各行をこの注文番号と突き合わせ、その行の注文番号が一
致すれば更新を実行します。
一様値を使用する更新
キーワード SET の後の代入式は、列に新しい値を指定します。その値は、更新するど
の行にも一様に適用されます。前の項の例では新しい値は定数でしたが、その列の値自
200
IBM Informix SQL ガイド: チュートリアル
体をベースにした式も含め、どんな式でも割り当てることができます。メーカー コード
HRO がすべての価格を 5% 上げたため、この値上げを反映するために、表 stock を更
新しなければならないと仮定します。次の文を使用します。
UPDATE stock
SET unit_price = unit_price * 1.05
WHERE manu_code = ’HRO’
式の一部に副問合せ文を使用することもできます。式の一部として副問合せ文を使用す
る場合、その文は値を 1 つだけ戻すものでなければなりません。1 つというのは、1 列
からなる 1 行のみということです。おそらく、どの在庫番号に対しても、その製品につ
いてはどのメーカーよりも高い価格を付けなければならないことを決定するでしょう。
この場合、未出荷の注文すべてについて価格を更新しなければなりません。次の例で
は、SELECT 文で基準を指定します。
UPDATE items
SET total_price = quantity *
(SELECT MAX (unit_price) FROM stock
WHERE stock.stock_num = items.stock_num)
WHERE items.order_num IN
(SELECT order_num FROM orders
WHERE ship_date IS NULL)
最初の SELECT 文は、特定の製品に関して表 stock 内で最も高い価格を表す値を 1 つ
戻します。最初の SELECT 文は、相関副問合せです。これは、最初の SELECT 文の
WHERE 節に items 表の値が使用されている場合、更新対象の行ごとに問合せを実行す
る必要があるためです。
2 つ目の SELECT 文は、未出荷の注文の注文番号を取り出します。この SELECT 文は
非相関副問合せ文のため、1 回実行されるのみです。
更新の制限
データを変更する場合の副問合せ文の使用については、いくつかの制限があります。特
に重要なのは、変更されている表に対しては問合せができないことです。列 unit_price
を 5% 増加させた例のように、列の現在の値を式の中で参照することができます。表
stock を更新する例 (表 items を更新して items.stock_num を結合式内で使用する) の
ように、副問合せ の WHERE 節内の列値を参照することができます。
Extended Parallel Server
Extended Parallel Server では、UPDATE 文の SET 節で副問合せを使用できません。
Extended Parallel Server の終り
適切に設計されたデータベースでは、同じ表に対する更新と問合せが同時に行われるこ
とはほとんどありません (データベース設計の詳細については、「IBM Informix: データ
ベース設計および実装 ガイド」を参照してください)。しかし、データベースを初めて
第 6 章 データの変更
201
設計するときには、データベース設計を熟考する前に、更新と問合せを同時に実行する
場合もあります。一意でなければならない列の中に重複値がある行が表内にいくつか誤
って含まれているような場合に、典型的な問題が発生します。この場合には、重複行を
削除するか、重複行のみを更新する必要が生じます。いずれの方法でも、重複行をテス
トする場合は、UPDATE 文または DELETE 文で許可されていない、同じ表に対する副
問合せが必要になります。第 9 章では、UPDATE カーソル を使用して、この種の変更
を実行する方法について説明します。
選択値を使用する更新
2 つ目の形式の UPDATE 文は、一連の代入を 1 つの代入にまとめて置き換えたもので
す。ここでは、列の並び順が値の並び順と等しくなるように設定してください。次の例
が示しているように、値が簡単な定数の場合には、この形式はその部分が再配置されて
いる上記の例の形式と大差がありません。
UPDATE customer
SET (fname, lname) = (’Barnaby’, ’Dorfler’)
WHERE customer_num = 103
文を前記のように記述しても利点はまったくありません。実際には、どの列にどの値が
代入されるかが明らかでないために、読みにくくなります。
ただし、代入される値が 1 つの SELECT 文から取得できるのであれば、この形式を使
用する意味があります。次の例では、数人の顧客の住所を変更しています。住所の変更
があるたびに表 customer を更新せずに、新しい住所を newaddr という名前の一時表
にいったん格納してあると仮定します。この一時表は、表 customer の顧客番号と住所
に関連するフィールドから構成されています。この一時表に格納された新しい住所を、
ある時点で一括して表 customer に反映します。
UPDATE customer
SET (address1, address2, city, state, zipcode) =
((SELECT address1, address2, city, state, zipcode
FROM newaddr
WHERE newaddr.customer_num=customer.customer_num))
WHERE customer_num IN (SELECT customer_num FROM newaddr)
1 つの SELECT 文により、複数の列値が生成されます。この例を、更新対象の各列ご
とに 1 つの代入文を使用するもう 1 つの形式で書き直すには、更新する個々の列ごと
に 1 つずつ、合計で 5 つの SELECT 文を記述しなければなりません。そのような文
の記述は難しいだけではなく、実行時間も長くなります。
ヒント: SQL API プログラムでは、レコードまたはホスト変数を使用して値を更新でき
ます。詳しくは、第 8 章を参照してください。
202
IBM Informix SQL ガイド: チュートリアル
行 (ROW) 型の更新 (IDS)
行 (ROW) 型値を更新する構文は、対象の列が名前付き行型か名前なし行型かによって
多少異なります。ここでは、それらの違いについて説明します。また、行 (ROW) 型の
フィールドに NULL 値を指定する方法についても説明します。
名前付き行型を含む行の更新
名前付き行型で定義された列を更新するには、行 (ROW) 型のすべてのフィールドを指
定する必要があります。例えば次の文は、employee 表にある address 列の street フィ
ールドと city フィールドのみを更新しますが、その行 (ROW) 型の各フィールドには値
が含まれている必要があります。NULL 値も指定できます。
UPDATE employee
SET address = ROW(’103 California St’,
San Francisco’, address.state, address.zip)::address_t
WHERE name = ’zawinul, joe’
この例では、フィールド state および zip の値が読み取られ、その後ただちに行に再挿
入されます。更新されるのは、列 address のフィールド street および city のみです。
名前付き行型で定義された列のフィールドを更新する場合は、行 (ROW) 型コンストラ
クタを使用して、行の値を適切な名前付き行型にキャストする必要があります。
名前なし行型を含む行の更新
名前なし行型で定義された列を更新するには、行 (ROW) 型のすべてのフィールドを指
定する必要があります。例えば次の文は、student 表にある address 列の street フィー
ルドと city フィールドのみを更新しますが、その行 (ROW) 型の各フィールドには値が
含まれている必要があります。NULL 値も指定できます。
UPDATE student
SET s_address = ROW(’13 Sunset’, ’Fresno’,
s_address.state, s_address.zip)
WHERE s_name = ’henry, john’
名前なし行型に対して定義された列のフィールドを更新するには、フィールド値が挿入
される前に必ず行 (ROW) 型コンストラクタを指定する必要があります。
行 (ROW) 型のフィールドに対する NULL 値の指定
行 (ROW) 型列のフィールドには、NULL 値を含めることができます。NULL 値を持つ
行 (ROW) 型フィールドに対して挿入または更新を行う場合は、その値を、そのフィー
ルドのデータ型にキャストする必要があります。
次の UPDATE 文は、名前付き行型列の特定のフィールドに NULL 値を指定する方法
を示しています。
UPDATE employee
SET address = ROW(NULL::VARCHAR(20), ’Davis’, ’CA’,
ROW(NULL::CHAR(5), NULL::CHAR(4)))::address_t)
WHERE name = ’henry, john’
第 6 章 データの変更
203
次の UPDATE 文は、student 表の address 列の street および zip フィールドに
NULL 値を指定する方法を示します。
UPDATE student
SET address = ROW(NULL::VARCHAR(20), address.city,
address.state, NULL::VARCHAR(9))
WHERE s_name = ’henry, john’
重要: 行 (ROW) 型列に対して NULL 値を指定することはできません。NULL 値を指
定できるのは、行 (ROW) 型の個々のフィールドに対してのみです。
コレクション (COLLECTION) 型の更新 (IDS)
DB–Access を使用してコレクション (COLLECTION) 型を更新する場合、コレクション
全体を更新する必要があります。次の文は、列 projects を更新する方法を示していま
す。更新する必要のある行を探すには、IN キーワードを使用して、列 direct_reports
に対する検索を実行します。
UPDATE manager
SET projects = "LIST
{
ROW(’brazil_project’, SET{’Pryor’, ’Murphy’, ’Kinsley’,
’Bryant’}),
ROW (’cuba_project’, SET{’Forester’, ’Barth’, ’Lewis’,
’Leonard’})
}"
WHERE ’Williams’ IN direct_reports
この文で SET キーワードが最初に現れるのは、UPDATE 文の中です。
ヒント: UPDATE 文の SET キーワードと、コレクションがセット (SET) 型であること
を示す SET コンストラクタを混同しないようにしてください。
キーワード IN を使用して、単純コレクション (COLLECTION) 型の特定の要素を探す
ことはできますが、コレクション (COLLECTION) 型列の個々の要素を DB–Access で
更新することはできません。ただし、ESQL/C プログラムおよび SPL ルーチンを作成
して、コレクション内の要素を更新することは可能です。ESQL/C プログラムを作成し
てコレクションを更新する方法については、「IBM Informix: ESQL/C Programmer’s
Manual」を参照してください。SPL ルーチンを作成してコレクションを更新する方法に
ついては、349 ページの『コレクションの処理 (IDS)』を参照してください。
上位表の行の更新 (IDS)
上位表の行を更新する場合、その更新範囲は上位表とその副表になります。
上位表に対して UPDATE 文を作成すると、その上位表にあるすべての列と、その上位
表から継承を行う副表の列を更新することができます。例えば次の文では、表 employee
および表 sales_rep の行が更新されます。これらは、上位表 person の副表です。
204
IBM Informix SQL ガイド: チュートリアル
UPDATE person
SET salary=65000
WHERE address.state = ’CA’
ただし、上位表を更新しても、その副表の列が上位表にない場合は、その列は更新され
ません。例えば前に示した UPDATE 文では、表 sales_rep の列 region_num を更新す
ることができません。これは、列 region_num が表 employee に存在しないためです。
上位表に対する更新を実行する場合は、その更新の範囲について注意する必要がありま
す。例えば、表 person に対する UPDATE 文に、更新する行を制限する WHERE 節が
含まれない場合、その UPDATE 文は、表 person、表 employee、および表 sales_rep
のすべての行を変更します。
上位表の行のみを更新するには、UPDATE 文でキーワード ONLY を使用する必要があ
ります。例えば次の文では、表 person の行のみが更新されます。
UPDATE ONLY(person)
SET address = ROW(’14 Jackson St’, ’Berkeley’,
address.state, address.zip)
WHERE name = ’Sallie, A.’
警告: 上位表の行を更新する場合は、その更新範囲に上位表とそのすべての副表が含ま
れることに注意してください。
CASE 式による列の更新
CASE 式により、いくつかの条件テストのどれが TRUE と評価されるかによって、文
はいくつかの可能な結果の 1 つを戻すことができます。
次の例は、UPDATE 文の CASE 文を使用して、表 stock にある項目の単価を上げる方
法を示しています。
UPDATE stock
SET unit_price = CASE
WHEN stock_num = 1
AND manu_code = "HRO"
THEN unit_price = unit_price * 1.2
WHEN stock_num = 1
AND manu_code = "SMT"
THEN unit_price = unit_price * 1.1
ELSE 0
END
CASE 式には、必ず 1 つ以上の WHEN 節をインクルードします。後続の WHEN 節お
よび ELSE 節はオプションです。WHEN 条件が TRUE と評価しない限り、結果の値は
NULL です。
第 6 章 データの変更
205
SQL 関数を使用したスマート ラージ オブジェクトの更新 (IDS)
UPDATE 文の中で SQL 関数を呼び出して、スマート ラージ オブジェクトをインポー
トまたはエクスポートすることができます。これらの関数については、116 ページを参
照してください。
次の UPDATE 文は、LOCOPY() 関数を使用して、BLOB 型データを、表 fbi_list の列
mugshot から表 inmate の列 picture にコピーします (表 inmate および表 fbi_list
は、117 ページの図 216 で定義しています)。
UPDATE inmate (picture)
SET picture = (SELECT LOCOPY(mugshot, ’inmate’, ’picture’)
FROM fbi_list WHERE fbi_list.id = 669)
WHERE inmate.id_num = 437
LOCOPY() の最初の引数は、このオブジェクトのエクスポート元の列 mugshot を指定
するものです。2 番目と 3 番目の引数では、新しく作成されるオブジェクトで使用する
格納特性を持つ表 inmate および列 picture の名前を指定します。UPDATE 文を実行す
ると、列 mugshot のデータが列 picture に格納されます。
関数の引数でファイル名のパスを指定する場合には、次のルールが適用されます。
v ソース ファイルがサーバ コンピュータに存在する場合は、現在の作業ディレクトリ
への相対パス名ではなく、そのファイルへのフルパス名を指定する必要があります。
v ソース ファイルがクライアント コンピュータに存在する場合は、そのファイルへの
フルパス名または相対パス名のどちらでも指定することができます。
結合を使用した列の更新
Extended Parallel Server により、表の結合を使用して、どの列を更新するかを決定する
ことができます。更新する列と行の値を指定するために、SET 節の FROM 節にリスト
表示されたどの表からも列を使用できます。
FROM 節を使用する場合、更新が実行される表の名前を含めなければなりません。その
他の場合は、エラーとなります。次の例に、FROM を含む UPDATE 文の使用方法を示
します。
UPDATE t SET a = t2.a FROM t, t2 WHERE t.b = t2.b
この例の文では、FROM 節が省略される場合と同じ処理を実行します。UPDATE 文の
FROM 節には、複数の表を指定できます。しかし、表を 1 つだけ指定する場合、それ
はターゲット表になります。
206
IBM Informix SQL ガイド: チュートリアル
データベースとそのオブジェクトに対するアクセス権
次のデータベース アクセス権を使用して、データベースへのアクセスを制御できます。
v データベース レベル アクセス権
v 表レベル アクセス権
v ルーチン レベル アクセス権
v 言語レベル アクセス権
v 型レベル アクセス権
v シーケンス レベル アクセス権
ここでは、データベース レベル アクセス権と表レベル アクセス権について、簡単に説
明します。データベース アクセス権の詳細については、「IBM Informix: データベース
設計および実装 ガイド」を参照してください。アクセス権のリスト、および GRANT
文と REVOKE 文の説明については、「IBM Informix: SQL ガイド: 構文」を参照して
ください。
データベース レベル アクセス権
データベースを作成する場合は、データベースの所有者またはデータベース管理者
(DBA) がデータベース レベル アクセス権を付与しない限り、他のユーザはデータベー
スにアクセスできません。次に、データベース レベル アクセス権を示します。
アクセス権
内容
Connect
データベースのオープン、問合せの発行、および一時表のインデック
スの作成と配置を行うことができます。
Resource
永続表を作成することができます。
DBA
DBA として、いくつかの追加機能を実行することができます。
表レベル アクセス権
ANSI 標準に準拠しないデータベースに表を作成すると、表の所有者が特定のユーザか
らの表レベルのアクセス権を取り消さない限り、すべてのユーザがその表へのアクセス
権を持つことになります。次の表は、ユーザが表へアクセスする場合の4つのアクセス権
を示しています。
アクセス権
内容
Select
表ごとに与えられる権限で、表から行を選択することができます。こ
のアクセス権は、表の特定の列のみに制限することもできます。
Delete
行を削除することができます。
Insert
行を挿入することができます。
Update
既存の行を更新する、つまり行の内容を変更することができます。
第 6 章 データの変更
207
多くの場合、データベースと表を作成したユーザは、Connect アクセス権および Select
アクセス権を public に与えて、すべてのユーザがそれらの権限を保有できるようにし
ます。表に対して問合せができるということは、そのデータベースと表について少なく
とも Connect アクセス権と Select アクセス権を持っていることになります。
データを変更するには、その他の表レベルアクセス権が必要です。多くの場合、表の所
有者だけがこれらの権限を持っているか、または特定のユーザだけに付与されていま
す。その結果、自由に問合せができる一部の表を変更できない場合があります。
これらのアクセス権は表ごとに設定できるため、例えばある表については Insert アクセ
ス権のみを持ち、他の表については Update アクセス権のみを持っているということも
あります。Update アクセス権は、表の特定の列のみに制限することもできます。
上記、または上記以外の表レベル アクセス権の詳細については、「IBM Informix: デー
タベース設計および実装 ガイド」を参照してください。
表アクセス権の表示
表の所有者、つまり作成者は、その表についてのすべてのアクセス権を持っています。
表の所有者でない場合は、システム カタログへの問合せによって、その表に対して持っ
ているアクセス権を調べることができます。システム カタログは、データベース構造を
記述するシステム表で構成されています。個々の表に対して付与されたアクセス権は、
システム表 systabauth に記録されています。これらのアクセス権を表示するには、こ
の表の一意な識別子番号を知っていなければなりません。この番号は、システム表
systables に指定されています。表 orders に対して付与されているアクセス権を表示す
るには、次の SELECT 文を入力します。
SELECT * FROM systabauth
WHERE tabid = (SELECT tabid FROM systables
WHERE tabname = ’orders’)
この問合せの出力は、次のようになります。
grantorgrantee tabid
tfecitmutator 101
tfecitprocrustes101
tfecitpublic
101
tabauth
su-i-x-s--idx-s--i-x--
grantor (権限授与者) はアクセス権を付与 したユーザです。通常、権限授与者はその表
の所有者ですが、権限授与者によって権限を与えられた別のユーザが所有者である場合
もあります。列 grantee に表示されるユーザは、アクセス権を付与された被権限授与者
であり、grantee public とは、「Connect アクセス権を持つすべてのユーザ」です。ユー
ザ名がここに記載されていないユーザは、パブリックに与えられたアクセス権以外は所
有していません。
列 tabauth に表示される文字列は、付与されたアクセス権を示します。この列の各行の
文字はアクセス権の名前の頭文字を表しますが、例外的に i は挿入 (Insert) を意味し、
208
IBM Informix SQL ガイド: チュートリアル
x はインデックス (Index) を意味します。この例では、public に Select、Insert、および
Index のアクセス権が与えられています。Update アクセス権を持つのはユーザ mutator
のみで、Delete アクセス権を持つのはユーザ procrustes のみです。
DELETE 文の実行など、ユーザが何らかの処理を行う場合、データベース サーバはそ
の処理を実行する前に、この例のように問合せを行います。ユーザが表の所有者でない
場合、またデータベース サーバがユーザ名に対してもパブリックに対しても表に対する
必要なアクセス権を与えていない場合は、その処理の実行は拒否されます。
ロールへのアクセス権の付与
DBA は、ロールを作成して、ユーザのクラスに付与されるアクセス権を標準化できま
す。DBA がロールにアクセス権を割り当てると、そのロールのすべてのユーザにその
アクセス権が付与されます。ロールの定義と操作に使用する SQL 文には、CREATE
ROLE、DROP ROLE、GRANT、REVOKE、および SET ROLE があります。ロールの
定義と操作のための SQL 構文の詳細については、「IBM Informix: SQL ガイド: 構文」
を参照してください。
デフォルト ロール は、特定のユーザおよびグループがデータベースに接続すると自動
的に適用されるため、ユーザは SET ROLE 文を発行する必要はありません。次に例を
示します。
GRANT DEFAULT ROLE manager TO larry;
ロールとデフォルト ロールの詳細については、 6 ページの『データベース利用の制御』
または「IBM Informix: Dynamic Server 管理者ガイド」を参照してください。
アクセス権の付与と取消しの詳細については、 261 ページの『アプリケーションでのア
クセス権の付与と取消し』を参照してください。「IBM Informix: データベース設計およ
び実装 ガイド」も参照してください。
データ整合性
INSERT、UPDATE、および DELETE 文は、既存データベース内のデータを修正しま
す。既存のデータを変更すると、データの整合性 が影響を受ける可能性があります。例
えば、存在しない製品に対する注文が表 orders に入力されていたり、その注文が未処
理である顧客が表 customer から削除されていたり、注文番号が表 orders で更新され
ていても表 items では更新されていない ということが起こります。このいずれの場合
も、格納されているデータの整合性は失われたことになります。
実際には、データ整合性は次の部分によって構成されています。
v エンティティ保全性
表の各行には、行を一意にする識別子が必要です。
v 意味整合性
第 6 章 データの変更
209
列内のデータは、列が保持すべき情報を正しく反映するものでなければなりません。
v 参照整合性
表と表の間の関係により強制される制約です。
例えば、存在しない行を参照することはできません。正しく設計されたデータベースで
は、これらの原則が守られ、データを変更する際にデータの整合性が失われないような
構造になっています。
エンティティ保全性
エンティティとは、データベースに記録されるあらゆる人、場所、または物のことで
す。個々の表はエンティティを表し、表の各行はエンティティのインスタンスを表しま
す。例えば、注文 がエンティティであれば、表 orders は注文の概念を表し、表の各行
は特定の注文を表します。
表の各行を識別するには、表に主キーが必要です。主キーは各行を識別するための一意
な値です。この要件は、実体整合性制約 と呼ばれます。
例えば、orders 表の主キーは order_num です。列 order_num はシステムによって生
成された、表内の各行を表す一意な番号を保持しています。表 orders のデータの行に
アクセスするには、次の SELECT 文を使用します。
SELECT * FROM orders WHERE order_num = 1001
注文番号の値が一意になっているため、WHERE 節でこの値を使用して簡単に特定の行
にアクセスすることができます。表内の注文番号に重複が許される場合は、この表の他
のすべての列に重複する値が存在することになるため、ある単一行にアクセスすること
はほぼ不可能です。
主キーおよびエンティティ保全性の詳細については、「IBM Informix: データベース設計
および実装 ガイド」を参照してください。
意味整合性
意味整合性とは、ある行に入力されたデータが確実にその行の許容値を反映するように
するためのものです。この値は、その列について、定義域 内の値、つまり許容可能な値
の集合である必要があります。例えば、表 items の列 quantity では、数字のみが許さ
れます。定義域外の値を列に入力できた場合には、そのデータの意味整合性に違反する
ことになります。
意味整合性は、次の制約によって強制されます。
v データ型
データ型は、列に格納することのできる値の型を定義します。例えば、小桁整数
(SMALLINT) 型の列には、-32,767 から 32,767 の値を入力することができます。
210
IBM Informix SQL ガイド: チュートリアル
v デフォルト値
デフォルト値は、明示的に値が指定されなかった場合に列に挿入される値です。例え
ば、表 cust_calls の列 user_id は、名前が入力されなかった場合デフォルトのログイ
ン名になります。
v チェック制約
チェック制約は、列に挿入するデータの条件を指定します。表に挿入される各行は、
この条件を満たしていなければなりません。例えば、表 items の列 quantity では 1
以上の数量であるかをチェックします。
データベース設計において意味整合性の制約を使用する方法については、
「IBM Informix: データベース設計および実装 ガイド」を参照してください。
参照整合性
参照整合性は、表間 の関係を表します。データベース内の各表には主キーがなければな
らないため、他の表内のデータとの関係のために、この主キーが他の表に現れる場合が
あります。ある表の主キーが他の表に現れる場合、これは外部キー と呼ばれます。
外部キーは複数の表を結合 し、表間の依存関係を確立します。表と表の依存性は、階層
的に形成することができます。ある表の行を変更または削除すると、他の表の行の意味
がなくなることがあります。例えば、図 353 は、表 customer の列 customer_num は
その表の主キーであり、表 orders と表 cust_call の外部キーであることを示していま
す。顧客番号 106 の George Watson は、表 orders と表 cust_calls の両方で参照 され
ています。顧客 106 が表 customer から削除されると、3 つの表のリンクとこの特定の
顧客は意味を失います。
第 6 章 データの変更
211
customer
customer_num
103
106
orders
order_num
1002
1003
1004
order_date
05/21/1998
05/22/1998
05/22/1998
name
Philip
George
name
Currie
Watson
customer_num
101
104
106
cust_calls
customer_num
106
119
119
call_dtime
1998-06-12 8:20
1998-07-07 10:24
1998-07-01 15:00
user_id
maryj
richc
richc
図 353. デモンストレーション データベースの参照整合性
主キーを含んでいる行を削除したり、別の主キーで更新したりすると、その値を外部キ
ーとして含んでいる行の意味を破壊することになります。参照整合性とは、主キーに対
する外部キーの論理的依存性のことです。外部キーを含む行の整合性 は、それが参照
する行、つまり一致する主キーを含む行の整合性に依存します。
デフォルトでは、データベース サーバは参照整合性に違反することを許可しません。子
表から行を削除する前に親表から行を削除しようとすると、エラー メッセージが表示さ
れます。ただし、オプション ON DELETE CASCADE を使用すれば、親表からのみ削
除を実行し、子表の削除を実行しないことができます。212 ページの『ON DELETE
CASCADE オプションの使用』を参照してください。
主キーと外部キーを定義し、これらの関係を定義するには、CREATE TABLE 文および
ALTER TABLE 文を使用します。これらの文の詳細については、「IBM Informix: SQL
ガイド: 構文」を参照してください。外部キーおよび主キーによるデータ モデルの構築
方法については、「IBM Informix: データベース設計および実装 ガイド」を参照してく
ださい。
ON DELETE CASCADE オプションの使用
表に対して主キーから行を削除した場合に参照整合性を維持するには、CREATE
TABLE の REFERENCES 節で ON DELETE CASCADE オプションを使用するか、
ALTER TABLE 文を使用します。このオプションを使用すると、1 回の削除コマンド
で、親表の行と対応する子表の一致している行を削除することができます。
カスケード削除中のロック: 削除の実行中に、親表および子表の修飾されている行
がすべてロックされます。削除を指定すると、親表から要求される削除は何らかの参照
動作が実行される前に発生します。
212
IBM Informix SQL ガイド: チュートリアル
複数の子表に対する影響: 一方の子にはカスケード削除が指定され、もう一方の子
にはカスケード削除が指定されていない 2 つの子側の制約を持つ親表があり、この両方
の子表に適用されている親表から行を削除しようとすると、DELETE 文は失敗し、親表
からも子表からも行は削除されません。
ログ機能をオンにする必要性: カスケード削除を実行するには、現行データベース
でログ機能をオンにする必要があります。ロギングとカスケード削除については、 222
ページの『トランザクション ログ』に記載されています。
カスケード削除の例
参照整合性規則が適用されている 2 つの表 (親表 accounts と子表 sub_accounts) がある
と仮定します。次の CREATE TABLE 文は、参照制約を定義しています。
CREATE TABLE accounts (
acc_num SERIAL primary key,
acc_type INT,
acc_descr CHAR(20));
CREATE TABLE sub_accounts (
sub_acc INTEGER primary key,
ref_num INTEGER REFERENCES accounts (acc_num)
ON DELETE CASCADE,
sub_descr CHAR(20));
accounts 表の主キー acc_num 列は、シリアル (SERIAL) 型を使用します。また、
sub_accounts 表の外部キー ref_num 列は、整数 (INTEGER) 型を使用します。主キー
のシリアル (SERIAL) 型と外部キーの整数 (INTEGER) 型の組合せは許されています。
この条件においてのみ、データ型を混用したり、一致させたりできます。シリアル
(SERIAL) 型は整数 (INTEGER) 型であり、データベースは自動的に列の値を生成しま
す。このデータ型以外の主キーと外部キーの組合せは、データ型がすべて明確に一致し
ていなければなりません。例えば、文字 (CHAR) 型として定義された主キーは、文字
(CHAR) 型として定義された外部キーに一致しなければなりません。
表 sub_accounts、列 ref_num の外部キーの定義にはオプション ON DELETE
CASCADE が含まれます。このオプションを指定すると、親表 accounts のどの行を削
除しても、子表 sub_accounts の対応する行が自動的に削除されます。
表 accounts から行を削除し、表 sub_accounts をカスケード削除するには、ログ機能を
オンにする必要があります。次の例が示しているように、ログ機能をオンにした後両方
の表からアカウント番号 2 を削除することができます。
DELETE FROM accounts WHERE acc_num = 2
カスケード削除に対する制約
自己参照型問合せおよび循環型問合せでの削除を含む、ほとんどの削除にカスケード削
除を使用することができます。唯一の例外は、相関副問合せです。相関副問合せとは、
副問合せ文 (または内側の SELECT 文) が生成する値が、その文自身が含まれている外
第 6 章 データの変更
213
側の SELECT 文によって生成された値に依存していることです。カスケード削除を実
行した場合、相関副問合せ文で子表を使用する削除を記述することはできません。相関
副問合せ文から削除を実行しようとすると、エラーが発生します。
重要: ON DELETE CASCADE で参照制約を定義している表では、DELETE トリガ イ
ベントを定義できません。
オブジェクト モードと違反の検出
データベースのオブジェクト モード機能と違反の検出機能は、データの整合性の監視に
役立ちます。この 2 つの機能は、スキーマの変更中に両方の機能を組み合わせて使用し
たり、短期間に大量のデータに対して挿入、削除、更新などの操作が実行されるときに
使用したりすると特に効果的です。
オブジェクト モード機能を説明する文中でのデータベース オブジェクトとは、制約、
インデックス、およびトリガのことで、これらはそれぞれ異なるモードを持ちます。オ
ブジェクト モード機能に関係のあるデータベース オブジェクトを、一般的な意味のデ
ータベース オブジェクトと混同しないでください。一般的なデータベース オブジェク
トは、表およびシノニムのようなものです。
オブジェクト モードの定義
制約または一意性インデックスについて、停止モード、有効モード、またはフィルタ モ
ードを設定することができます。トリガまたは重複インデックスについて、停止モード
または有効モードを設定することができます。データベース オブジェクト モードを使
用して、INSERT、DELETE、および UPDATE 文の影響を制御できます。
有効モード (IDS): 制約、インデックス、およびトリガは、デフォルトでは有効にな
っています。
あるデータベース オブジェクトが有効の場合、データベース サーバではそのデータベ
ース オブジェクトの存在が認識され、INSERT 文、DELETE 文、または UPDATE 文
の実行中には、そのデータベース オブジェクトが考慮に入れられます。したがって、ト
リガ イベントが発生すると、有効な制約が強制実行され、有効なインデックスが更新さ
れ、有効なトリガが実行されます。
制約および一意性インデックスを有効にするときに違反行が存在すると、データ操作ス
テートメントが失敗して行の変更が行われず、エラー メッセージが戻されます。
違反表と診断表の情報を分析すると、障害の原因を特定することができます。原因が特
定できたら、修正処置をとるか、その操作をロールバックします。
停止モード (IDS): あるデータベース オブジェクトが停止している場合は、
INSERT 文、DELETE 文、または UPDATE 文の実行中に、そのデータベース オブジ
ェクトは考慮に入れられません。トリガ イベントが発生しても、停止している制約は実
行されず、停止しているインデックスも更新されず、停止しているトリガも実行されま
214
IBM Informix SQL ガイド: チュートリアル
せん。制約および一意性インデックスを停止すると、制約または一意性インデックスの
制限に違反するすべてのデータ操作ステートメントが正常に機能してターゲット行が変
更され、エラー メッセージも戻されません。
フィルタ モード: 制約または一意性インデックスがフィルタ モードの場合、各文は
正常に機能し、INSERT 文、DELETE 文、または UPDATE 文の実行中に、制約または
一意性インデックスの要件が実行されます。このとき、ターゲット表に関連付けられた
違反表に、失敗した行が書き込まれます。制約違反に関する診断情報は、ターゲット表
に関連付けられた診断表に書き込まれます。
データ操作ステートメントのモード例
INSERT 文を使用する例で、有効モード、停止モード、およびフィルタ モードの違いを
説明することができます。INSERT 文を使用して、表の整合性制約を満足しない行を追
加する場合を考えます。例えば、ユーザ joe が表 cust_subset を作成し、この表が、ssn
(顧客の社会保障番号)、fname (顧客の名)、lname (顧客の姓)、city (顧客の居住する市)
という 4 つの列で構成されるとします。列 ssn は整数 (INT) 型であり、他の 3 列は
文字 (CHAR) 型であるとします。
ユーザ joe は列 lname を非 NULL として定義しましたが、NULL 値不可制約に名前
を割り当てなかったため、データベース サーバによって、この制約に n104_7 という
名前が暗黙的に割り当てられました。最後にユーザ joe は、列 ssn に対して unq_ssn
という一意性インデックスを作成しました。
ここで、表 cust_subset に対して Insert アクセス権を持つユーザ linda が、次の
INSERT 文をこの表に対して入力します。
INSERT INTO cust_subset (ssn, fname, city)
VALUES (973824499, "jane", "los altos")
有効モード、停止モード、および フィルタ モードの違いがよくわかるように、この
INSERT 文の結果を以下の 3 つの節で説明します。
制約が有効な場合の挿入操作の結果: 表 cust_subset に対する NULL 値不可制約
が有効な場合は、INSERT 文を使用してもこの表に新しい行を挿入することができませ
ん。ユーザ linda は、INSERT 文を入力すると、次のエラー メッセージを受け取りま
す。
-292 An implied insert column lname does not accept NULLs.
制約が無効な場合の挿入操作の結果: 表 cust_subset に対する NULL 値不可制約
が無効な場合、ユーザ linda が発行する INSERT 文によって、この表に新しい行が正
常に挿入されます。表 cust_subset の新しい行には、次の列値があります。
ssn
fname
lname
city
973824499
jane
NULL
los altos
第 6 章 データの変更
215
制約がフィルタ モードの場合の挿入操作の結果: cust_subset 表に対する NOT
NULL 制約がフィルタ モードに設定されている場合、ユーザ linda が発行する
INSERT 文では、この表に新しい行を挿入することができません。代わりに、その新し
い行は違反表に挿入され、その整合性違反を説明する診断行が診断表に追加されます。
ユーザ joe が、表 cust_subset に対する違反表と診断表を起動した場合を考えます。違
反表の名前は cust_subset_vio で、診断表の名前は cust_subset_dia です。ユーザ linda
がターゲット表 cust_subset に対して INSERT 文を発行したときに、違反表
cust_subset_vio に追加される新しい行は、次の列値をもちます。
ssn
fname
lname
city
informix_tupleid
informix_optype
informix_recowner
973824499
jane
NULL
los
altos
1
I
linda
違反表 cust_subset_vio のこの新しい行には、次のような特徴があります。
v 違反表の最初の 4 つの列は、ターゲット表の列と完全に一致します。これら 4 つの
列は、ターゲット表の対応する列と同じ名前および同じデータ型を持ち、また、ユー
ザ linda が入力した INSERT 文によって与えられた列値を持ちます。
v 列 informix_tupleid の値 1 は、不一致行に割り当てられた、一意のシリアル識別子
です。
v 列 informix_optype の値 I は、この、不一致行を作成した操作の種類を識別するコ
ードです。特に、I は挿入操作を表します。
v 列 informix_recowner の値 linda は、この不一致行を作成した文を発行したユーザ
を識別するものです。
ユーザ linda がターゲット表 cust_subset に対して発行した INSERT 文によっても、診
断表 cust_subset_dia に診断行が 1 行追加されます。診断表に追加されたこの新しい診
断行には、次の列値があります。
informix_tupleid
objtype
objowner
objname
1
C
joe
n104_7
診断表 cust_subset_dia のこの新しい診断行には、次のような特徴があります。
v 診断表のこの行は、違反表の対応する行にリンクしています。これは、列
informix_tupleid が両方の表に存在することで実現しています。値 1 は、両方の表で
この列に表示されます。
v 列 objtype の値 C は、違反表の対応する行の発生要因になった整合性違反の種類を
識別するものです。特に、値 C は制約違反を表します。
v 列 objowner の値 joe は、整合性違反が検出された制約の所有者を識別するもので
す。
216
IBM Informix SQL ガイド: チュートリアル
v 列 objname の値 n104_7 は、整合性違反が検出された制約の名前を示しています。
違反表と診断表を結合することにより、ターゲット表 cust_subset と、それに関連付け
られた特別な表の所有者であるユーザ joe、または DBA は、列 informix_tupleid に 1
という値を持つ行が INSERT 文実行の後で違反表に作成されたこと、および、この行が
制約に違反していることがわかります。表の所有者または DBA は、sysconstraints シ
ステム カタログ表に対して問合せを実行することで、この制約が NOT NULL 制約で
あると判別します。INSERT 文の失敗が判明したため、ユーザ joe または DBA は修正
処置を実行できます。
1 つの違反行に対する複数の診断行: 前の例では、診断表の 1 つの行だけが、違
反表の新しい行に対応していました。しかし、単一の新しい行が違反表に追加されたと
きに、複数の診断行を診断表に追加することも可能です。例えば、ユーザ linda が
INSERT 文で入力した ssn の値 (973824499) が、ターゲット表 cust_subset の列 ssn
にすでにある値と同じだった場合、違反表に表示される新しい行は 1 つのみですが、診
断表 cust_subset_dia には次の 2 つの診断行が表示されます。
informix_tupleid
objtype
objowner
objname
1
C
joe
n104_7
1
I
joe
unq_ssn
どちらの診断表の行も列 informix_tupleid に 1 の値を持つため、違反表の同じ行に対
応しています。ただし、1 番目の診断行は、ユーザ linda が発行した INSERT 文によ
る制約違反を識別するのに対し、2 番目の診断行は、同じ INSERT 文による一意性イン
デックス違反を識別します。この 2 番目の診断行では、列 objtype の値 I が一意性イ
ンデックス違反を表し、列 objname の値 unq_ssn が、整合性違反が検出されたインデ
ックスの名前を示します。
データベース オブジェクト モードの設定方法については、「IBM Informix: SQL ガイ
ド: 構文」のSET DATABASE OBJECT MODE 文に関する説明を参照してください。
違反表と診断表
ターゲット表に対する違反表を起動すると、ターゲット表に対する挿入、更新、または
削除の操作中に制約または一意性インデックスに違反する行があった場合、全体の操作
に支障はありませんが、それらは違反表に出力されます。診断表には、違反表の各行に
よって発生した整合性違反の情報が格納されます。これらの表を調査することにより、
障害の原因を識別し、違反を修正したり、操作をロールバックしたりするなどの修正処
置をとることができます。
ターゲット表に対する違反表を作成した後は、基本表または違反表の列やフラグメント
化を変更することができません。違反表を起動した後にターゲット表に対する制約を変
第 6 章 データの変更
217
更した場合は、一致しない行が違反表に出力されます。
Extended Parallel Server
Extended Parallel Server でターゲット表に対する違反表を作成すると、すべての制約が
フィルタ モードになります。違反表には診断情報を記録したフィールドが含まれるた
め、単独の診断表はありません。
Extended Parallel Server の終り
違反表の開始および停止方法については、「IBM Informix: SQL ガイド: 構文」の
START VIOLATIONS TABLE および STOP VIOLATIONS TABLE 文を参照してくだ
さい。
違反表とデータベース オブジェクト モードの関係: 表に対して定義された制約
または一意性インデックスをフィルタ モードに設定しても、このターゲット表に対する
違反表および診断表を作成しない場合は、挿入、更新、または削除の操作中に制約また
は一意性インデックスの要件に違反した行があっても違反表に出力されません。代わり
に、そのターゲット表に対する違反表を起動することを求めるエラー メッセージが表示
されます。
同様に、停止モードの制約または一意性インデックスを有効モードまたはフィルタ モー
ドに設定して、その制約または一意性インデックスの要件を満足しない既存の行を識別
できるようにするには、SET DATABASE OBJECT MODE 文を発行する前に違反表を
作成する必要があります。
START VIOLATIONS TABLE 文の例: 次の例では、START VIOLATIONS
TABLE 文を実行する、異なる方法を示します。
名前を指定しない診断表の開始: デモンストレーション データベースで、ターゲッ
ト表 customer に対する違反表および診断表を起動するには、次の文を入力します。
START VIOLATIONS TABLE FOR customer
この START VIOLATIONS TABLE 文には USING 節が含まれていないため、違反表に
はデフォルト名 customer_vio が付けられ、診断表にはデフォルト名 customer_dia が付
けられます。表 customer_vio には、次の列が含まれます。
customer_num
fname
lname
company
address1
address2
city
state
zipcode
218
IBM Informix SQL ガイド: チュートリアル
phone
informix_tupleid
informix_optype
informix_recowner
表 customer_vio には、表 customer と同じ表定義が含まれます。異なるのは、表
customer_vio の方にさらに 3 つの列が追加されていることで、これらには、不正な行
の原因になった操作に関する情報が含まれています。
表 customer_dia には、次の列が含まれます。
informix_tupleid
objtype
objowner
objname
この列のリストには、ターゲット表に対する診断表と違反表の重要な違いが示されてい
ます。違反表には、ターゲット表のすべての列に対して一致する列がありますが、診断
表の列は、ターゲット表のどの列とも一致しません。START VIOLATIONS TABLE 文
で作成される診断表には、同じ列名とデータ型を持つ同じ列が必ず含まれます。
名前を指定した違反表と診断表の開始: 次の文を実行すると、items というターゲ
ット表に対する違反表と診断表が起動されます。USING 節は、違反表と診断表に明示的
な名前を割り当てます。違反表は exceptions と名付けられ、診断表は reasons と名付
けられます。
START VIOLATIONS TABLE FOR items
USING exceptions, reasons
診断表の最大行数の指定: 次の文を実行すると、ターゲット表 orders に対する違反
表と診断表が起動されます。MAX ROWS 節を使用すると、 INSERT 文や SET
DATABASE OBJECT MODE 文のような単一の文をターゲット表に対して実行するとき
に、診断表に挿入できる行の最大数を指定できます。
START VIOLATIONS TABLE FOR orders MAX ROWS 50000
違反表を作成するときに MAX ROWS の値を指定しない場合は、ディスク領域以外の
制限はかかりません。
違反表に対するアクセス権の例: 次の例に、違反表に対するアクセス権の初期セッ
トが、ターゲット表の現在のアクセス権から導出される様子を示します。
例えば、表 cust_subset を作成し、この表が、ssn (顧客の社会保障番号)、fname (顧客
の名)、lname (顧客の姓)、city (顧客の居住する市) という 4 つの列で構成されるとし
ます。
表 cust_subset に対しては、次のアクセス権があります。
v ユーザ alvin はこの表の所有者です。
第 6 章 データの変更
219
v ユーザ barbara は、この表に対して Insert アクセス権および Index アクセス権を持
っています。また、列 ssn および lname に対しては、Select アクセス権も持ってい
ます。
v ユーザ carrie は、列 city に対して Update アクセス権を持っています。また、列
ssn に対しては、Select アクセス権も持っています。
v ユーザ danny は、この表に対する Alter アクセス権を持っています。
ここで、ユーザ alvin が次のように、表 cust_subset に対する違反表 cust_subset_viols
および診断表 cust_subset_diags を起動します。
START VIOLATIONS TABLE FOR cust_subset
USING cust_subset_viols, cust_subset_diags
データベース サーバにより、違反表 cust_subset_viols に対する次の初期アクセス権が
許可されます。
v ユーザ alvin はこの違反表の所有者なので、この表に対するすべての表レベルのアク
セス権を持っています。
v ユーザ barbara は、この違反表に対して、Insert、Delete、および Index の各アクセ
ス権を持っています。また、違反表の列 ssn、lname、informix_tupleid、
informix_optype、および informix_recowner に対しては、Select アクセス権も持って
います。
v ユーザ carrie は、この違反表に対して Insert アクセス権および Delete アクセス権を
持っています。また、違反表の列 city、informix_tupleid、informix_optype、および
informix_recowner に対しては、Select アクセス権も持っています。また、違反表の
列 ssn、informix_tupleid、informix_optype、および informix_recowner に対しては、
Select アクセス権も持っています。
v ユーザ danny は、この違反表に対してアクセス権を持っていません。
診断表に対するアクセス権の例: 次の例に、診断表に対するアクセス権の初期セッ
トが、ターゲット表の現在のアクセス権から導出される様子を示します。
例えば、表 cust_subset が、ssn (顧客の社会保障番号)、fname (顧客の名)、lname (顧
客の姓)、city (顧客の居住する市) という 4 つの列で構成されるとします。
表 cust_subset に対しては、次のアクセス権があります。
v ユーザ alvin はこの表の所有者です。
v ユーザ barbara は、この表に対して Insert アクセス権および Index アクセス権を持
っています。また、列 ssn および lname に対しては、Select アクセス権も持ってい
ます。
v ユーザ carrie は、列 city に対して Update アクセス権を持っています。また、列
ssn に対しては、Select アクセス権も持っています。
v ユーザ danny は、この表に対する Alter アクセス権を持っています。
220
IBM Informix SQL ガイド: チュートリアル
ここで、ユーザ alvin が次のように、表 cust_subset に対する違反表 cust_subset_viols
および診断表 cust_subset_diags を起動します。
START VIOLATIONS TABLE FOR cust_subset
USING cust_subset_viols, cust_subset_diags
データベース サーバにより、診断表 cust_subset_diags に対する次の初期アクセス権が
許可されます。
v ユーザ alvin はこの診断表の所有者なので、この表に対するすべての表レベルのアク
セス権を持っています。
v ユーザ barbara は、この診断表に対して、Insert、Delete、Select および Index の各
アクセス権を持っています。
v ユーザ carrie は、この診断表に対して Insert、Delete、Select、および Update の各ア
クセス権を持っています。
v ユーザ danny は、この診断表に対してアクセス権を持っていません。
中断された変更
どのソフトウェアにもエラーがなく、すべてのハードウェアが完全に信頼できる場合で
も、コンピュータ外部の環境から干渉を受ける場合があります。落雷による停電で、
UPDATE 文の実行中にコンピュータが停止する事態が起こらないとも限りません。もっ
と可能性があるのは、ディスクがフルになったり、ユーザが誤ったデータを入力したり
したために、複数行の挿入がエラーのために途中で停止する場合などです。いずれにし
ても、データを変更する場合は、予想外のイベントによって変更が中断される可能性を
想定する必要があります。
外部の原因によって変更が中断された場合は、どの段階まで操作が完了しているのか判
断できません。1 行を対象にした操作の場合でも、データがディスクに格納されたか、
またはインデックスが完全に更新されたかなどを確認することはできません。
複数行の変更が問題となる場合は、複数文の変更はさらに大きな問題を発生させます。
複数文は通常プログラムの中に埋め込まれているため、個々の SQL 文の実行はユーザ
にはわかりません。例えば、デモンストレーション データベースに新しい注文を入力す
るには、次の手順を実行します。
1. 表 orders に行を挿入する。この挿入操作によって注文番号が生成されます。
2. 注文された各品目について、表 items に行を挿入する。
注文入力アプリケーションのプログラミングには、2 つの方法があります。その 1 つ
は、プログラムを完全に対話 (interactive) 型にする方法です。これにより、最初の行が
ただちに挿入され、その後オペレータがデータを入力するたびに各品目が挿入されるよ
うになります。ただし、この方法では、顧客からの電話の切断、オペレータの誤入力、
オペレータによる端末電源の切断などの不測のイベントが処理中に多数発生する可能性
があります。
第 6 章 データの変更
221
次に、注文入力アプリケーションの正しい作成方法を説明します。
v すべてのデータを対話的に受け入れる。
v データの妥当性を検査し、表 stock や表 manufact のコードを参照するなどして必要
な値を補う。
v オペレータが確認できるように、情報を画面に表示する。
v オペレータが最終的な確定操作を行うまで待つ。
v 挿入を迅速に実行する。
このような手順を踏んでも、予測不能な状況が発生して、注文は挿入したものの、まだ
項目の挿入が終わらないうちにプログラムが停止してしまう場合があります。このよう
な障害が発生した場合には、データベースの状態は予測できないものとなり、データ整
合性 が損なわれます。
トランザクション
これまで述べてきたような潜在的な問題すべてに対する解決策は、トランザクション と
呼ばれています。トランザクションとは、完全に遂行されるか、あるいはまったく遂行
されないかのどちらか一連の変更のことです。データベース サーバは、トランザクショ
ンの範囲内で実行された操作が、完全にディスクにコミットされたか、またはデータベ
ースがトランザクションが開始される前の状態に復元されたかのいずれかを保証しま
す。
トランザクションの役割は、予想外の障害からの保護だけではありません。プログラム
が論理エラーを検出したときのエスケープの方法も提供します。
トランザクション ログ
データベース サーバは、トランザクションの実行中にデータベースに対して行われた個
々の変更内容を記録することができます。トランザクションをキャンセルするようなイ
ベントが発生すると、データベース サーバは自動的にその記録を使用して変更前の状態
に戻します。トランザクションの失敗には、多くの原因が考えられます。例えば、SQL
文を発行するプログラムが失敗または強制終了することがあります。トランザクション
の失敗 (この失敗は、コンピュータおよびデータベース サーバが再起動された後にのみ
発生する場合がある) を検出すると、すぐにデータベース サーバはトランザクションの
レコードを使用して、データベースを以前と同じ状態に戻します。
トランザクションのレコードを記録するプロセスを、トランザクション ログ または単
にロギング と呼びます。ログ レコード と呼ばれるトランザクションの記録は、データ
ベースとは別のディスク領域に格納されます。ログ レコードがトランザクションの論理
装置を表すため、この領域を論理ログ と呼んでいます。
Dynamic Server
Dynamic Server は以下のアクションをサポートします。
222
IBM Informix SQL ガイド: チュートリアル
v ログ付きデータベースにログなし (ロウ) 表またはログ付き (標準) 表を作成する。
v ALTER TABLE 文を使用して、ログなし表をログ付き表に、ログ付き表をログなし表
に変更する。
Dynamic Server では、非常に大きい表を速くロードするためにログなし表をサポートし
ます。トランザクションではログなし表を使用しないことをお勧めします。並行性の問
題を回避するには、トランザクションで使用する前に ALTER TABLE 文を使用して、
表を標準 (つまりログ付き) にします。
Dynamic Server におけるログなし表の詳細については、「IBM Informix: Dynamic Server
管理者ガイド」を参照してください。ログなし表のパフォーマンス上の優位性について
は、「IBM Informix: Dynamic Server パフォーマンス ガイド」を参照してください。
ALTER TABLE 文については、「IBM Informix: SQL ガイド: 構文」を参照してくださ
い。
Dynamic Server の終り
Extended Parallel Server
トランザクション レコードを自動的に生成するのは、Extended Parallel Server のデータ
ベースのみです。
Extended Parallel Server の終り
多くの Informix データベースは、トランザクション レコードを自動的には生成しませ
ん。DBA は、データベースがトランザクション ログ機能を使用するかどうか決定しま
す。トランザクション ログ機能を使用しない場合、トランザクションをロールバックす
ることはできません。
Extended Parallel Server のトランザクション ログ機能
Extended Parallel Server では、論理ログ ファイルのほかにログ スライス の作成が可能
で、これを変更することによって論理ログをいつでも追加できます。ログ スライスは、
DB 領域を占めるログ ファイルのセットです。これらのログ ファイルは、DB 領域当
たり 1 つのログ ファイルの割合で、複数のコサーバが所有します。ログ スライスは、
1 セットのログ ファイルを単一のエンティティとして扱うため、ログ ファイルの追加
と削除のプロセスを単純化します。DB スライスを作成、変更、または削除するには、
onutil ユーティリティを使用します。ログ スライスの詳細については、「IBM Informix:
Dynamic Server 管理者ガイド」を参照してください。
Extended Parallel Server のデータベースは必ずログ付きデータベースである必要があ
り、ログ機能をオフにすることはできません。しかし、個々の表がログ付き表であるか
ログなし表であるかを指定できます。ログ付き表とログなし表の両方のニーズに合致す
るため、Extended Parallel Server は、次のタイプの永続表と一時表をサポートします。
第 6 章 データの変更
223
v ロウ永続表 (ログなし)
v 静的永続表 (ログなし)
v 操作可能永続表 (ログあり)
v 標準永続表 (ログあり)
v スクラッチ一時表 (ログなし)
v Temp 一時表 (ログあり)
Extended Parallel Server がサポートする表タイプに関する詳細は、「IBM Informix: デー
タベース設計および実装 ガイド」に記載されています。
ロギングおよびカスケード削除
カスケード削除を実行するためには、データベースでログ機能をオンにしなければなり
ません。これは、カスケード削除を指定すると、削除はまず親表の主キーで実行される
ためです。親表の主キー行の削除が実行された後で、子表の外部キー行が削除される前
にシステムで障害が発生すると、参照整合性の違反となります。ログ機能を一時的にで
もオフにすると、削除処理はカスケードされません。しかし、ログ機能をオンに戻す
と、再びカスケード削除にすることができます。
Extended Parallel Server
Extended Parallel Server で作成したデータベースはすべて、ログ付きデータベースにな
ります。
Extended Parallel Server の終り
Dynamic Server
Dynamic Server では、CREATE DATABASE 内の WITH LOG 節でログ機能を有効に
できます。
Dynamic Server の終り
トランザクションの指定
SQL 文を使用してトランザクションの範囲を指定する方法は 2 つあります。最も一般
的な方法では、BEGIN WORK 文を実行することにより、複数文のトランザクションの
開始を指定します。オプション MODE ANSI を使用して作成されたデータベースで
は、トランザクションの開始を指定する必要はありません。常にトランザクションが開
始されている状態にあるため、個々のトランザクションの終了のみを指定してくださ
い。
どちらの方法を使用する場合でも、成功したトランザクションの終了を指定するには、
COMMIT WORK 文を実行します。この文は、すべてが完全に成功しなければならない
224
IBM Informix SQL ガイド: チュートリアル
一連の文の終わりに達したことをデータベース サーバに伝えます。データベース サー
バは、すべての変更を正しく完了し、コミットされてディスクに格納されるために、必
要な操作をすべて行います。
また、プログラムは、ROLLBACK WORK 文を実行することによって、トランザクショ
ンを意図的にキャンセルすることもできます。この文は、現行のトランザクションをキ
ャンセルし、すべての変更を取り消すようにデータベース サーバに指示します。
注文入力アプリケーションは、新しい注文の作成時に次のような方法を使用してトラン
ザクションを使用することができます。
v すべてのデータを対話的に受け入れる。
v 妥当性を検査し、必要な値を補う。
v オペレータが最終的な確定操作を行うまで待つ。
v BEGIN WORK を実行する。
v 表 orders および表 items に行を挿入し、データベース サーバが戻すエラー コード
をチェックする。
v エラーが発生しない場合は COMMIT WORK を、発生する場合は ROLLBACK
WORK を実行する。
外部の障害によってトランザクションが完了できなかった場合でも、システムを再起動
すると、トランザクションの一部がロールバックされます。これによって、どのような
場合でもデータベースの状態は予測可能です。すなわち、新しい注文が完全に入力され
たか、あるいはまったく入力されていないかのいずれかの状態がわかります。
Informix データベース サーバを使用したバックアップとログ
トランザクションを使用することによって、データベースを常に一貫した状態に保ち、
変更内容を正しくディスクに記録することができます。しかし、ディスクそのものは必
ず安全というわけではありません。ディスクは、機械的な障害や水害、火災、また地震
などの影響を受けやすいものです。このような障害に対する唯一の安全措置は、データ
のコピーを複数作成し、保持することです。これらの冗長コピーは、バックアップ コピ
ーと呼ばれます。
トランザクション ログ (論理ログとも呼ぶ) は、データベースのバックアップ コピー
を補います。その内容は、最後にデータベースをバックアップしてから発生したすべて
の変更の履歴です。バックアップ コピーからデータベースを復元する必要が発生した場
合は、トランザクション ログを使用して、データベースを最新の状態にロールフォワー
ドすることができます。
データベース サーバには、バックアップ機能とログ機能をサポートする高性能機能があ
ります。ご使用のデータベース サーバのアーカイブとバックアップのガイドでこれらの
機能について説明しています。
第 6 章 データの変更
225
データベース サーバには、例えばデータベースの使用中にはバックアップ コピーが作
成される必要があるなど、パフォーマンスおよび信頼性について厳格な要件がありま
す。
データベース サーバは、ログ機能専用の自分自身のディスク領域を管理します。
データベース サーバは、少数のログ ファイル セットを使用して、すべてのデータベー
スのためにログ機能を同時に実行します。ログ ファイルは、トランザクションが有効な
間に (バックアップされた) 別の媒体にコピーできます。
これらの機能は通常、DBA によって中央設置場所から管理されるため、データベース
のユーザが関わることはありません。
Dynamic Server
Dynamic Server は、onload および onunload ユーティリティをサポートします。
onunload ユーティリティを使用すると、単一のデータベースまたは表について個人用バ
ックアップ コピーを作成できます。このプログラムは、表またはデータベースをテープ
にコピーします。出力は、データベース サーバで格納されたときのディスク ページの
バイナリ イメージから構成されています。その結果、コピーを簡単に作成でき、対応す
るプログラム onload でもファイルを簡単に復元できます。ただし、他のプログラムで
はこのデータ フォーマットは無効です。onload および onunload ユーティリティの使
用方法については、「IBM Informix: 移行ガイド」を参照してください。
Dynamic Server の終り
Extended Parallel Server
Extended Parallel Server は、外部表 を使用して、データのロードおよびアンロードを実
行します。外部表を使用してデータをロードする方法については、「IBM Informix:
Dynamic Server 管理者ガイド」を参照してください。
Extended Parallel Server の終り
ご使用の DBA が ON–Bar を使用してバックアップを作成し、論理ログをバックアップ
する場合、ON–Bar を使用して独自のバックアップ コピーを作成することもできます。
詳しくは、「IBM Informix: バックアップおよび復元 ガイド」を参照してください。
226
IBM Informix SQL ガイド: チュートリアル
並行性およびロック
データベースが単一ユーザのワークステーションに含まれており、ネットワークを経由
して接続されているコンピュータがない場合、並行性は問題にはなりません。その他の
場合には、ユーザのプログラムがデータを変更している間に、他のプログラムが同じデ
ータを読み込んだり変更したりしている可能性について考慮しなければなりません。並
行性 は、同じデータを同時に複数の場所で別々に使用する場合に発生します。
高度な並行性は、複数のユーザによって使用されるデータベースシステムのパフォーマ
ンス向上に不可欠です。ただし、データの使用を十分に管理しないと、並行性はさまざ
まな弊害をもたらすおそれがあります。プログラムが古いデータを読み込んでしまった
り、正しく入力した変更内容が失われてしまったりすることもありえます。
データベース サーバは、ロック を系統的に設定することによって、このようなエラー
を防止します。ロックは、データの各部に対するプログラムからの使用予約です。デー
タベース サーバは、ロックされているデータについては、他のプログラムがそのデータ
を更新できないようにします。他のプログラムがそのデータを要求した場合は、ロック
が解除されるまでそのプログラムを待機させるか、あるいはエラー メッセージを発行し
てその要求を拒否します。
データ アクセスに対するロックの効果を制御するには、SET LOCK MODE と、SET
ISOLATION か SET TRANSACTION を組み合わせた SQL 文を使用します。これらの
文の詳細については、プログラム内部からカーソル を使用する方法の説明を参照してく
ださい。カーソルについては、235 ページの『第 8 章 SQL を使用したプログラミン
グ』と 265 ページの『第 9 章 SQL プログラムによるデータの更新』 に記載されてい
ます。ロックと並行性の詳細については、 279 ページの『第 10 章 マルチユーザ環境の
ためのプログラミング』を参照してください。
IBM Informix データ レプリケーション (IDS)
データ レプリケーション とは、広義では、データベース オブジェクトが、複数の異な
るサイトで複数の表現を持つことを意味します。例えば、元のデータベースを使用して
いるクライアント アプリケーションを妨害せずに、データに対してレポートを実行でき
るようにデータを複製する 1 つの方法として、データベースを別のコンピュータ上のデ
ータベース サーバにコピーすることができます。
次に、データ レプリケーションの利点について説明します。
v 複製されていないリモート データではなく、複製されたデータにローカルにアクセ
スするクライアントは、ネットワーク サービスを使用する必要がないためにパフォ
ーマンスが向上します。
v どのサイトのクライアントでも、複製されたデータを使用すると可用性が向上しま
す。これは、ローカルの複製データが使用できない場合に、リモートからでもデータ
のコピーを使用することができるためです。
第 6 章 データの変更
227
これらの利点を得るには、コストもかかります。データ レプリケーションでは、データ
を複製しない場合よりも複製データのためにより多くの記憶域が必要となり、複製デー
タの更新には、1 つのオブジェクトの更新よりも多くの処理時間がかかるためです。
実際には、データ レプリケーションは、データの位置または更新位置を明示的に指定す
ることにより、クライアント アプリケーションのプログラム ロジックに実行すること
ができます。ただし、この方法によるデータ レプリケーションのアーカイブにはコスト
がかかり、エラーも発生しやすく、管理が難しくなります。むしろ、データ レプリケー
ションの概念は、しばしばレプリケーションの透過性 と結び付けられます。レプリケー
ションの透過性は、データの複製の自動配置および保持の個々の処理を行うために (ク
ライアント アプリケーションの代わりに) データベース サーバに組み込まれている機
能です。
データ レプリケーションの幅広い枠内で、Informix データベース サーバはデータベー
ス サーバ全体のほとんど透過的なデータ レプリケーションを実装します。1 つの
Informix データベース サーバによって管理されるすべてのデータは、通常、リモート
サイトにある別の Informix データベース サーバで複製され、動的に更新されます。
Informix データベース サーバのデータ レプリケーションは、非常に重大な障害が発生
した場合にすばやく使用できる、データベース サーバ全体のバックアップ コピーを保
持する手段を提供するため、ホットサイト バックアップ と呼ばれることもあります。
データベース サーバではレプリケーションの透過性が提供されているので、通常はデー
タ レプリケーションについて意識する必要はありません。DBA がデータ レプリケー
ションを処理します。しかし、ユーザの組織がデータ レプリケーションの採用を決定し
た場合は、データ レプリケーション環境では、クライアント アプリケーションに関し
て特殊なコネクティビティ問題があることを認識すべきです。これらの考慮事項につい
ては、「IBM Informix: Dynamic Server 管理者ガイド」で説明されています。
IBM Informix エンタープライズ レプリケーションは、異なるデータ レプリケーション
機能を持ちます。この機能については、「IBM Informix: Dynamic Server エンタープラ
イズ レプリケーション ガイド」を参照してください。
サマリ
データベースに対するアクセスは、データベースの所有者が付与するアクセス権によっ
て制限されます。データに対する問合せを行うためのアクセス権は、多くの場合自動的
に与えられますが、データを変更するための権利は、表ごとに特定の Insert アクセス
権、Delete アクセス権、Update アクセス権を付与することによって制限されます。
データベースにデータ整合性制約がある場合、データを変更するための権限は、これら
の制約によって制限されます。データベース レベルおよび表レベルのアクセス権は、す
べてのデータ制約とともに、データを変更する方法とタイミングを制御します。更に、
データベースのオブジェクト モードと違反検出機能は、ユーザがデータを変更する方
法、およびユーザがデータの整合性の維持を支援する方法に影響を与えます。
228
IBM Informix SQL ガイド: チュートリアル
DELETE 文を使用すると、表から 1 つ以上の行を削除することができます。この文内
の WHERE 節は行を選択します。削除内容を確認するには、同じ節を指定した
SELECT 文を使用します。
INSERT 文を使用すると、行が表に追加されます。指定した列の値を含んでいる単一の
行を挿入することや、SELECT 文が生成する行のブロックを挿入することもできます。
UPDATE 文を使用して、既存の行の内容を修正することができます。副問合せ文を指定
できる式で新しい内容を指定して、他の表や更新された表自体に基づくデータを使用す
ることができます。この文には 2 つの形式があります。最初の形式では、列ごとに新し
い値を指定します。もう 1 つの形式では、SELECT 文またはレコード変数が一連の新
しい値を生成します。
CREATE TABLE および ALTER TABLE 文の REFERENCES 節を使用して、複数の表
間の関係を作成できます。REFERENCES 節の ON DELETE CASCADE オプションを
使用して、1 つの DELETE 文で親表と子表の両方から行を削除できます。
トランザクションを使用すると、変更操作の実行中に予想外の障害が発生して、データ
ベースが不安定な状態になるのを防止することができます。トランザクション内で変更
が実行され、エラーが発生した場合、それらの変更はロールバックされます。また、ト
ランザクション ログは、定期的に作成されるデータベースのバックアップ コピーも適
用します。これにより、データベースを復元しなければならない場合に、最新の状態に
戻すことができます。
ユーザに対して透過的に行われるデータ レプリケーションは、致命的な障害からのもう
1 つの保護対策です。
第 6 章 データの変更
229
230
IBM Informix SQL ガイド: チュートリアル
第 7 章 外部データベースのデータへのアクセスおよび修正
他のデータベース サーバへのアクセス . . .
ANSI データベースへのアクセス . . . .
外部データベース サーバ間の結合の作成 . .
外部ルーチンへのアクセス (IDS) . . . .
リモート データベース アクセスの制約事項 .
SQL 文およびロギング モード . . . . .
外部データベース オブジェクトへのアクセス
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
231
232
232
232
232
233
233
本章について
この章では、現行データベースにない表およびルーチンへのアクセスについて概説しま
す。
他のデータベース サーバへのアクセス
外部 データベースの表およびルーチンにアクセスするには、データベース オブジェク
ト (表、ビュー、シノニム、またはルーチン) 名を修飾します。
外部データベースが、現行データベースと同じデータベース サーバにある場合、オブジ
ェクト名をデータベース名とコロンで修飾します。例えば、ローカル データベース以外
のデータベースの表を参照するには、次の SELECT 文で外部データベースから情報に
アクセスします。
SELECT name, number FROM salesdb:contacts
この例の問合せでは、データベース salesdb 内の表 contacts のデータを戻します。
リモート データベース サーバは、現行データベース サーバ以外であればどのデータベ
ース サーバでも構いません。外部データベースがリモート データベース サーバにある
場合、オブジェクト名はデータベース オブジェクト名、データベース サーバ名、およ
びデータベース名で修飾する必要があります。次に例を示します。
SELECT name, number FROM salesdb@distantserver:contacts
この例の問合せでは、リモート データベース サーバ distantserver 上のデータベース
salesdb にある表 contacts からデータを戻します。
外部データベースにあるデータベース オブジェクト名を指定する方法に関する構文およ
びルールについては、「IBM Informix: SQL ガイド: 構文」を参照してください。
© Copyright IBM Corp. 1996, 2004
231
ANSI データベースへのアクセス
ANSI データベースでは、ownername.objectname のように、オブジェクトの所有者
(名) がオブジェクト名に含まれます。現行データベースおよび外部データベースが両方
ANSI データベースである場合は、ユーザがオブジェクトの所有者である場合を除き、
所有者名を含める必要があります。次の SELECT 文では、表の完全修飾名を使用して
います。
SELECT name, number FROM salesdb@aserver:ownername.contacts
ヒント: オブジェクト名は、常に明示的に修飾することができます。つまり、完全なオ
ブジェクト名が必須でない場合も、database@servername:ownername.objectname
のような完全な名前を使用できます。
ANSI 準拠データベースの詳細については、「IBM Informix: データベース設計および実
装 ガイド」を参照してください。
外部データベース サーバ間の結合の作成
結合の中でも同じ表記を使用できます。データベース名を明示的に指定する場合は、次
の例に示すように、長い表名を別名を使用して短くしなければ扱いにくくなります。
SELECT O.order_num, C.fname, C.lname
FROM masterdb@central:customer C, sales@boston:orders O
WHERE C.customer_num = O.Customer_num
外部ルーチンへのアクセス (IDS)
現行データベース サーバ以外のデータベース サーバのルーチンを参照するには、ルー
チン名をデータベース サーバ名とデータベース名 (リモート データベースが ANSI 準
拠の場合は所有者名も) で修飾します。次の SELECT 文で例示します。
SELECT name, salesdb@boston:how_long()
FROM salesdb@boston:contacts
リモート データベース アクセスの制約事項
ここでは、リモート データベース アクセスに関する制約事項の概要を示します。
232
IBM Informix SQL ガイド: チュートリアル
SQL 文およびロギング モード
次の SQL 文を、データベース間およびデータベース サーバ間で実行できます。
SELECT
CREATE VIEW
UNLOAD
INSERT
CREATE SYNONYM
LOCK TABLE
UPDATE
DROP DATABASE
UNLOCK TABLE
DELETE
EXECUTE FUNCTION (IDS のみ)
INFO
DATABASE
EXECUTE PROCEDURE (IDS のみ)
CREATE DATABASE
LOAD
各文をデータベースまたはデータベース サーバ全体に対して確実に実行するには、ロー
カル データベースと外部データベースが同じロギング モードである必要があります。
注: リモート データベース サーバのデータベースでの分散クロス サーバ操作でアクセ
スできるのは、ラージ オブジェクトでも複合データ型でもない、非不透明
(OPAQUE) 型の組込みデータ型値のみです。ただし、ローカル Dynamic Server イ
ンスタンスの他のデータベースにアクセスするために SQL 文または UDR を使用
する分散操作では、不透明 (OPAQUE) 型の組込みデータ型である BLOB 型、ブー
ル (BOOLEAN) 型、CLOB 型、および ラージ可変長文字 (LVARCHAR) 型を戻す
こともできます。また、そのような操作において、ディスティンクト (DISTINCT)
型値または UDT 値が組込みデータ型に明示的にキャストされ、ディスティンクト
(DISTINCT) 型、UDT、およびキャストのすべてが、関与するすべてのデータベー
スで定義されている場合、組込み型にキャストできる UDT のほか、組込みデータ
型に基づくディスティンクト (DISTINCT) 型にもアクセスできます。
Extended Parallel Server
注: INSERT、UPDATE、DELETE、および LOAD の場合、リモート サーバ上のターゲ
ット表は操作できません。
注: XPS では、リモート関数とリモート プロシジャ (EXECUTE FUNCTION と
EXECUTE PROCEDURE) はサポートされていません。
Extended Parallel Server の終り
外部データベース オブジェクトへのアクセス
外部データベース オブジェクトにアクセスするには、以下の条件があります。
v これらのオブジェクトに対して適切な権限を所有している。
v 両方のデータベースが同じロケールに設定されている。
第 7 章 外部データベースのデータへのアクセスおよび修正
233
重要: 他のデータベース サーバと通信するデータベース サーバの場合、両方のインス
タンスが同じマシン上にあるときでも、DBSERVERNAME または
DBSERVERALIAS に TCP/IP 接続を定義する必要があります。
234
IBM Informix SQL ガイド: チュートリアル
第 8 章 SQL を使用したプログラミング
プログラム中の SQL . . . . . . . . . . . .
SQL API 中の SQL . . . . . . . . . . . .
アプリケーション言語の SQL . . . . . . . .
静的埋込み . . . . . . . . . . . . . . .
動的文 . . . . . . . . . . . . . . . .
プログラム変数とホスト変数 . . . . . . . . .
データベース サーバの呼出し . . . . . . . . .
SQL 通信領域 . . . . . . . . . . . . . .
SQLCODE フィールド . . . . . . . . . . .
データの終わり . . . . . . . . . . . .
負数コード . . . . . . . . . . . . . .
SQLERRD 配列 . . . . . . . . . . . . .
SQLWARN 配列 . . . . . . . . . . . . .
SQLERRM 文字列 . . . . . . . . . . . .
SQLSTATE 値 . . . . . . . . . . . . . .
単一行の抽出 . . . . . . . . . . . . . . .
データ型の変換 . . . . . . . . . . . . .
NULL データの処理 . . . . . . . . . . . .
エラーの処理 . . . . . . . . . . . . . .
データの終わり . . . . . . . . . . . .
ANSI 標準準拠でないデータベースのデータの終り
重大なエラー . . . . . . . . . . . . .
集計関数とデータの終り . . . . . . . . .
デフォルト値の使用 . . . . . . . . . . .
複数行の抽出 . . . . . . . . . . . . . . .
カーソルの宣言 . . . . . . . . . . . . .
カーソルのオープン . . . . . . . . . . . .
行の取出し . . . . . . . . . . . . . . .
データの終りの検出 . . . . . . . . . . .
INTO 節の位置決め . . . . . . . . . . .
カーソル入力モード . . . . . . . . . . . .
カーソルのアクティブ セット . . . . . . . .
アクティブ セットの作成 . . . . . . . . .
順カーソルのアクティブ セット . . . . . . .
スクロール カーソルのアクティブ セット . . .
アクティブ セットと並行性 . . . . . . . .
カーソルの使用: 部品展開 . . . . . . . . . .
動的 SQL . . . . . . . . . . . . . . . .
文の PREPARE 文による処理 . . . . . . . .
PREPARE 文で処理された SQL 文の実行 . . . .
© Copyright IBM Corp. 1996, 2004
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
236
237
237
238
238
238
239
240
240
241
241
241
242
244
245
245
246
247
248
248
248
248
248
249
249
250
250
251
251
252
252
253
253
254
254
254
255
257
258
259
235
動的ホスト変数 . . . . . . . . . .
PREPARE 文で処理された文の解放. . . .
実行の高速化 . . . . . . . . . . .
データ定義文の埋込み . . . . . . . . .
アプリケーションでのアクセス権の付与と取消し
ロールの割当て . . . . . . . . . .
サマリ . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
260
260
261
261
261
263
264
本章について
これまでの章では、SQL を対話 (interactive) 型コンピュータ言語として扱い、説明して
きました。つまりユーザが SELECT 文をデータベース サーバに直接入力し、それに対
してロールバックされる行が表示されると想定しました。
実際はもう少し複雑です。ユーザとデータベース サーバの間には、何層ものソフトウェ
アが存在しています。データベース サーバはデータをバイナリ形式で保持しているた
め、表示の前にデータのフォーマットが必要です。また、データベース サーバが、大量
のデータを一度にユーザに戻すことはありません。プログラムの要求に応じて、1 行ず
つ戻します。
DB–Access でデータベースの情報にアクセスするには、対話式アクセスを使用します。
これは、ESQL/C のような SQL API で記述されたアプリケーション プログラム、また
は SPL のようなアプリケーション言語を介して行われます。
ほとんどのプログラムでは、内部に SQL 文を埋め込んで実行し、データベース サーバ
からデータを抽出することができます。この章では、データベース操作をどのように行
うか、また、データベース操作を行うプログラムをどのように作成するかについて説明
します。
この章では、SQL プログラミングに使用するすべての言語に共通する概念を紹介しま
す。特定のプログラム言語を使用して実用的なプログラムを作成するには、まず、その
言語をよく理解していることが必要です。プログラム作成のプロセスは各言語により異
なるため、詳細については、ご使用の言語の IBM Informix SQL API のマニュアルを参
照してください。
プログラム中の SQL
プログラムは複数の言語のうち任意の言語で作成することができ、SQL 文をそのプログ
ラム言語の通常の文として、プログラムの他の文の間に混合させることができます。こ
れらの SQL 文は、プログラムに埋め込まれ、そのプログラムには埋込み SQL (略して
ESQL) が含まれます。
236
IBM Informix SQL ガイド: チュートリアル
SQL API 中の SQL
ESQL の製品は、IBM Informix SQL API (アプリケーション プログラム インターフェ
イス) です。IBM では、C プログラミング言語用の SQL API を提供します。
図 354 に、SQL API が行う処理を示します。まず SQL 文を実行可能コードとして扱
い、ソース プログラムを作成します。ソース プログラムは、埋め込み SQL プリプロ
セッサ、つまり埋め込み SQL 文を格納するプログラムによって処理され、それらの文
を一連のプロシジャ呼出しと特定のデータ構造に変換します。
ESQL
ESQL
図 354. ESQL 文を含むプログラムの処理概要
変換されたソース プログラムは、そのプログラム言語のコンパイラへ渡されます。コン
パイラ出力は、SQL API プロシジャの静的または動的 ライブラリとリンクした後に、
実行可能プログラムになります。プログラムが実行されると、SQL API ライブラリ プ
ロシジャが呼び出されます。これらは、データベース サーバとの通信をセットアップし
て、SQL 操作を実行します。
実行可能プログラムをスレッド化ライブラリ パッケージとリンクさせると、ESQL/C マ
ルチスレッド アプリケーション を作成できます。マルチスレッド アプリケーション
は、制御スレッドを多く含むことができます。マルチスレッド アプリケーションは、プ
ロセスを、それぞれ独立して実行できる複数の実行スレッドに分割します。マルチスレ
ッドの ESQL/C アプリケーションの最大の利点は、各スレッドがデータベース サーバ
に対して複数の実効接続を同時に確立できるという点です。非スレッド ESQL/C アプリ
ケーションが 1 つ以上のデータベースに対して複数の接続を確立できるのに対し、マル
チスレッドのアプリケーションは 1 回に 1 つの実効状態の接続のみ確立します。マル
チスレッド ESQL/C アプリケーションは、スレッドあたり 1 つの実効状態の接続を確
立でき、アプリケーションごとに複数のスレッドを持つことができます。
マルチスレッド アプリケーションの詳細については、「IBM Informix: ESQL/C
Programmer’s Manual」を参照してください。
アプリケーション言語の SQL
SQL API 製品が SQL をホスト言語に埋め込むことができる一方、SQL を一連の文の
一部に最初から含む言語もあります。IBM Informix ストアド プロシジャ (SPL) は、
SQL を、一連の文に本来含まれるものとして使用します。アプリケーション プログラ
第 8 章 SQL を使用したプログラミング
237
ムを作成するには、SQL API 製品を使用します。データベースに格納され、アプリケー
ション プログラムによって呼び出されるルーチンは、SPL を使用して作成します。
静的埋込み
SQL 文は、静的埋込みまたは動的埋込みによりプログラム中に埋め込むことができま
す。より簡単で一般的な方法は、静的埋込み です。これは、SQL 文をコードの一部と
して作成する方法です。この文は、ソース テキストの固定的な部分であるため、静的
になります。静的埋込みの詳細については、245 ページの『単一行の抽出』および 249
ページの『複数行の抽出』を参照してください。
動的文
アプリケーションの中には、ユーザ入力に応答して動的に SQL 文を構成する機能を必
要とするものがあります。ユーザからの入力に応じて異なる列を選択したり、異なる判
断基準を行に適用したりしなければならないプログラムがその例です。
動的 SQL では、プログラムは SQL 文をメモリ内に文字の列として構成し、それをデ
ータベース サーバに受け渡して実行します。動的文は、ソース プログラムのテキスト
の一部ではなく、プログラムを実行する時点でメモリ内に作成されます。詳しくは、257
ページの『動的 SQL』を参照してください。
プログラム変数とホスト変数
アプリケーション プログラムでは、SQL 文の中でプログラム変数を使用できます。
SPL では、プログラム変数を構文が許可するとおりに SQL 文に書き込みます。例え
ば、DELETE 文では、その WHERE 節にプログラム変数を使用できます。
次のコードの例は、SPL 内のプログラム変数を示しています。
CREATE
PROCEDURE delete_item (drop_number INT)
..
.
DELETE
FROM items WHERE order_num = drop_number
..
.
埋込み SQL 文を使用するアプリケーションでは、SQL 文でプログラム変数の内容を参
照できます。埋込み SQL 文で名前が付けられたプログラム変数は、その SQL 文がプ
ログラム内でゲスト と認識されるために、ホスト変数 と呼ばれます。
次の例は、IBM Informix ESQL/C ソース プログラムに埋め込まれる場合に表示される
ことがある DELETE 文です。
EXEC SQL delete FROM items
WHERE order_num = :onum;
238
IBM Informix SQL ガイド: チュートリアル
このプログラムでは、第 6 章に記載したような、一般的な DELETE 文が使用されま
す。ESQL/C プログラムを実行すると、表 items の行を削除することができます。複数
行の削除も可能です。
この文には新しい機能が 1 つ含まれています。この機能は列 order_num を :onum と
書き込まれた項目と比較します。これはホスト変数の名前を表します。
それぞれの SQL API 製品には、ホスト変数が SQL 文のコンテキストに表示されると
きに、そのホスト変数の名前を区切る方法があります。ESQL/C では、ホスト変数はド
ル記号 ($) またはコロン (:) で導入できます。コロンには、ANSI との互換性がありま
す。この例文は、注文番号が :onum という名前のホスト変数の現在の内容と等しい行
を削除するよう、データベース サーバに要求しています。この数値変数は、プログラム
内のこれよりも前の部分で宣言され、値を設定されています。
IBM Informix ESQL/C では、SQL 文をドル記号 ($) または EXEC SQL で導入できま
す。
前述の例に示すように構文上の違いは些細なものにすぎず、本質的なポイントは、SQL
API と SPL の言語では次のタスクを実行できるということです。
v SQL 文を、ホスト言語の実行可能文としてソース プログラムに埋め込むことができ
る。
v SQL 式内でリテラル値と同様にプログラム変数を使用できる。
プログラミング経験のある方なら、すぐにその可能性を把握できます。例では、削除対
象の行の注文番号はホスト変数 onum から渡されます。この値は、プログラムからアク
セス可能なソースであれば、どのソースからでも受け取ることができます。ファイルか
ら読み込んだ値、プログラムが発行したプロンプトに応じてユーザが入力した値、ある
いは、データベースから読み込んだ値の場合などが考えられます。DELETE 文自体がサ
ブルーチンの一部である可能性があります。その場合は、onum はそのサブルーチンの
パラメータになります。そのサブルーチンは 1 回だけ、あるいは繰り返し呼び出されま
す。
つまり、SQL 文をプログラムに埋め込む場合、ホスト言語のすべての機能をそれらの文
に適用できます。SQL を多数のインターフェイスの下に隠して、さまざまな方法でその
機能を装飾することもできます。
データベース サーバの呼出し
SQL 文を実行すると、データベース サーバがサブルーチンとして必ず呼び出されま
す。プログラムとデータベース サーバの間で情報の受渡しが必要です。
プログラムとデータベース サーバとの間の通信の一部はホスト変数を介して行われま
す。SQL 文の内部に指定したホスト変数は、データベース サーバにアクセスするプロ
シジャ呼出しのパラメータと考えることができます。先の例では、ホスト変数は
第 8 章 SQL を使用したプログラミング
239
WHERE 節のパラメータとして機能しています。249 ページの『複数行の抽出』で説明
しているように、ホスト変数はデータベース サーバが戻すデータを受け取ります。
SQL 通信領域
データベース サーバは、SQL 通信領域 (SQLCA) と呼ばれるデータ構造体に常に結果
コードを戻します。また、その操作の結果に関するその他の情報も戻すことがありま
す。データベース サーバが、ユーザ定義ルーチンで SQL 文を実行する場合、呼出しア
プリケーションの SQLCA には、そのルーチンで SQL 文によってトリガされた値が含
まれます。
SQLCA の基本フィールドは、表 6 から 243 ページの表 8 にリストされています。
SQLCA などのデータ構造体の説明に使用する構文や、そのデータ構造体のフィールド
の参照に使用する構文は、各プログラム言語によって異なります。詳細については、
SQL API の資料を参照してください。
特に、SQLERRD 配列と SQLWARN 配列の要素を命名するサブスクリプトは異なりま
す。配列要素の番号は、IBM Informix ESQL/C ではゼロから始まりますが、他の言語で
は 1 から始まります。この説明では、「3 番目」などの語でフィールドに特定の名前が
付けられていますが、使用するプログラム言語の構文に合うように、これらの語を変換
することが必要です。
また、GET DIAGNOSTICS 文の SQLSTATE 変数を使用して、エラーを検出、処理、
および診断することも可能です。245 ページの『SQLSTATE 値』を参照してください。
SQLCODE フィールド
SQLCODE フィールドは、データベース サーバの 1 次戻りコードです。各 SQL 文の
後は、表 6 に示すように、SQLCODE が整数値に設定されます。ゼロ (0) は文の実行が
成功し、エラーがないことを示します。特に、データをホスト変数に戻す文の場合は、
コードが 0 ならば、データがホスト変数に戻されて使用可能であることを示します。コ
ードが非ゼロ値のときは、データがホスト変数に戻されておらず、使用不可であること
を示します。有用なデータは、ホスト変数に戻されません。
表 6. SQLCODE の値
240
戻り値
意味
値 < 0
エラー コードを指定する。
値 = 0
成功したことを示す。
0 < 値 < 100
DESCRIBE 文の後で、記述された SQL 文の型を示す整数値。
100
問合せが正常に実行され、行を戻さなかった場合にNOT FOUND 状
態を示す。NOT FOUND 状態は、ANSI 準拠のデータベースで
INSERT INTO/SELECT、UPDATE、DELETE、または
SELECT...INTO TEMP 文が行を戻さなかった場合にも発生します。
IBM Informix SQL ガイド: チュートリアル
データの終わり
データベース サーバは、文が正常に実行され、行が検出されなかった場合、SQLCODE
を 100 に設定します。これには 2 つの状況が考えられます。
まず、問合せでカーソルを使用している場合です (249 ページの『複数行の抽出』で、
カーソルを使用する問合せについて説明しています)。このような問合せでは、FETCH
文により各値がアクティブ セットからメモリ内に抽出されます。最後の行が抽出される
と、以降の FETCH 文はデータを戻すことができません。この状態になると、データベ
ース サーバは SQLCODE を 100 に設定し、データの終わりか、行が検出できない こ
とを示します。
もう 1 つのケースは、カーソルを使用しない問合せの場合です。このケースでは、問合
せ条件を満たす行がなかった場合、データベース サーバは SQLCODE を 100 に設定
します。ANSI 標準に準拠しないデータベースでは、SELECT 文が行を戻さない場合の
み、SQLCODE が 100 に設定されます。
米国規格協会 (ANSI)
ANSI 標準準拠データベースでは、SELECT、DELETE、UPDATE、および INSERT 文
のいずれの場合でも、行が戻されない場合には SQLCODE が 100 に設定されます。
米国規格協会 (ANSI) の終り
負数コード
文の実行中に予期されなかった要素が発生して実行が失敗すると、データベース サーバ
はエラーを示す負の番号を SQLCODE に戻します。これらのコードの意味は、オンラ
イン エラー メッセージ ファイルに記述されます。
SQLERRD 配列
SQLCODEに設定されるエラー コードの一部は一般的なエラーを示します。データベー
ス サーバでは、SQLERRD の 2 番目のフィールドに、より詳細なコードを設定できま
す。これにより、データベース サーバ入出力ルーチンまたはオペレーティング システ
ムで発生したエラーを確認できます。
SQLERRD 配列内の整数は、異なる文に続く異なる値に設定されます。配列の 1 番目お
よび 4 番目の要素は、IBM Informix ESQL/C でのみ使用されます。242 ページの表 7
に、フィールドの使用方法を示します。
これらの補足的な詳細情報は便利です。例えば、3 番目のフィールドの値を使用して、
削除や更新された行が何行であったかを報告できます。ユーザが入力した SQL 文をプ
ログラムが PREPARE 文で処理しているときにエラーが検出された場合は、5 番目のフ
第 8 章 SQL を使用したプログラミング
241
ィールドの値を使用するとエラーの場所を特定することができます (DB–Access では、
ユーザがエラー後に文を修正するよう要求するときに、この機能を使用してカーソルを
配置します)。
表 7. SQLERRD のフィールド
フィールド 意味
1 番目
SELECT、UPDATE、INSERT、または DELETE 文のための PREPARE 文
が正常に実行された後、または選択カーソルがオープンされた後、影響を
受けた行の見積り数がこのフィールドに含まれる。
2 番目
SQLCODE にエラー コードが含まれている場合は、このフィールドに、
ゼロもしくは ISAM エラー コードと呼ばれる追加のエラー コードのどち
らかが含まれる。これは、主なエラーの原因を示す。単一の行に対して挿
入操作が成功した後では、このフィールドに、その行に対して生成された
あらゆるシリアル (SERIAL) 型の値が含まれる。
3 番目
複数行に対して挿入、更新、または削除操作が成功した後では、このフィ
ールドに、処理された行の数が含まれる。複数行の挿入、更新、または削
除操作がエラーで終了した後では、このフィールドに、エラーが検出され
る前に正常に処理された行の数が含まれる。
4 番目
SELECT、UPDATE、INSERT、または DELETE 文のための PREPARE 文
が正常に実行された後、または選択カーソルがオープンされた後、ディス
ク アクセス数と処理された行の総数の加重値の見積りが、このフィールド
に含まれる。
5 番目
PREPARE、EXECUTE IMMEDIATE、DECLARE、または静的 SQL 文での
構文エラーの後、このフィールドに、エラーが検出された文のテキストの
オフセットが含まれる。
6 番目
選択された行の取出しが成功したか、あるいは挿入、更新、または削除操
作が成功した後では、このフィールドに、最後に処理された行の行識別子
(物理アドレス) が含まれる。この行識別子の値が、データベース サーバが
ユーザに戻す行に対応するものかどうかは、データベース サーバが問合せ
(特に SELECT 文についての問合せ) をどのように処理するかによる。
7 番目
SET EXPLAIN ON AVOID_EXECUTE が設定されているため、SQL は実
行されない。
SQLWARN 配列
SQLWARN 配列を構成する 8 つの文字 (CHAR) 型フィールドのフィールドは、空白か
W のどちらかに設定され、さまざまな状態を示します。これらの意味は直前に実行され
た文によって異なります。
242
IBM Informix SQL ガイド: チュートリアル
データベースがオープンされたとき、CONNECT、DATABASE、または CREATE
DATABASE 文の後に、一連の警告フラグが表示されます。これらのフラグはデータベ
ース全体の特性を示します。
警告フラグ以外のフラグは、上記以外のすべての文を実行した後に表示されます。これ
らのフラグは、その文の実行中に発生した異常なイベントを示します。フラグにより、
SQLCODE だけでは十分に記述できないイベントを示す場合もあります。
SQLWARN 値の両方のセットの要約は、表 8 に記載しています。
表 8. SQLWARN のフィールド
フィールド
データベースに対してオープン
または接続する場合
その他すべての操作の場合
1 番目
他の警告フィールドが W に設定 他の警告フィールドが W に設定されて
されているときは、W に設定され いるときは、W に設定されます。
ます。このフィールドが空白の場
合、他のフィールドをチェックす
る必要はありません。
2 番目
現在オープンしているデータベー
スがトランザクション ログを使
用する場合は、W に設定されま
す。
3 番目
現在オープンしているデータベー FETCH または SELECT 文が、集計関
数 (SUM、AVG、MIN、MAX) 値
スが ANSI 標準準拠の場合、W
NULL を戻す場合、W に設定されま
に設定されます。
す。
4 番目
データベース サーバが Dynamic
Server の場合、W に設定されま
す。
FETCH または SELECT...INTO 文を使
用して列値がホスト変数に取り出さ
れ、切り捨てられた場合に W に設定さ
れます。REVOKE ALL 文の実行時、7
つの表レベル アクセス権すべてが取り
消されない場合に、W に設定されま
す。
SELECT...INTO、FETCH...INTO、また
は EXECUTE...INTO 文の実行時、選択
リストの項目数が、それを受け取るた
めに INTO 節に渡されるホスト変数の
数と異なる場合に、W に設定されま
す。GRANT ALL 文の実行時、7 つの
表レベル アクセス権すべてが付与され
ない場合に、W に設定されます。
第 8 章 SQL を使用したプログラミング
243
表 8. SQLWARN のフィールド (続き)
フィールド
データベースに対してオープン
または接続する場合
その他すべての操作の場合
5 番目
データベース サーバが 10 進数
(DECIMAL) 型フォームに実数
(FLOAT) 型を格納する場合に、W
に設定されます (ホスト システ
ムに実数 (FLOAT) 型のサポート
がない場合)。
WHERE 節をもたない UPDATE 文ま
たは DELETE 文を PREPARE 文で処
理した場合、DESCRIBE 文の後で、W
に設定されます。
6 番目
予約済み。
ANSI 標準の SQL 構文を使用しない文
の実行後、W に設定されます
(DBANSIWARN 環境変数が設定され
ていることが前提となります)。
7 番目
アプリケーションが、データ レ
プリケーション ペアの副サーバ
であるデータベース サーバに接
続されている場合、W に設定され
ます。これは、このサーバが読取
り操作のみに使用できることを意
味します。
問合せ処理中にデータ フラグメント
(dbspace) がスキップされたとき
(DATASKIP 機能がオンに設定されて
いるとき) は W に設定されます。
8 番目
クライアントの DB_LOCALE が 予約済み。
データベース ロケールと一致し
ない場合、W に設定されます。詳
しくは、「IBM Informix: GLS ユ
ーザーズ ガイド」を参照してく
ださい。
SQLERRM 文字列
SQLERRM には 70 バイトまでの文字列を格納できます。SQLERRM 文字列には、エラ
ー メッセージに使用する表名などの識別子が含まれます。一部のネットワーク アプリ
ケーションでは、この配列に、ネットワーキング ソフトウェアによって生成されたエラ
ー メッセージが含まれています。
制約違反によって INSERT 操作が失敗した場合は、違反の起きた制約の名前が
SQLERRM に書き込まれます。
ヒント: エラー文字列が 70 バイトを超える場合は、オーバーフローが自動的に廃棄さ
れます。このため、コンテキストによっては、ランタイム エラーに関する情報
が失われる可能性があります (例えばエラー文字列が 70 バイトを超える識別
子を含む場合など)。
244
IBM Informix SQL ガイド: チュートリアル
SQLSTATE 値
IBM Informix ESQL/C のような特定の IBM Informix 製品では、X/Open および ANSI
SQL 標準に準拠する SQLSTATE 値をサポートします。GET DIAGNOSTICS 文は
SQLSTATE 値を読み込み、SQL 文の実行後にエラーを診断します。データベース サー
バは結果コードを 5 文字の文字列で戻し、この文字列は SQLSTATE 変数に格納されま
す。SQLSTATE エラー コードまたは SQLSTATE 値は、実行された最新の SQL 文に
関する情報を示します。
v 文の実行は成功した。
v 文の実行は成功したが、警告が生成された。
v 文の実行は成功したが、データが生成されなかった。
v 文の実行が失敗した。
GET DIAGNOSTICS 文、SQLSTATE 変数、および SQLSTATE 戻りコードの意味につ
いては、「IBM Informix: SQL ガイド: 構文」の GET DIAGNOSTICS 文に関する説明
を参照してください。
ヒント: ご使用の IBM Informix 製品が GET DIAGNOSTICS および SQLSTATE をサ
ポートする場合は、それらをエラーの検出、処理、および診断に使用する主構
造体として利用することをお勧めします。SQLSTATE は ANSI に準拠してお
り、複数のエラーを検出することができます。
単一行の抽出
SELECT 文が戻す行のセットは、その文に対するアクティブ セット です。単一行
SELECT 文は、1 つの行を戻します。埋込み SELECT 文を使用すると、データベース
から 1 行を抽出して、ホスト変数に代入することができます。ただし、SELECT 文に
より複数行のデータが戻される場合は、カーソルを使用して、一度にそれらの行が抽出
されるようにする必要があります。複数行の選択操作については、249 ページの『複数
行の抽出』に記載しています。
1 行のデータを抽出する場合は、SELECT 文をプログラム中に埋め込むだけで済みま
す。次の例では、IBM Informix ESQL/C を使用して埋込み SELECT 文を作成する方法
を示します。
EXEC SQL SELECT avg (total_price)
INTO :avg_price
FROM items
WHERE order_num in
(SELECT order_num from orders
WHERE order_date < date(’6/1/98’) );
第 2 章または第 5 章に示す例と、この文では、INTO 節のみが異なります。この節を
使用すると、生成されたデータを受け取るホスト変数を指定することができます。
第 8 章 SQL を使用したプログラミング
245
埋込み SELECT 文が実行されると、データベース サーバは問合せを実行します。この
例文では集計関数が戻す値が選択されるため、生成されるデータは 1 行です。この行は
1列のみで構成され、列の値は avg_price という名前のホスト変数に格納されます。こ
のプログラムの後続の行で、このホスト変数の値を使用できます。
この種の文を使用すると、単一行のデータを抽出してホスト変数に代入することができ
ます。その単一行は、必要な数の列を含みます。問合せにより、複数行のデータが生成
された場合には、データベース サーバはデータを戻すことができません。代わりに、エ
ラー コードを戻します。
INTO 節に指定するホスト変数の数は、必ず選択リストで指定する項目の数と同じにし
てください。ホスト変数の数と選択リストの項目の数が一致しない場合は、データベー
ス サーバはできるだけ多くの値を戻し、SQLWARN の 4 番目のフィールドに警告フラ
グを設定します。
データ型の変換
次の ESQL/C の例は、それ自体が 10 進数 (DECIMAL) 型値である 10 進数
(DECIMAL) 型列の平均を抽出します。ただし、10 進数 (DECIMAL) 型列の平均が格納
されるホスト変数のデータ型は同じである必要はありません。
EXEC SQL SELECT avg (total_price) into :avg_price
FROM items;
ESQL/C コードの前述の例のデータを受け取る変数 avg_price の宣言は示していませ
ん。次の宣言のどれでも可能です。
int avg_price;
double avg_price;
char avg_price[16];
dec_t avg_price; /* typedef of decimal number structure */
SQL 文で使用されている各ホスト変数のデータ型は、その文と一緒にデータベース サ
ーバに渡されます。データベース サーバは、列の値をできるだけその受取り先のホスト
変数のデータ型に変換します。可能な限りの変換が実行されますが、一部の変換では精
度が落ちます。この例の結果は、ホスト変数のデータ型によって、次のように変わりま
す。
246
IBM Informix SQL ガイド: チュートリアル
データ型
結果
実数 (FLOAT)
型
データベース サーバは 10 進数型の結果を実数 (FLOAT) 型に変換
します。その場合、小数点以下の桁がいくつか切り捨てられることが
あります。10 進数型の値が実数 (FLOAT) 型で表現可能な最大値を
超える場合はエラーが戻されます。
整数 (INTEGER)
型
データベース サーバは結果を整数 (INTEGER) 型に変換します。こ
の場合、必要に応じて小数点以下の桁が切り捨てられます。変換後の
数値の整数部が大きすぎて受け取る側の変数に収まらない場合はエラ
ーが戻されます。
文字
(CHARACTER)
型
データベース サーバが 10 進数値を文字 (CHARACTER) 型文字列
に変換します。文字列が長すぎてホスト変数に収まらない場合は、文
字列の一部が切り捨てられます。SQLWARN の 2 番目のフィールド
は W に設定され、SQLSTATE 変数の値は 01004 になります。
NULL データの処理
プログラムが NULL 値を抽出した場合について説明します。NULL 値はデータベース
に格納できますが、プログラム言語でサポートされているデータ型は NULL の状態を
認識しません。プログラムは何らかの方法で NULL を識別して、NULL がデータとし
て処理されるのを防ぐ必要があります。
標識変数 は、SQLAPI でこのニーズを満たします。標識変数は付加的な変数で、NULL
を受け取る可能性があるホスト変数と関連付けられます。主変数にデータを格納すると
き、データベース サーバはそのデータが NULL かどうかを示す特別な値を標識変数に
も格納します。次の IBM Informix ESQL/C 例では、1 行が選択され、1 つの値がホス
ト変数 op_date に抽出されます。
EXEC SQL SELECT paid_date
INTO :op_date:op_d_ind
FROM orders
WHERE order_num = $the_order;
if (op_d_ind < 0) /* data was null */
rstrdate (’01/01/1900’, :op_date);
その値が NULL である可能性があるため、op_d_ind という名前の標識変数がホスト変
数に関連付けられています。この標識変数は、プログラム内の任意の行で short int 型と
して宣言されていなければなりません。
SELECT 文の実行後に、標識変数の値が負かどうかがテストされます。負の値 (通常は
-1) は主変数に抽出された値が NULLであることを示します。この変数が NULL の場
合は、プログラムは ESQL/C ライブラリ関数を使用してホスト変数にデフォルト値を割
り当てます。rstrdate 関数は IBM Informix ESQL/C 製品の一部です。
第 8 章 SQL を使用したプログラミング
247
標識変数をホスト変数に関連付ける構文は、プログラム言語によって異なりますが、こ
こで説明した原理はどの言語でも同じです。
エラーの処理
データ型間の変換はデータベース サーバが自動的に処理しますが、SELECT 文には問
題が発生する可能性がまだいくつかあります。SQL プログラミングでは、他のプログラ
ムと同様に、このような状況に備えてエラーの発生を予測し、エラーに対し万全の対策
を講じる必要があります。
データの終わり
問合せがまったく行を戻さないということも珍しくありません。このイベントは、
SELECT に続いて、SQLSTATE コード 02000 および SQLCODE 内のコード 100 でシ
グナル通知されます。このコードはエラーか単に行が存在しないことを示します。どち
らを示すかはアプリケーションによって判断しなくてはなりません。例えば、別の表か
ら取り出したばかりのキー値を使用して行を読み込んでいるときのように、行が存在し
なければならないことがはっきりしている場合、データの終わりを示すコードはプログ
ラムの論理に重大な障害があることを示しています。これに対し、ユーザが入力した値
や、プログラムより信頼性の少ないソースを基にして行を選択している場合は、データ
がなくてもエラーではありません。
ANSI 標準準拠でないデータベースのデータの終り
使用しているデータベース が ANSI 標準準拠でない場合、データの終わりの戻りコー
ド 100 は SELECT 文に続く SQLCODE にのみ設定されます。また、SQLSTATE 値は
02000 に設定されます。(INSERT、UPDATE、および DELETE などの他の文は、それら
の文によって影響を受けた行数を示すように SQLERRD の 3 つ目の要素を設定しま
す。この内容については、第 9 章に記載しています。)
重大なエラー
SQLCODE を負の値に設定したり、SQLSTATE を 00、01、または 02 以外の値で始ま
る値に設定するようなエラーは、通常重大なエラーと考えられます。こうしたエラー
が、開発したプログラムや製品において報告されたことはごくまれです。しかし、珍し
いケースだからといって、無視することはできません。
例えば、「指定された表がデータベースにない」という意味の -206 というエラー コー
ドが戻ってきたとします。このエラーが発生するのは、プログラムが作成されてから後
に誰かが表を削除した場合、あるいは論理エラーもしくは入力ミスにより、プログラム
が間違ったデータベースをオープンした場合です。
集計関数とデータの終り
SUM、MIN、または AVG などの集計関数を使用する SELECT 文は、WHERE 節の条
件を満たす行がない場合でも、通常 1 つ以上のデータ行を戻します。条件を満たす行が
ない場合の集計関数の値は NULL となりますが、NULL は値と見なされます。
248
IBM Informix SQL ガイド: チュートリアル
条件を満たす行が 1 行以上あり、それらすべての行に NULL が入っている場合も、集
計関数の値は NULL になります。いずれの行にも基づかない集合値と、すべてに
NULL が含まれる複数行に基づく集合値の差を検出するには、文に COUNT 関数をイ
ンクルードし、集合値の値に対し標識変数を設定することが必要になります。これによ
って、次の場合を区別できます。
Count の値
標識変数
意味
0
-1
ゼロ行を選択。
>0
-1
いくつかの行を選択。すべての値が NULL。
>0
0
いくつかの非 NULL 行を選択。
デフォルト値の使用
不可避のエラーの処理には、さまざまな方法があります。アプリケーションによって
は、通常の状態を処理する機能より、エラー処理をする機能の方が多いこともありま
す。ここでは、デフォルト値を使用してエラーを処理する方法を例で示します。
avg_price = 0; /* set default for errors */
EXEC SQL SELECT avg (total_price)
INTO :avg_price:null_flag
FROM items;
if (null_flag < 0) /* probably no rows */
avg_price = 0; /* set default for 0 rows */
この例は、状態に応じて次のように処理します。
v NULL 以外の行が 1 行以上選択された場合は、正しい値が戻され、使用されます。
この結果はもっとも頻繁に発生すると思われます。
v 問合せで 1 行も選択されなかった場合や、NULL が許されない列 total_price に
NULL が含まれる行のみが選択された場合は、標識変数が設定され、デフォルト値が
割り当てられます。
v 重大なエラーが発生した場合は、ホスト変数の値は最初に指定したデフォルト値のま
ま変わりません。プログラムのこの箇所では、プログラマはこのようなエラーをトラ
ップし、報告する必要はありません。
複数行の抽出
問合せによって戻される行が 2 行以上になる可能性がある場合は、プログラム中の問合
せの実行方法を変えなければなりません。複数行を戻す問合せは 2 段階で処理されま
す。まず、プログラムが問合せを開始します。すぐに戻されるデータはありません。次
に、プログラムが一度に 1 行ずつデータを要求します。
これらの操作は、カーソル と呼ばれる特別のデータ オブジェクトを使用して行われま
す。カーソルは、問合せの現行状態を表すデータ構造体です。通常のプログラムの操作
の流れは、次のようになります。
第 8 章 SQL を使用したプログラミング
249
1. プログラムは、カーソルとそれに関連した SELECT 文を宣言 します。これは、単
にカーソルを保留するための記憶域を割り当てるだけです。
2. カーソルがオープン され、これによってカーソルと関連付けられた SELECT 文の
実行が開始され、エラーがあれば検出されます。
3. プログラムは、1 行のデータをホスト変数に取り出して 処理します。
4. プログラムは、最後の行が取り出された後にカーソルをクローズ します。
5. カーソルが不要になると、プログラムではカーソルを解放 して、使用するリソース
の割当てを解除します。
これらの操作は、DECLARE、OPEN、FETCH、CLOSE、および FREE と呼ばれる SQL
文で実行されます。
カーソルの宣言
カーソルの宣言には DECLARE 文を使用します。この文はカーソルを命名し、その用
途を指定し、カーソルを文と関連付けます。次の例は、IBM Informix ESQL/C で書かれ
ています。
EXEC SQL DECLARE the_item CURSOR FOR
SELECT order_num, item_num, stock_num
INTO :o_num, :i_num, :s_num
FROM items
FOR READ ONLY;
この宣言ではカーソルを the_item と命名し、カーソルを SELECT 文と関連付けていま
す (カーソルを INSERT 文と関連付ける方法については、第 9 章に記載しています)。
この例の SELECT 文には、INTO 節が含まれます。INTO 節は、どの変数がデータを受
け取るか指定します。また、FETCH 文を使用して、データを受け取る変数を指定でき
ます。これについては、252 ページの『INTO 節の位置決め』で説明します。
DECLARE 文は、データベースに対する操作を行うものではなく、カーソルの機能を確
立し、カーソルに記憶域を割り当てる文です。この例のカーソルを使用すると、表
items の行を始めから終わりまで 1 回読み込むことができます。カーソルの宣言方法に
よっては順方向にも逆方向にも読み込むことができます。詳細は、252 ページの『カー
ソル入力モード』を参照してください。このカーソルは、FOR UPDATE 節を指定して
宣言されていないため FOR READ ONLY と指定され、データの変更には使用されませ
ん。カーソルを使用するデータの修正については、第 9 章で説明します。
カーソルのオープン
使用準備ができると、カーソルはオープンされます。OPEN 文がカーソルを起動しま
す。このとき、カーソルに関連付けられた SELECT 文がデータベース サーバに渡さ
れ、データベース サーバは一致する行の探索を始めます。データベース サーバは、表
の最初の行が検出されるか構築されるまで問合せを処理します。データベース サーバ
250
IBM Informix SQL ガイド: チュートリアル
は、実際にその行のデータを戻すのではなく、戻りコードを SQL API の SQLSTATE
および SQLCODE に設定します。次の例に、ESQL/C 内の OPEN 文を示します。
EXEC SQL OPEN the_item;
文が実行されるとき初めて、データベース サーバが問合せを認識するため、エラーが検
出される可能性があります。カーソルのオープン後、プログラムは SQLSTATE と
SQLCODE をテストする必要があります。SQLSTATE の値が 02000 を超える場合、ま
たは SQLCODE に負の数値が含まれる場合は、そのカーソルを使用できません。
SELECT 文にエラーがあったり、他の問題がデータベース サーバに文を実行させない
ようにしていたりする場合があります。
SQLSTATE が 00000 と等しい場合、または SQLCODE にゼロが含まれる場合、
SELECT 文は構文上有効であり、カーソルを使用することができます。ただし、この時
点ではカーソルが行を生成するかどうかはわかりません。
行の取出し
プログラムは、FETCH 文を使用して、出力の各行を抽出します。FETCH 文はカーソル
を命名し、データを受け取るホスト変数も命名します。次に、完了した IBM Informix
ESQL/C コードを示します。
EXEC SQL DECLARE the_item CURSOR FOR
SELECT order_num, item_num, stock_num
INTO :o_num, :i_num, :s_num
FROM items;
EXEC SQL OPEN the_item;
while(SQLCODE == 0)
{
EXEC SQL FETCH the_item;
if(SQLCODE == 0)
printf("%d, %d, %d", o_num, i_num, s_num);
}
データの終りの検出
この例では、OPEN 文がエラーを戻すと、WHILE 節の条件によりループの実行を回避
します。同じ条件で、SQLCODE が 100 に設定され、データの終わりが示される場
合、ループが終了します。ただし、SQLCODE の値は、ループの内部でもテストされて
います。これが必要なのは、SELECT 文が有効でも一致する行が検索されない場合は、
OPEN 文がゼロを戻すのに対し、最初の取出しでは 100 (データの終わり) が戻された
り、全くデータが戻されないことがあるためです。この例のループは、次のように記述
し直すことができます。
EXEC SQL DECLARE the_item CURSOR FOR
SELECT order_num, item_num, stock_num
INTO :o_num, :i_num, :s_num
FROM items;
EXEC SQL OPEN the_item;
if(SQLCODE == 0)
EXEC SQL FETCH the_item;
/* fetch 1st row*/
第 8 章 SQL を使用したプログラミング
251
while(SQLCODE == 0)
{
printf("%d, %d, %d", o_num, i_num, s_num);
EXEC SQL FETCH the_item;
}
このように記述し直すと、戻される行が存在しない場合が先に処理されるため、ループ
内で 2 回目の SQLCODE のテストは行われません。ただし、このように書き直して
も、測定には現れない程度のパフォーマンスの差しかありません。SQLCODE のテスト
に要する時間コストは、FETCH 文のコストに比べごくわずかに過ぎません。
INTO 節の位置決め
INTO 節には、データベース サーバが戻すデータを受け取るホスト変数の名前を指定し
ます。これは、SELECT 文または FETCH 文のいずれかで表示される必要があります
が、INTO 節は、SELECT 文または FETCH 文のいずれかで表示される必要があります
が、両方の文で指定することはできません。次の例は、ホスト変数を FETCH 文で指定
するように前の例を記述し直したものです。
EXEC SQL DECLARE the_item CURSOR FOR
SELECT order_num, item_num, stock_num
FROM items;
EXEC SQL OPEN the_item;
while(SQLCODE == 0)
{
EXEC SQL FETCH the_item INTO :o_num, :i_num, :s_num;
if(SQLCODE == 0)
printf("%d, %d, %d", o_num, i_num, s_num);
}
このフォームによって、別々の行を別々の配置に取り出すことができます。例えば、こ
のフォームを使用すると、連続する行を配列内の連続する要素に取り出すことができま
す。
カーソル入力モード
入力目的のため、カーソルは 2 つのモード (順次 または スクロール) のうちのいずれ
かで作動します。順カーソルが取り出すことができるのは、カーソルが置かれている位
置の次の行のみです。そのため、オープンするごとに 1 度しか表を読み通すことができ
ません。スクロール カーソルは、次の行だけでなく、カーソルより前にある任意の行を
取り出すことができます。したがって、行を何回でも読み込むことができます。次の例
は、IBM Informix ESQL/C で宣言された順カーソルを示しています。
EXEC SQL DECLARE pcurs cursor for
SELECT customer_num, lname, city
FROM customer;
次の例で示しているように、カーソルはオープンされた後は、次の行のデータを抽出す
る順次取出しでしか使用できません。
EXEC SQL FETCH p_curs into:cnum, :clname, :ccity;
252
IBM Informix SQL ガイド: チュートリアル
順次取出しを行うたびに、新しい行が 1 行戻されます。
スクロール カーソルは、次の IBM Informix ESQL/C からの例に示すように、キーワー
ド SCROLL CURSOR で宣言されます。
EXEC SQL DECLARE s_curs SCROLL CURSOR FOR
SELECT order_num, order_date FROM orders
WHERE customer_num > 104
スクロール カーソルを宣言した場合、さまざまな取出しオプションが使用できます。例
えば ABSOLUTE オプションは、取り出す行の絶対位置を指定します。
EXEC SQL FETCH ABSOLUTE :numrow s_curs
INTO :nordr, :nodat
この文が取り出す行は、ホスト変数 numrow にその位置を指定されている行です。現
在取り出した行を再度取り出すこともでき、また、選択された複数の行を最初の行から
再び走査することもできます。ただし、これらの機能を実行すると、アプリケーション
の実行速度が遅くなる場合があります。これについては次のセクションで説明します。
スクロール カーソルに適用する他のオプションについては、「IBM Informix: SQL ガイ
ド: 構文」の FETCH 文を参照してください。
カーソルのアクティブ セット
オープンされたカーソルは、選択された一群の行を表します。問合せが生成する行すべ
ての集合は、カーソルのアクティブ セット と呼ばれます。アクティブ セットを特定の
条件を満たす行の集合、カーソルをその集合の 1 行を指すポインタと考えてください。
同じデータを並行して変更するプログラムが他にない場合には、このようなモデル化は
誤りではありません。
アクティブ セットの作成
カーソルがオープンされるとデータベース サーバは、選択されたデータの最初の行を検
出しようとします。簡単に検出されるか、それともかなりの作業と時間を要するかは、
問合せの表現法により異なります。次のカーソルの宣言について考えてみます。
EXEC SQL DECLARE easy CURSOR FOR
SELECT fname, lname FROM customer
WHERE state = ’NJ’
データベース サーバは、問合せの条件を満たす行が存在するかどうかを迅速に認識で
き、最初の行をすぐに検出します。この時点でデータベース サーバが検出する行は最初
の 1 行のみです。アクティブ セットを構成する残りの他の行は、まだ不明のままで
す。もう 1 つのカーソルの宣言について以下に示します。
EXEC SQL DECLARE hard SCROLL CURSOR FOR
SELECT C.customer_num, O.order_num, sum (items.total_price)
FROM customer C, orders O, items I
第 8 章 SQL を使用したプログラミング
253
WHERE C.customer_num = O.customer_num
AND O.order_num = I.order_num
AND O.paid_date is null
GROUP BY C.customer_num, O.order_num
この例のカーソルのアクティブ セットは、3 つの表を結合し、さらに出力の行をグルー
プ化することによって生成されます。オプティマイザが行を正しい順番で生成するとき
にインデックスを使用できることもあります。しかし、ORDER BY 節や GROUP BY
節が使用されている場合は、通常、データベース サーバは生成した行を一時表にコピー
し、その一時表をソートしないと、正しい順序で行を渡すことができません。
アクティブ セットを完全に生成して一時表に保存する場合は、カーソルがオープンされ
るまでにかなりの時間がかかることがあります。一時表が作られる場合には、データベ
ース サーバは、アクティブ セットが何行から構成されているかを知ることができま
す。しかし、この情報をプログラムから利用することはできません。その理由の 1 つ
は、オプティマイザが選択する方法を、事前に予測するのは困難だからです。ソートと
一時表の作成を省くことができる場合には、オプティマイザはそのようにします。しか
し、問合せや表のサイズや利用可能なインデックスがわずかに変わるだけで、オプティ
マイザが使用する方法が変わってしまうことがあります。
順カーソルのアクティブ セット
データベース サーバはできるだけ少ないリソースを使用して、カーソルのアクティブ
セットを保持しようとします。複数行を保持する必要がなければ、次に取り出される 1
行だけしか保持しません。ほとんどの順カーソルについては、1 行だけ保持すれば解決
します。データベース サーバは、取出しが実行されるたびに現在行の内容を戻し、次の
行を検出します。
スクロール カーソルのアクティブ セット
スクロール カーソルのアクティブ セットの行は、カーソルがクローズされるまですべ
て保持しておかなければなりません。これは、次にプログラムから要求される行をデー
タベース サーバが予測できないためです。
データベース サーバは多くの場合、スクロール カーソルのアクティブ セットを一時表
として実行します。ただし、問合せの処理のために一時表を作成する場合は別として、
一時表をすぐに生成しないこともあります。通常はカーソルがオープンされるときに一
時表が作成されます。データベース サーバは行を取り出すと、その行を一時表にコピー
し、プログラムに戻します。同じ行が 2 度目に取り出されるときは一時表からその行を
取り出すことができます。この方法を用いると、すべての行を取り出す前にプログラム
が問合せを中止した場合のリソースが最小になります。取り出されない行が作成された
り、保存されたりすることはありません。
アクティブ セットと並行性
データベース サーバにアクセスしているプログラムが 1 つのみの場合は、アクティブ
セットを構成する行が変化してしまうことはありません。これは、ほとんどのパーソナ
254
IBM Informix SQL ガイド: チュートリアル
ル コンピュータに当てはまるもっとも単純な状況です。しかし、多重プログラミングシ
ステム用に設計しなければならないプログラムもあります。多重プログラミングシステ
ムでは、数個あるいは数十個の異なるプログラムが、同じ表を同時に処理することが考
えられます。
あるプログラムのカーソルがオープンしているときに、他のプログラムがそのカーソル
の表を更新する可能性がある場合には、アクティブ セットの概念は信頼性が高いとはい
えません。表のすべての行が変化していても、プログラムが参照できるのは 1 回に 1
行のデータのみです。
アクティブ セットの 1 行のみがデータベース サーバに保持されるような問合せの場
合、他の行は変更される可能性があります。また、プログラムが行を取り出した直後
に、別のプログラムがその行を削除または更新すると、その行はもはやアクティブ セッ
トに存在しないことがあります。
アクティブ セットの全体、あるいはその一部が一時表に保存されている場合には、失効
したデータ という問題が起こる可能性があります。これは、アクティブ セットの元と
なった実際の表の行が変更される可能性がある、という問題です。元の表が変わって
も、アクティブ セットを構成している行には、現在の表の内容が反映されないものもあ
ります。
プログラムのデータの読込みのみの場合、データの失効は問題になりません。アクティ
ブ セットは、一時点におけるデータの断片です。行の変更が翌日あるいはミリ秒後でも
問題はありません。したがって、プログラムの実行中に発生した変化とプログラムが終
了する間際に適用される変化との間には実際的な差はありません。
データの失効が問題になるのは、プログラムが入力データを使用して同じデータベース
を変更しようとする場合のみです。例えば、銀行業務のアプリケーションが勘定残高を
データベースから読み込んで変更し、変更済みのデータを同じデータベースに書き込む
場合がこれにあたります。データを変更するプログラムについては、第 9 章を参照して
ください。
カーソルの使用: 部品展開
カーソルとプログラム ロジックを組み合わせることにより、SQL のみでは解決できな
い問題を解決できます。このような問題の 1 つが、材料目録処理とも呼ばれる部品展開
です。この問題で重要となるのは、オブジェクト同士の再帰的関係です。再帰的関係と
は、オブジェクトは他のオブジェクトを含むことができ、そのオブジェクトもさらに他
のオブジェクトを含むことができるという関係です。
例として、メーカーの在庫を取り上げます。さまざまな部品を製造している会社がある
と仮定します。部品には、単独で構成される独立した部品と、他の部品の集合で構成さ
れる組み立て品目があります。
第 8 章 SQL を使用したプログラミング
255
これらの関係を 1 つの表に記述します。この表の名前が contains だとします。列
contains.parent に、組立て品のパーツ ナンバーが格納されます。列 contains.child に
は、親のコンポーネントであるパーツのパーツ ナンバーが格納されます。部品番号が
123400 の部品が 9 個の部品からなる組立て品の場合、最初の列には 123400、2 番目の
列には子の部品番号が格納された行が 9 行存在することになります。図 355 に、パー
ツ ナンバー 123400 を表す行の 1 つを示します。
図 355. 部品展開の問題
部品展開の問題は次のとおりです。パーツ・ナンバーが与えられると、そのパーツのコ
ンポーネントであるすべてのパーツのリストを作成します。次に IBM Informix ESQL/C
でのこの問題の 1 つの解決策を示します。
int part_list[200];
boom(top_part)
int top_part;
{
long this_part, child_part;
int next_to_do = 0, next_free = 1;
part_list[next_to_do] = top_part;
EXEC SQL DECLARE part_scan CURSOR FOR
SELECT child INTO child_part FROM contains
WHERE parent = this_part;
while(next_to_do < next_free)
{
this_part = part_list[next_to_do];
EXEC SQL OPEN part_scan;
while(SQLCODE == 0)
{
EXEC SQL FETCH part_scan;
if(SQLCODE == 0)
{
part_list[next_free] = child_part;
next_free += 1;
}
}
EXEC SQL CLOSE part_scan;
256
IBM Informix SQL ガイド: チュートリアル
next_to_do += 1;
}
return (next_free - 1);
}
専門用語では、表 contains の各行は、方向をもつ非周期グラフ、つまりツリーのヘッド
ノードです。関数は、ツリーの横方向優先探索を実行します。ツリーのルートは関数の
パラメータとして渡される部品番号です。関数は、part_scan という名前のカーソルを
使用して、すべての行を、列 parent に特定の値が指定された状態で戻します。一番内
側の while ループはカーソル part_scan をオープンして、選択セット内の各行を取り
出し、各コンポーネントの部品番号が抽出されたときにカーソルをクローズします。
上記の関数は、部品展開問題の核心部を処理しますが、完全な解決策ではありません。
例えば、ツリーの複数のレベルに現れるコンポーネントでは使用できません。さらに、
実際の表 contains には、列 count も含まれ、この列に、それぞれの parent で使用され
た child パーツのカウントが示されます。さらに、実際の表 contains には、列 count
も含まれ、この列にそれぞれの parent で使用された child パーツのカウントが示され
ます。各要素部品の総カウント数を戻すプログラムは、さらに複雑になります。
前述した繰返し処理型のアプローチが、部品展開問題への唯一のアプローチではありま
せん。世代の数に一定の制限がある場合は、入れ子になった外部セルフ結合を使用する
SELECT 文を 1 つ使用すると、この問題を解決できます。
トップレベルの部品に最大で 4 世代の部品が含まれている場合、次の SELECT 文では
それらの部品をすべて戻します。
SELECT a.parent, a.child, b.child, c.child, d.child
FROM contains a
OUTER (contains b,
OUTER (contains c, outer contains d) )
WHERE a.parent = top_part_number
AND a.child = b.parent
AND b.child = c.parent
AND c.child = d.parent
この SELECT 文は、top_part_number として与えられた部品を祖先とする各世代につ
いて 1 行を戻します。存在しないレベルについては NULL が戻されます。NULL を検
出するには標識変数を使用します。表 contains の入れ子になった外部結合をもっと多く
使用すれば、他のレベルに対しても行えます。また、各レベルでの部品の数を戻すよう
に、このプログラムを記述し直すこともできます。
動的 SQL
静的 SQL は便利ですが、プログラムを作成するには SQL 文の内容を事前に完全に理
解していなければなりません。例えば、WHERE 節ではどの列をテストするのか、選択
リストにはどの列を指定するのかをプログラム中に記述しなければなりません。
第 8 章 SQL を使用したプログラミング
257
事前に十分に定義された特定のタスクを実行するプログラムを作成するのなら、これで
十分です。しかし、事前に完全には定義できないデータベース操作を行うプログラムも
あります。特に、ユーザの要求に対話的に応えなければならないプログラムの場合、ユ
ーザからの入力に応じて SQL 文を作成することが必要になります。
動的 SQL を使用すると、プログラムの実行中に SQL 文が生成できるので、ユーザの
入力で文の内容が決定されます。この動作は、次の手順で実行されます。
1. プログラムは、SQL 文のテキストをプログラム変数に格納される文字列として作成
する。
2. プログラムは PREPARE 文を実行する。PREPARE 文はデータベース サーバに対
し、SQL 文のテキストを調べることと、そのテキストを実行できるように準備する
ことを要求する。
3. プログラムは EXECUTE 文を使用して、準備した文を実行する。
この方法を用いると、あらゆる種類のユーザ入力を基にして SQL 文を構築し実行する
ことができます。例えば、SQL 文のファイルを読み込み、それらを処理して実行するこ
とができます。
DB–Access は SQL を対話的に実行するユーティリティで、SQL 文の構築、処理、実行
を動的に行う IBM Informix ESQL/C プログラムです。例えば、DB–Access によって、
簡単な対話式メニューを使用して表の列を指定することができます。ユーザがメニュー
の指定を終えると、DB–Access は必要な CREATE TABLE 文か ALTER TABLE 文を
動的に作成して、それを準備し実行します。
文の PREPARE 文による処理
動的 SQL 文も、構文的には他の SQL 文とほとんど同じです。ただ 1 つの違いは、動
的 SQL 文にはホスト変数名を記述することができない点です。
動的 SQL 文には、2 つの制約事項があります。1 つ目は、それが SELECT 文である場
合に、INTO 節を含めることができないという点です。INTO 節には列のデータを収め
るホスト変数を指定しますが、ホスト変数の使用は、動的文では許可されていません。2
つ目は、式の内部でホスト変数名を使用する場所には、位置指定子として疑問符 (?) を
記述しなければならないという点です。
このフォームの文を PREPARE 文で処理する例を次に示します。次の例は、
IBM Informix ESQL/C で書かれています。
EXEC SQL prepare query_2 from
’SELECT * from orders
WHERE customer_num = ? and order_date > ?’;
この例の 2 つの疑問符は、文が実行されると、ホスト変数の値がこれらの 2 つの場所
で使用されることを示しています。
258
IBM Informix SQL ガイド: チュートリアル
ほとんどの SQL 文は、動的に処理できます。PREPARE 文で処理できない SQL 文
は、PREPARE 文や OPEN 文などの、動的 SQL やカーソル管理に直接関係する文のみ
です。UPDATE または DELETE 文を処理した場合、SQLWARN の 5 番目のフィール
ドをテストし、WHERE 節を使用したかどうか確認してください (242 ページの
『SQLWARN 配列』を参照)。
文を準備した結果は、その文を表すデータ構造体になります。このデータ構造体は、そ
の文を生成した文字列と同じではありません。PREPARE 文の内部でデータ構造体に名
前を付けます。前の例の場合は query_2 がデータ構造体の名前です。この名前が、処理
済みの SQL 文を実行するのに使用されます。
PREPARE 文で処理する文字列には、複数の文を含めることができます。複数の SQL
文を並べる場合は、セミコロン(;) で区切ります。次に、IBM Informix ESQL/C のトラ
ンザクションで記述した、かなり複雑な例を示します。
strcpy(big_query, "UPDATE account SET balance = balance + ?
WHERE customer_id = ?; ¥ UPDATE teller SET balance =
balance + ? WHERE teller_id = ?;");
EXEC SQL PREPARE big1 FROM :big_query;
この例の文の並びが実行されるときに、6 個の位置指定子としての疑問符がホスト変数
の値で置換されます。複数の文の並びを設定するのは大変ですが、プログラムとデータ
ベース サーバ間のやりとりの回数が減るため、パフォーマンスは改善されます。
PREPARE 文で処理された SQL 文の実行
PREPARE 文で処理済みの SQL 文は複数回実行することができます。SELECT 文以外
の 文と 1 行だけ戻す SELECT 文は、EXECUTE 文を使用して実行します。
次の IBM Informix ESQL/C のコードは、銀行の帳簿を更新する複数文を処理し実行す
る PREPARE 文と EXECUTE 文を示します。
EXEC SQL BEGIN DECLARE SECTION;
char bigquery[270] = "begin work;";
EXEC SQL END DECLARE SECTION;
stcat ("update account set balance = balance + ? where ", bigquery);
stcat ("acct_number = ?;’, bigquery);
stcat ("update teller set balance = balance + ? where ", bigquery);
stcat ("teller_number = ?;’, bigquery);
stcat ("update branch set balance = balance + ? where ", bigquery);
stcat ("branch_number = ?;’, bigquery);
stcat ("insert into history values(timestamp, values);", bigquery);
EXEC SQL prepare bigq from :bigquery;
EXEC SQL execute bigq using :delta, :acct_number, :delta,
:teller_number, :delta, :branch_number;
EXEC SQL commit work;
EXECUTE 文の USING 節には、ホスト変数の並びが指定されています。PREPARE 文
によって処理された文の疑問符は、これらのホスト変数の値で置換されます。SELECT
第 8 章 SQL を使用したプログラミング
259
文 (または EXECUTE FUNCTION 文) が戻す行が 1 行のみの場合、EXECUTE 文の
INTO 節を使用してその値を受け取るホスト変数を指定できます。
動的ホスト変数
動的に割り当てられたデータ オブジェクトをサポートする SQL API では、動的 SQL
文をもう 1 段高いレベルで使用することができます。これによって、列データを受け取
るホスト変数を動的に割り当てることができます。
変数の動的割当てによって、任意の SELECT 文をプログラム入力から取り出して、こ
の SELECT 文が生成する値の個数とデータ型を判断して、これらのデータを保持する
適切なデータ型のホスト変数を割り当てることができます。
このようなことを実現するために中心的な役割を果たすのが DESCRIBE 文です。
DESCRIBE 文は、PREPARE 文によって処理された SQL 文の名前を受け取り、その文
に関する情報と内容を戻します。また、SQLCODE を設定して、その文がどの動詞で始
まっているかを示します。PREPARE 文によって処理された文が SELECT 文の場合、
DESCRIBE 文は選択された出力データに関する情報も戻します。PREPARE 文によって
処理された文が INSERT 文の場合には、DESCRIBE 文は入力パラメータに関する情報
を戻します。DESCRIBE 文によって情報を戻されるデータ構造体は、この目的のために
割り当てられ、システム記述子領域として知られている、あらかじめ定義されたデータ
構造体です。IBM Informix ESQL/C を使用している場合は、システム記述子領域あるい
は sqlda 構造体を使用できます。
DESCRIBE 文が SELECT 文に対し戻すか参照するデータ構造体には、構造体の配列が
含まれています。各構造体は、SELECT 文の選択リストの各項目に対し、戻されるデー
タに関する情報を提供します。例えば、プログラムはこの一連の構造体を調べ、戻され
るデータが 10 進数値とある長さの文字値、そして整数からなることを知ることができ
ます。
この情報を使用すると、プログラムは抽出された値を格納するための記憶域をメモリに
割り当て、データベース サーバに送るデータ構造体に記憶域を指すポインタを設定する
ことができます。
PREPARE 文で処理された文の解放
PREPARE 文で処理された SQL 文は、メモリ内の領域を占有します。一部のデータベ
ース サーバでは、この SQL 文がプログラム側の領域だけでなく、データベース サー
バの領域も占有することがあります。SQL 文が占有する領域は、プログラムが終了する
ときに解放されますが、終了時よりも前に解放することが必要になる場合があります。
FREE 文を使用して、この領域を解放できます。FREE 文は、文の名前または文の名前
に対して宣言されたカーソルの名前を指定し、PREPARE 文で処理された文に割り当て
られた領域を解放します。1 つの文に複数のカーソルが定義されている場合、文を解放
してもカーソルは解放されません。
260
IBM Informix SQL ガイド: チュートリアル
実行の高速化
カーソルやホスト変数を必要としない単純な文の場合は、PREPARE 文、EXECUTE
文、FREE 文の処理をまとめて 1 回で行うことができます。次の例は、EXECUTE
IMMEDIATE 文が 1 つの操作で文字列を取り、PREPARE 文で処理して実行し、記憶
域を解放する方法を示しています。
EXEC SQL execute immediate ’drop index my_temp_index’;
この機能により、単純な SQL 文の作成が容易になります。ただし、USING 節が使用で
きないため、EXECUTE IMMEDIATE 文を SELECT 文に使用することはできません。
データ定義文の埋込み
データベースの作成や表の定義の変更を行うような SQL 文、すなわちデータ定義文は
通常、プログラム中には記述されません。プログラム中に記述することがほとんどない
のは、データ定義文はまれにしか実行されないためですが、問合せやデータの変更は何
回も行われます。データベースは 1 回作成されますが、問合せや更新は何回も行われま
す。
データベースとその表の作成は、通常は、DB–Access を使用して対話的に行われます。
これらのツールには SQL 文の入ったファイルが含まれているため、データベースの作
成をオペレーティング システムのコマンド 1 つで行うことが可能です。データ定義文
については、「IBM Informix: SQL ガイド: 構文」および「IBM Informix: データベース
設計および実装 ガイド」に記載されています。
アプリケーションでのアクセス権の付与と取消し
データ定義に関するタスクとして繰返し実行されるのが、アクセス権の付与と取消しで
す。アクセス権の付与と取消しの操作は頻繁に発生し、SQL に不慣れな人によって行わ
れる可能性もあります。この対策として、GRANT 文と REVOKE 文をプログラムにパ
ッケージし、ユーザにとって単純で便利なユーザ インターフェイスを提供する方法があ
ります。
GRANT 文と REVOKE 文は、動的 SQL としての扱いに特に適しています。どちらの
文も、次のようなパラメータを取ります。
v アクセス権の並び
v 表名
v ユーザ名
これらの値の一部はユーザやコマンド行パラメータ、あるいはファイルなどのプログラ
ムへの入力を基に指定することが必要になります。しかし、これらの値はどれも、ホス
ト変数の形式で指定することはできません。これらの文の構文のどこにもホスト変数を
使用することができません。
第 8 章 SQL を使用したプログラミング
261
代替手段は、文の各部を文字列にアセンブルし、アセンブルされた文を PREPARE 文で
処理して実行する方法です。プログラム入力は、準備済みの文に文字列として組み込む
ことがでます。
次の IBM Informix ESQL/C 関数は、関数パラメータから GRANT 文をアセンブルし、
PREPARE 文で処理して実行します。
char priv_to_grant[100];
char table_name[20];
char user_id[20];
table_grant(priv_to_grant, table_name, user_id)
char *priv_to_grant;
char *table_name;
char *user_id;
{
EXEC SQL BEGIN DECLARE SECTION;
char grant_stmt[200];
EXEC SQL END DECLARE SECTION;
sprintf(grant_stmt, " GRANT %s ON %s TO %s",
priv_to_grant, table_name, user_id);
PREPARE the_grant FROM :grant_stmt;
if(SQLCODE == 0)
EXEC SQL EXECUTE the_grant;
else
printf("Sorry, got error # %d attempting %s",
SQLCODE, grant_stmt);
EXEC SQL FREE the_grant;
}
次の例に示す関数の最初の文は、関数の名前とその 3 つのパラメータを指定します。こ
の 3 つのパラメータでは、付与されるアクセス権、アクセス権が付与される表の名前、
およびそれらのアクセス権を付与されるユーザの ID を指定します。
table_grant(priv_to_grant, table_name, user_id)
char *priv_to_grant;
char *table_name;
char *user_id;
関数は、次の例に示されている文を使用して、局所変数 grant_stmt を定義します。こ
の変数は、GRANT 文をアセンブルして保持するのに使用されます。
EXEC SQL BEGIN DECLARE SECTION;
char grant_stmt[200];
EXEC SQL END DECLARE SECTION;
次の例に示されているとおり、GRANT 文は、その定数部分と関数パラメータを連結し
て作成されます。
sprintf(grant_stmt, " GRANT %s ON %s TO %s",priv_to_grant,
table_name, user_id);
262
IBM Informix SQL ガイド: チュートリアル
この文は、次の 6 個の文字列を連結しています。
v GRANT
v 付与されるアクセス権を指定するパラメータ
v ON
v 表名を指定するパラメータ
v TO
v ユーザを指定するパラメータ
この結果、一部がプログラム入力で構成された、完全な GRANT 文が得られます。
PREPARE 文は、アセンブルされた文テキストを、解析のためにデータベース サーバへ
渡します。
データベース サーバが、PREPARE 文の後の SQLCODE にエラー コードを入れて戻し
た場合は、関数はエラー メッセージを表示します。データベース サーバは文の形式を
承認した場合には、ゼロの戻りコードを設定します。このアクションは文が正しく実行
されることを保証するものではありません。その文の構文が正しいことを意味している
に過ぎません。存在しない表を指定したり、実行時でなければ検出できない、その他多
くの種類のエラーが文に含まれていることがあります。例の次の部分は、PREPARE 文
による the_grant の処理が成功したかどうかを実行前にチェックするものです。
if(SQLCODE == 0)
EXEC SQL EXECUTE the_grant;
else
printf("Sorry, got error # %d attempting %s", SQLCODE, grant_stmt);
PREPARE 文の処理が成功した場合 (SQLCODE = = 0) には、次に PREPARE 文で処理さ
れた文が実行されます。
ロールの割当て
別の方法として、DBA は CREATE ROLE 文を使用してロールを定義し、GRANT、
GRANT ROLE、および REVOKE ROLE 文を使用して、そのロールに対するアクセス
権の割当て、付与、および取消しを行うことができます。次に例を示します。
GRANT ROLE engineer TO nmartin;
非デフォルト ロールを活動化するには、SET ROLE 文が必要です。ロールとアクセス
権の詳細については、 6 ページの『アクセス管理ストラテジ』および 207 ページの『デ
ータベースとそのオブジェクトに対するアクセス権』を参照してください。GRANT 文
と REVOKE 文の詳細については、「IBM Informix: データベース設計および実装 ガイ
ド」を参照してください。これらの文の構文の詳細については、「IBM Informix: SQL
ガイド: 構文」を参照してください。
第 8 章 SQL を使用したプログラミング
263
サマリ
SQL 文をプログラム言語の通常の文と同じように扱って、プログラム中に埋め込むこと
ができます。プログラム変数を WHERE 節で使用したり、データベースから取り出した
データをプログラム変数に代入したりすることができます。プリプロセッサは、SQL コ
ードをプロシジャ呼出しとデータ構造体に変換します。
データを戻さない文や 1 行のデータしか戻さない問合せは、プログラム言語の通常の文
と同じように作成することができます。複数の行を戻す可能性のある問合せは、現在行
のデータを表すカーソルと関連付けられます。プログラムはカーソルを使用して、必要
なデータを 1 行ずつ取り出すことができます。
静的 SQL 文は、プログラムのテキストとして書き込まれます。プログラムの実行時に
SQL 文を動的に生成して実行することも可能です。さらに、問合せがどのようなデータ
型の列をいくつ戻すかを調べ、それらを格納するためのメモリ領域を動的に割り当てる
ことができます。
264
IBM Informix SQL ガイド: チュートリアル
第 9 章 SQL プログラムによるデータの更新
DELETE の使用 . . . . . . . . . . .
直接的な削除 . . . . . . . . . . .
直接的な削除の途中で発生するエラー . .
トランザクション ログの使用 . . . .
整合性がある削除 . . . . . . . .
カーソルを使用した削除 . . . . . . .
INSERT の使用 . . . . . . . . . . .
INSERT カーソルの使用方法 . . . . . .
INSERT カーソルの宣言 . . . . . .
カーソルを使用した挿入 . . . . . .
PUT 文と FLUSH 文の実行後の状態コード
定数の行 . . . . . . . . . . . .
挿入の例 . . . . . . . . . . . .
UPDATE 文の使用 . . . . . . . . . .
UPDATE カーソルの使用方法 . . . . .
キーワード UPDATE の目的 . . . . .
特定の列の更新 . . . . . . . . .
常に必要とされないキーワード UPDATE .
表の仕上げ . . . . . . . . . . . .
サマリ . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
266
266
266
267
267
268
270
270
270
271
271
272
273
275
275
276
276
276
276
277
本章について
これまでの章では、SQL 文、特に SELECT 文を、他の言語で作成されたプログラムに
挿入したり、埋め込んだりする方法について説明しました。埋込み SQL を使用する
と、プログラムによるデータベースからのデータ抽出が可能になります。
この章では、プログラムで、表の行を削除、挿入、更新してデータベースを変更する際
に発生する問題について説明します。235 ページの『第 8 章 SQL を使用したプログラ
ミング』と同様に、この章では、IBM Informix の埋込み言語のマニュアルを読むために
必要な情報を紹介します。
INSERT、UPDATE、および DELETE 文の一般的な使用方法については、 183 ページの
『第 6 章 データの変更』に記載されています。この章では、プログラム内部での使用
方法について説明します。これらの文をプログラムの内部に埋め込むこと自体は簡単で
すが、エラーを処理したり、複数のプログラムから同時に実行されるデータ変更操作を
扱うのは、場合により非常に複雑になります。
© Copyright IBM Corp. 1996, 2004
265
DELETE の使用
表内の行を削除するために、プログラムは DELETE 文を実行します。DELETE 文は
WHERE 節を使用した通常の方法で行を指定できるほか、指定したカーソルで取り出さ
れた最後の行を参照できます。
行を削除するときは、その行に依存している行が他の表に含まれていないかを確認する
必要があります。このような整合性がある削除の問題については、第 6 章を参照してく
ださい。プログラム内部から削除が行われる場合も問題は同じです。
直接的な削除
DELETE 文はプログラムに埋め込むことができます。次の例では、IBM Informix
ESQL/C を使用しています。
EXEC SQL delete from items
WHERE order_num = :onum;
これと同じ書式の文を動的に処理し、実行することもできます。どちらの場合も、文は
データベースに直接作用して、表の複数行に影響を与えます。
この例の WHERE 節では、onum というホスト変数の値を使用します。削除が終わる
と、結果が通常どおり SQLSTATE と sqlca 構造体に設定されます。配列 SQLERRD
の 3 番目の要素の値は、エラーが発生した場合も削除した行の数を示しています。
SQLCODE の値は、この操作が成功したかどうかを示します。この値が負ではない場合
は、エラーは発生していません。この場合、SQLERRD の 3 番目の要素の値は、
WHERE 節の条件を満たして削除された行の総数を示しています。
直接的な削除の途中で発生するエラー
エラーが発生すると、文は途中で終了します。エラーの原因は、SQLSTATE と
SQLCODE の値、および SQLERRD の 2 番目の要素の値から判別できます。また、行
のカウントにより、削除された行数が確認できます。多くのエラーでは、データベース
サーバが処理を開始する前にエラーが検出されるため、カウントの値はゼロ (0) です。
例えば、存在しない表を指定した場合や、WHERE 節で指定した列の名前が変更されて
いるような場合は、削除はまったく行われません。
削除が始まって複数行が処理されてから検出されるエラーもあります。このようなエラ
ーでもっとも一般的なのが、ロックの競合です。行を削除する場合、データベース サー
バはその行に対し排他ロックを設定しないと削除できません。他のプログラムが操作の
対象となる表を使用している場合は、データベース サーバはその行をロックできませ
ん。ロックの問題はあらゆる種類の変更操作に影響するため、279 ページの『第 10 章
マルチユーザ環境のためのプログラミング』で詳細に説明しています。
削除を開始した後で、他の特殊なタイプのエラーが発生することがあります。例えば、
データベースの更新中に発生するハードウェアのエラーなどです。
266
IBM Informix SQL ガイド: チュートリアル
トランザクション ログの使用
変更中に発生するあらゆる種類のエラーに対処するには、トランザクション ログ機能を
使用します。トランザクション ログ機能を使用すると、エラーが発生した場合でも、デ
ータベースを変更した直前の状態に戻すことができます。次の例は、266 ページの『直
接的な削除』で示した例を、トランザクションを使用するように拡張したものです。
EXEC SQL begin work;
EXEC SQL delete from items
where order_num = :onum;
del_result = sqlca.sqlcode;
del_isamno = sqlca.sqlerrd[1];
del_rowcnt = sqlca.sqlerrd[2];
if (del_result < 0)
EXEC SQL rollback work;
else
EXEC SQL commit work;
/* start the transaction*/
/*
/*
/*
/*
/*
/*
/*
save two error */
code numbers */
and count of rows */
problem found: */
put everything back */
everything worked OK:*/
finish transaction */
この例で重要なのは、トランザクションを終了する前 に、プログラムが sqlca 構造体
に重要な戻り値を保存していることです。ROLLBACK WORK 文も COMMIT WORK
文も、他の SQL 文と同様に、戻りコードを sqlca 構造体に設定します。ただし、エラ
ーが生成したコードをレポートするには、ROLLBACK WORK 文を実行する前にそれら
を保存する必要があります。これは、ROLLBACK WORK 文が、エラー コードを含む
すべて の保留トランザクションを除去してしまうためです。
トランザクションを使用する利点は、何か問題が発生しても、データベースは不安定な
状態にならないことです。どこまで変更が終了したのかが不明になることはありませ
ん。すべての操作が完全に終了したか、あるいはまったく行われなかったのかのいずれ
になります。
ログ機能を使用するデータベースでは、ユーザが明示的なトランザクションを開始しな
い場合には、データベース サーバは文の実行の前に内部トランザクションを開始し、実
行が完了または失敗した後トランザクションを終了します。文の実行に成功すると、内
部トランザクションは確定されます。文が失敗すると、ロールバックされます。
整合性がある削除
トランザクション ログ機能は、複数の表を削除する場合に特に役立ちます。例えばデモ
ンストレーション データベースから注文を 1 件削除すると仮定します。2 つの表
orders と items から行を削除する場合を、IBM Informix ESQL/C の例で説明します。
EXEC SQL BEGIN WORK;
EXEC SQL DELETE FROM items
WHERE order_num = :o_num;
if (SQLCODE >= 0)
{
EXEC SQL DELETE FROM orders
WHERE order_num == :o_num;
第 9 章 SQL プログラムによるデータの更新
267
{
if (SQLCODE >= 0)
EXEC SQL COMMIT WORK;
{
else
{
printf("Error %d on DELETE", SQLCODE);
EXEC SQL ROLLBACK WORK;
}
このプログラムの論理は、トランザクションの使用あるいは不使用でもほとんど変わり
ません。しかし、トランザクションを使用しない場合、エラー メッセージを見たユーザ
が行う決定が困難になってしまいます。トランザクションを使用しない場合、いつエラ
ーが発生したかによって状況は次のように変わります。
v 削除はまったく行われなかった。この注文番号のすべての行は、データベースに残っ
ている。
v 表 items の行が一部のみ削除された。いくつかの品目 (いくつかは不明) を含む注文
レコードが残っている。
v 表 items のすべての行は削除されたが、表 orders の行は残っている。
v すべての行が削除された。
2 番目と 3 番目の場合、データベースの一部が壊れてしまっています。データベースに
は部分的な情報が入っているため、問合せに対しては間違った結果を戻すことがありま
す。この場合、慎重な処理を行って、情報を一貫性のある状態に戻さなければなりませ
ん。トランザクションを使用していれば、このような不明確な状態になることはありま
せん。
カーソルを使用した削除
カーソルを使用して、取り出した最後の行を削除するように、DELETE 文を記述するこ
ともできます。この方法で行を削除すると、次の例に示すように、WHERE 節でテスト
できない条件に基づいて削除をプログラムすることができます。次の例は、トランザク
ションの始まりと終わりをセットアップする方法のため、ANSI 標準準拠ではないデー
タベースにのみ適用されます。
警告: この例の ESQL/C 関数の設計では、プログラムがいつでも完全に動作するとは限
りません。この関数が正しく動作するかどうかは、現在の排他レベルに依存して
います。排他レベルについては後述します。排他レベルの詳細については、第 10
章を参照してください。たとえ意図したとおりに関数が動作しても、その効果は
表の行の物理的な順序に依存するため、一般的な意味で適切な設計と言えませ
ん。
int delDupOrder()
{
int ord_num;
int dup_cnt, ret_code;
268
IBM Informix SQL ガイド: チュートリアル
EXEC SQL declare scan_ord cursor for
select order_num, order_date
into :ord_num, :ord_date
from orders for update;
EXEC SQL open scan_ord;
if (sqlca.sqlcode != 0)
return (sqlca.sqlcode);
EXEC SQL begin work;
for(;;)
{
EXEC SQL fetch next scan_ord;
if (sqlca.sqlcode != 0) break;
dup_cnt = 0; /* default in case of error */
EXEC SQL select count(*) into dup_cnt from orders
where order_num = :ord_num;
if (dup_cnt > 1)
{
EXEC SQL delete from orders
where current of scan_ord;
if (sqlca.sqlcode != 0)
break;
}
}
ret_code = sqlca.sqlcode;
if (ret_code == 100)
/* merely end of data */
EXEC SQL commit work;
else
/* error on fetch or on delete */
EXEC SQL rollback work;
return (ret_code);
}
この関数の目的は、重複した注文番号を含む行を削除することです。デモンストレーシ
ョン データベースでは、orders.order_num の列番号に一意性インデックスが指定され
ているため、注文番号が重複する可能性はありません。しかし、類似した関数が行に設
定する別のデータベース用に書き込まれている可能性はあります。この場合、使用済み
の列名が指定されます。
この関数は、表 orders のすべての行を走査するカーソルとして、scan_ord を宣言して
います。このカーソルは FOR UPDATE 節で宣言されていますが、これは、カーソルが
データの変更に使用できることを示しています。カーソルが正しくオープンした場合
は、この関数はトランザクションを開始し、表の各行を反復処理します。この関数は、
表の各行について、埋込み SELECT 文を使用して、現在行と注文番号が同じ行が表に
何行あるかを調べます。第 10 章で説明するように、この手順は、排他レベルが正しく
ないと失敗します。
デモンストレーション データベースでは、この表に一意性インデックスが付いているた
め、dup_cnt に戻されるカウント、つまり重複行の数は常に 1 です。この値が 1 より
も大きい場合は、この関数は表の現在行を削除して、カウント数を 1 減らします。
第 9 章 SQL プログラムによるデータの更新
269
このような目的で使用される関数は、この例より高度な設計を必要とします。この関数
は、データベース サーバが戻す最後の重複行以外のすべての重複行を削除します。この
順番は、行の内容や意味とはまったく関係がありません。前出の例の関数は、カーソル
宣言に ORDER BY 節を追加することで改善することができます。ただし、ORDER BY
節と FOR UPDATE 節を同時に使用することはできません。273 ページの『挿入の例』
で、より適切な方法を説明します。
INSERT の使用
INSERT 文はプログラムに埋め込むことができます。その形式およびプログラム内での
使用方法は、第 6 章で説明したものと同じですが、追加機能として、ホスト変数を式内
で、VALUES 節と WHERE 節の両方で使用できます。さらに、プログラムにカーソル
を使用して行を挿入することもできます。
INSERT カーソルの使用方法
DECLARE CURSOR 文には多くの種類があります。その大部分は、データに対してさ
まざまな走査を行うカーソルを作成するためのものですが、INSERT カーソル という特
別な種類のカーソルを作成するものがあります。INSERT カーソルを PUT 文と FLUSH
文で使用すると、複数の行を一括して効率よく表に挿入できます。
INSERT カーソルの宣言
INSERT カーソルを作成するには、SELECT 文の変わりに INSERT 文についてカーソ
ルを宣言します。このように宣言したカーソルは、行の取出しには使用できません。使
用できるのは行の挿入だけです。次の 4GL コード フラグメントに、INSERT カーソル
の宣言の例を示します。
DEFINE the_company LIKE customer.company,
the_fname LIKE customer.fname,
the_lname LIKE customer.lname
DECLARE new_custs CURSOR FOR
INSERT INTO customer (company, fname, lname)
VALUES (the_company, the_fname, the_lname)
INSERT カーソルをオープンすると、一群の行を格納するためのバッファがメモリ内に
作成されます。このバッファにはプログラムが生成した行が格納されます。バッファが
フルになると、バッファ内のすべての行が一括してデータベース サーバへ送られます。
こうすれば、プログラムとデータベース サーバとの間の通信量が減るとともに、データ
ベース サーバはより簡単に行を挿入できるようになります。その結果、挿入処理が高速
化されます。
バッファは、常に少なくとも 1 行の挿入データが入る大きさに作成されます。バッファ
の最小サイズより行が十分に短い場合は、バッファには複数の行が格納されます。
270
IBM Informix SQL ガイド: チュートリアル
カーソルを使用した挿入
上記の例は、INSERT カーソルが使用できるよう PREPARE 文で処理されています。次
の例は、カーソルをどのように使用するかを示しています。問題を単純にするため、こ
の例では、next_cust という関数が新しい顧客に関する情報か、入力の終わりを知らせる
NULL データのどちらかを戻すと仮定しています。
EXEC SQL BEGIN WORK;
EXEC SQL OPEN new_custs;
while(SQLCODE == 0)
{
next_cust();
if(the_company == NULL)
break;
EXEC SQL PUT new_custs;
}
if(SQLCODE == 0)
{
EXEC SQL FLUSH new_custs;
if(SQLCODE == 0)
EXEC SQL COMMIT WORK;
}
else
EXEC SQL ROLLBACK WORK;
/* if no problem with PUT */
/* write any rows left */
/* if no problem with FLUSH */
/* commit changes */
/* else undo changes */
この例のコードでは next_cust が繰り返し呼び出されています。next_cust が NULL で
ないデータを戻すと、PUT 文はそのデータを行バッファへ送ります。バッファがフルに
なると、バッファ内の行は自動的にデータベース サーバへ送られます。WHILE ループ
は、next_cust が戻すデータがなくなると正常終了します。ループから抜けた後、
FLUSH 文がバッファ内に残っている行を表に書き込み、それが終わると、このトラン
ザクションは終了します。
270 ページの INSERT 文を再度確認してください。この INSERT 文自体は、カーソル
定義の一部ではなく、表 customer に 1 行を挿入します。実際、この例から INSERT
カーソルを指定する部分を削除して、INSERT 文を PUT 文がある位置に書くこともで
きます。その違いは、INSERT カーソルの方がプログラムの実行速度が多少速いという
点です。
PUT 文と FLUSH 文の実行後の状態コード
PUT 文を実行する場合、プログラムは行が実際にバッファに格納されたかどうかをテス
トする必要があります。新しい行がバッファに入った場合、PUT 文が行う操作は、その
行をバッファにコピーすることのみです。この場合、エラーが発生する可能性はありま
せん。しかし、新しい行がバッファに入りきらない場合は、バッファの中身全体がデー
タベース サーバに渡されて表に挿入されるため、このときにエラーが発生する可能性が
あります。
第 9 章 SQL プログラムによるデータの更新
271
SQL 通信領域 (SQLCA) に戻される値が、プログラムに対し、それぞれの場合を分類す
るための情報を示します。PUT 文が実行されるたびに、SQLCODE および SQLSTATE
が、エラーが発生しなかった場合はゼロに、エラーが発生した場合は負のエラー コード
に、それぞれ設定されます。
データベース サーバにより、SQLERRD の 3 番目の要素は、表に実際に挿入された行
の数に設定されます。以下のようになります。
v 新しい行がバッファにコピーされただけの場合はゼロ
v バッファの中身がエラーを発生せずに挿入された場合は、バッファに格納されていた
行数
v 挿入中にエラーが発生した場合は、それまでに挿入された行数
コードを再度読んで、SQLCODE をどのように使用しているか確認してください。前出
の例を参照してください。まず、OPEN 文でエラーが発生した場合は、WHILE 条件が
機能しないためにループが実行されず、FLUSH 操作も実行されずに、トランザクショ
ンがロールバックします。次に、PUT 文がエラーを戻す場合は、WHILE 条件によりル
ープは終了し、FLUSH 操作は実行されずに、トランザクションがロールバックしま
す。これが発生するのは、バッファを少なくとも 1 回はフルにするだけの数の行がルー
プによって生成された場合のみです。その他の場合は、PUT 文の実行でエラーが発生す
ることはありません。
行がバッファに残っていても、場合によっては、1 行も挿入されていないにもかかわら
ずループが終了することがあります。この時点で SQL の状態はゼロになり、FLUSH 操
作が実行されます。FLUSH 操作がエラー コードを生成する場合は、トランザクション
がロールバックします。トランザクションがコミットするのは、すべての行が完全に成
功したときのみです。
定数の行
INSERT カーソルを使用すると簡単に高い効率が得られる特殊な場合が 1 つあります。
それは、INSERT 文にリストされた値すべてが定数の場合、つまり、式もホスト変数も
なく、リテラル番号と文字列だけが並ぶ場合です。このような INSERT 文は、何回実行
しても同じ行を生成します。行が同じである場合、コピーし、バッファに入れ、転送す
ることはありません。
このような INSERT 文では、PUT 文はカウンタの値を増加するだけで他に何も行いま
せん。最後に FLUSH 文が実行されるときに、行の単一コピーと挿入の回数がデータベ
ース サーバへ渡されます。データベース サーバは渡された情報を基に、必要な数の行
を生成して 1 回の操作で挿入します。
同じ行を数多く挿入することは、通常ありません。ただし、データベースを作成した直
後には、大規模な表を NULL データで埋めるために、同一行を挿入できます。
272
IBM Informix SQL ガイド: チュートリアル
挿入の例
268 ページの『カーソルを使用した削除』では、重複行を表から探し出して削除するこ
とを目的とする、DELETE 文の例を説明しました。不要な行を削除するのではなく、必
要な行を選択した方が、このタスクを適切に実行できます。次の IBM Informix ESQL/C
のコードは、このタスクを遂行する方法の一例です。
EXEC SQL BEGIN DECLARE SECTION;
long last_ord = 1;
struct {
long int o_num;
date
o_date;
long
c_num;
char
o_shipinst[40];
char
o_backlog;
char
o_po[10];
date
o_shipdate;
decimal o_shipwt;
decimal o_shipchg;
date
o_paiddate;
} ord_row;
EXEC SQL END DECLARE SECTION;
EXEC SQL BEGIN WORK;
EXEC SQL INSERT INTO new_orders
SELECT * FROM orders main
WHERE 1 = (SELECT COUNT(*) FROM orders minor
WHERE main.order_num = minor.order_num);
EXEC SQL COMMIT WORK;
EXEC SQL DECLARE dup_row CURSOR FOR
SELECT * FROM orders main INTO :ord_row
WHERE 1 < (SELECT COUNT(*) FROM orders minor
WHERE main.order_num = minor.order_num)
ORDER BY order_date;
EXEC SQL DECLARE ins_row CURSOR FOR
INSERT INTO new_orders VALUES (:ord_row);
EXEC SQL BEGIN WORK;
EXEC SQL OPEN ins_row;
EXEC SQL OPEN dup_row;
while(SQLCODE == 0)
{
EXEC SQL FETCH dup_row;
if(SQLCODE == 0)
{
if(ord_row.o_num != last_ord)
EXEC SQL PUT ins_row;
last_ord = ord_row.o_num
continue;
}
break;
}
if(SQLCODE != 0 && SQLCODE != 100)
EXEC SQL ROLLBACK WORK;
第 9 章 SQL プログラムによるデータの更新
273
else
EXEC SQL COMMIT WORK;
EXEC SQL CLOSE ins_row;
EXEC SQL CLOSE dup_row;
この INSERT 文は、重複していない行を表から検出し、別の表に挿入します。挿入先の
表は、このプログラムの開始前に作成されている必要があります。この操作を行うと、
重複している行のみが残ります。デモンストレーション データベースの表 orders に
は、一意性インデックスが付いているため、行が重複する可能性はありません。この例
では、デモンストレーション データベース以外のデータベースを取り上げています。
上記の例では、その後 2 つのカーソルを宣言します。最初の dup_row というカーソル
は、表の重複行を取り出します。dup_row は入力専用なので、ORDER BY 節を使用し
て重複行をソートすることができます。268 ページの例で示したように、物理的順序で
行がソートされることはありません。この例では、重複行は日付の順にソートされてい
ます。これは、最も古い日付の行が格納されるようにするためです。目的に応じて、他
の順序でソートすることも可能です。
2 番目のカーソル、ins_row は INSERT カーソルです。このカーソルは、C 構造体、
ord_row を使用できるという利点を生かして、その行のすべての列に値を与えます。
コードの残りの部分は、dup_row から取り出した行を調べます。重複行の各グループか
ら最初の 1 行だけを選んで表に挿入し、残りの行は無視します。
簡潔さのために、前出の例では、最も単純な種類のエラー処理を使用しています。すべ
ての行が処理される前にエラーが発生した場合には、サンプル コードは実行されたトラ
ンザクションにロールバックします。
影響を受ける行の数
カーソルを使用して行を選択するプログラムでは、SQLCODE の戻りコードがデータの
終わりを示す 100 かどうか、また SQLSTATE では 02000 かどうかを調べることがで
きます。このコードは、問合せ条件を満たす行が存在しないか、またはこれ以上存在し
ないかを示すために設定されます。ANSI 標準に準拠していないデータベースでは、デ
ータの終わりを示す戻りコードが設定されるのは、SELECT 文の後の SQLCODE や
SQLSTATE のみです。この値は、DELETE 文、INSERT 文、または UPDATE 文の後
には使用されません。ANSI 標準準拠データベースでは、UPDATE 文、DELETE 文、
INSERT 文では、プログラム操作の影響を受ける行が含まれない場合でも SQLCODE
が 100 に設定されます。
データを取り出さなかった問合せは、成功したとはみなされません。これに対して、
UPDATE 文と DELETE 文では、1 行も更新または削除を行わなくても成功したものと
見なされます。これは、WHERE 節の条件を満たす行の集合が更新または削除されまし
たが、その集合が空であったことを意味します。
274
IBM Informix SQL ガイド: チュートリアル
INSERT 文の場合も同様です。挿入対象の行が SELECT 文の結果で、その SELECT 文
が 1 行も選択しなかった場合でも、データの終わりを示す戻りコードは設定されませ
ん。この場合、INSERT 文は成功したと見なされます。指定された数の行、この場合は
ゼロ行を挿入しているためです。
挿入、更新、削除された行が何行あるかは、SQLERRD の 3 番目の要素を調べるとわか
ります。SQLCODE の値が何であっても、この要素の値は、挿入、更新、削除された行
数を示しています。行数がゼロや負の値であっても、その値が示されます。
UPDATE 文の使用
第 6 章で説明した、どの形式のプログラムにでも、UPDATE 文を埋め込むことができ
ます。追加機能として、SET 節および WHERE 節の両方で、ホスト変数を式内で指定
できます。さらにプログラムでは、カーソルが指定する行を更新することができます。
UPDATE カーソルの使用方法
UPDATE カーソル により、現在行を削除または更新できます。現在行とは最後に取り
出された行のことです。IBM Informix ESQL/C で記述された次の例に、UPDATE カー
ソルの宣言を示します。
EXEC SQL
DECLARE names CURSOR FOR
SELECT fname, lname, company
FROM customer
FOR UPDATE;
このカーソルを使用するプログラムは、次に示すように入力用のカーソルと同様に行を
取り出すことができます。
EXEC SQL
FETCH names INTO :FNAME, :LNAME, :COMPANY;
取り出した行を変更する必要がある場合は、次に示すように更新することもでき ます。
if (strcmp(COMPANY, "SONY") ==0)
{
EXEC SQL
UPDATE customer
SET fname = ’Midori’, lname = ’Tokugawa’
WHERE CURRENT OF names;
}
この WHERE 節では、通常の条件式の代わりに CURRENT OF names が使用されていま
す。これ以外は、この UPDATE 文は通常の UPDATE 文と同じです。この文に指定さ
れている表名は、カーソル名から間接的にわかりますが、指定しなければなりません。
第 9 章 SQL プログラムによるデータの更新
275
キーワード UPDATE の目的
キーワード UPDATE を使用して UPDATE カーソルを宣言するのは、取り出された行
が更新または削除される可能性があることをデータベース サーバに知らせるためです。
データベース サーバは、UPDATE カーソルによって取り出された行に厳しいロックを
設定し、このキーワードが宣言されていないカーソルによって取り出された行にはあま
り厳しくないロックを設定します。これにより、通常のカーソルについては効率が向上
し、多重プロセッシング システムでは並行性が高まります。ロックのレベルと並行使用
については、第 10 章で説明します。
特定の列の更新
次の例は、UPDATE カーソルの前述の例の特定の列を更新しています。
EXEC SQL
DECLARE names CURSOR FOR
SELECT fname, lname, company, phone
INTO :FNAME,:LNAME,:COMPANY,:PHONE FROM customer
FOR UPDATE OF fname, lname
END-EXEC.
このカーソルを使用して更新できる列は、列 fname と列 lname のみです。次のような
文は、エラーと見なされるため実行できません。
EXEC SQL
UPDATE customer
SET company = ’Siemens’
WHERE CURRENT OF names
END-EXEC.
このような UPDATE 文がプログラムに含まれていると、エラー コードが戻されて、更
新は行われません。WHERE CURRENT OF を指定した削除も実行できません。削除は
すべての列に影響すると考えられるためです。
常に必要とされないキーワード UPDATE
ANSI 標準の SQL では、カーソル定義での FOR UPDATE 節は提供されていません。
ANSI 標準準拠のデータベースを使用するプログラムは、任意のカーソルを使用して更
新や削除を実行できます。
表の仕上げ
UPDATE カーソルの使用例をもう 1 つ示します。この問題も、完成したデータベース
では絶対に発生しませんが、アプリケーションの初期設計段階で発生する問題です。
この例では、target という大きな表が構築、移植されています。dactyl という文字カラ
ムに、誤って NULL 値が複数挿入されました。これらの列は削除しなければなりませ
ん。さらに、表の作成後に、ALTER TABLE 文を使用して serials という名前の新しい
276
IBM Informix SQL ガイド: チュートリアル
列を追加しました。この列には、一意の整数値を割り当てる必要があります。次の例で
は、このタスクを実行するために使用する IBM Informix ESQL/C コードを示していま
す。
EXEC SQL BEGIN DECLARE SECTION;
char dcol[80];
short dcolint;
int sequence;
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE target_row CURSOR FOR
SELECT datcol
INTO :dcol:dcolint
FROM target
FOR UPDATE OF serials;
EXEC SQL BEGIN WORK;
EXEC SQL OPEN target_row;
if (sqlca.sqlcode == 0) EXEC SQL FETCH NEXT target_row;
for(sequence = 1; sqlca.sqlcode == 0; ++sequence)
{
if (dcolint < 0) /* null datcol */
EXEC SQL DELETE WHERE CURRENT OF target_row;
else
EXEC SQL UPDATE target SET serials = :sequence
WHERE CURRENT OF target_row;
}
if (sqlca.sqlcode >= 0)
EXEC SQL COMMIT WORK;
else EXEC SQL ROLLBACK WORK;
サマリ
プログラムでは、INSERT 文、DELETE 文、および UPDATE 文を実行できます。これ
については、第 6 章で説明しています。またプログラムでは、表をカーソルで走査し
て、指定した行を更新または削除することもできます。また、行の挿入にもカーソルを
使用することができます。これには、行がバッファに格納されてから、一括してデータ
ベース サーバに送られるという利点があります。
このような操作を行う場合、エラーを検出し、エラーが発生した場合にはデータベース
を復元するようなプログラムを作成する必要があります。この復元処理で最重要のツー
ルは、トランザクション ログ機能です。プログラムでトランザクション ログ機能を使
用しないと、エラーからの復旧が困難になります。
第 9 章 SQL プログラムによるデータの更新
277
278
IBM Informix SQL ガイド: チュートリアル
第 10 章 マルチユーザ環境のためのプログラミング
並行性およびパフォーマンス . . . . . . . . . . . . . . . . .
ロックおよび整合性 . . . . . . . . . . . . . . . . . . . .
ロックおよびパフォーマンス . . . . . . . . . . . . . . . . .
並行性の問題 . . . . . . . . . . . . . . . . . . . . . .
ロックの動作 . . . . . . . . . . . . . . . . . . . . . .
ロックの種類 . . . . . . . . . . . . . . . . . . . . .
ロック範囲 . . . . . . . . . . . . . . . . . . . . . .
データベース ロック . . . . . . . . . . . . . . . . .
表ロック . . . . . . . . . . . . . . . . . . . . .
行とキーのロック . . . . . . . . . . . . . . . . . .
ページ ロック . . . . . . . . . . . . . . . . . . . .
コアース インデックス ロック . . . . . . . . . . . . . .
スマート ラージ オブジェクトのロック (IDS) . . . . . . . . .
ロックの継続期間 . . . . . . . . . . . . . . . . . . .
データ修正中のロック . . . . . . . . . . . . . . . . . .
SELECT 文でのロック . . . . . . . . . . . . . . . . . . .
排他レベルの設定 . . . . . . . . . . . . . . . . . . .
SET TRANSACTION 文と SET ISOLATION 文の比較 . . . . . .
排他レベルの非確定読込み (ANSI) と単純読込み (Informix) . . . .
排他レベルの確定読込み (ANSI) および確定読込み (Informix) . . . .
排他レベルのカーソル安定性 (Informix) . . . . . . . . . . .
直列化可能 (ANSI)、繰返し可能読込み (ANSI)、および繰返し可能読込み
ル. . . . . . . . . . . . . . . . . . . . . . . .
UPDATE カーソル . . . . . . . . . . . . . . . . . . .
更新ロックの保存 . . . . . . . . . . . . . . . . . . . .
INSERT 文、UPDATE 文、および DELETE 文により設定するロック . . .
ロック タイプの動作の理解 . . . . . . . . . . . . . . . . .
アクセス モードによるデータ変更の制御 . . . . . . . . . . . . .
ロック モードの設定 . . . . . . . . . . . . . . . . . . .
ロックの待機 . . . . . . . . . . . . . . . . . . . . .
ロックの解除を待機しない . . . . . . . . . . . . . . . .
一定時間ロックの解除を待機する . . . . . . . . . . . . . .
デッドロックの処理 . . . . . . . . . . . . . . . . . . .
外部デッドロックの処理 . . . . . . . . . . . . . . . . .
単純な並行性 . . . . . . . . . . . . . . . . . . . . . .
HOLD カーソル . . . . . . . . . . . . . . . . . . . . .
SQL 文キャッシュの使用 . . . . . . . . . . . . . . . . . .
© Copyright IBM Corp. 1996, 2004
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
(Informix)
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
排他レベ
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
280
280
280
281
282
283
283
284
284
286
287
288
289
289
290
290
291
291
292
292
293
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
295
296
296
297
297
299
299
300
300
300
300
301
301
302
303
279
サマリ .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 304
本章について
この章では、マルチユーザ環境で操作する場合に把握しておく必要がある、プログラミ
ングの問題をいくつか説明します。
データベースが保存されているコンピュータがシングルユーザ用のワークステーション
で、他のコンピュータからデータにアクセスしなければ、プログラムはそのデータベー
スのデータを自由に変更できます。しかし、これ以外では、あるプログラムがデータを
変更しているときに、他のプログラムが同じデータを読み込んだり変更したりする可能
性があります。この状態は並行性 と称されます。つまり、同じデータを複数のプログラ
ムが同時に使用することを指します。この章では、同時実行性、ロック、および排他レ
ベルについて説明します。
この章では、セッションあたりのメモリ割当てを削減して、問合せ処理を高速化するこ
とができる、文キャッシュ機能も説明します。文キャッシュが格納した文は、同じ SQL
文を使用する異なるユーザ セッションで共有できます。
並行性およびパフォーマンス
同時実行性は、複数プログラミング システムのパフォーマンス向上に不可欠なもので
す。1 回に 1 本のプログラムのデータのみを使用するようにデータベースへのアクセス
を直列化 すると、処理速度は大幅に低下してしまいます。
ロックおよび整合性
データへのアクセスを適切に制御しないと、同時実行性はさまざまな弊害をもたらす恐
れがあります。プログラムが、失効したデータを読み込んだり、成功とみなされた変更
操作の結果が失われるかもしれません。
データベース サーバは、ロック を系統的に設定することによって、このようなエラー
を防止します。ロックは、データの各部に対するプログラムからの使用予約です。デー
タベース サーバは、ロックされているデータについては、他のプログラムがそのデータ
を更新できないようにします。他のプログラムがそのデータを要求した場合は、ロック
が解除されるまでそのプログラムを待機させるか、あるいはエラー メッセージを発行し
てその要求を拒否します。
ロックおよびパフォーマンス
ロックは 1 つのデータに対するアクセスを直列化するため、同時実行性は低下します。
ロックされているデータにアクセスしようとするプログラムは待機しなければなりませ
ん。データベース サーバは単一の行、複数の行を持つディスク ページ、表全体、また
はデータベース全体をロックすることができます (ディスク ページは、複数の行を持つ
280
IBM Informix SQL ガイド: チュートリアル
ことができ、行は複数のディスク ページを必要とすることがあります)。データベース
サーバが設定するロックの数が多いほど、また、ロック対象のオブジェクトが大きいほ
ど、同時実行性は低下します。ロックの数が少なくオブジェクトが小さいほど、同時実
行性とパフォーマンスは向上します。
以下の各節で、プログラムが次の目標を達成する方法について説明します。
v データ整合性を維持するために必要なロックを、すべて設定する。
v 最初の目標を達成できる範囲内で、ロックの数とロック対象のデータのサイズを可能
な限り減らす。
並行性の問題
同時実行性の弊害を理解するには、それぞれが独自の速度で動作する複数のプログラム
が実行されている状況を考える必要があります。例えば、あるアプリケーション プログ
ラムが、次のように宣言されたカーソルを使用して行を取り出すと想定します。
EXEC SQL DECLARE sto_curse CURSOR FOR
SELECT * FROM stock
WHERE manu_code = ’ANZ’;
データベース サーバが各行をプログラムへ転送するには時間がかかります。行が転送さ
れているとき、あるいは転送が終わってから次の転送が始まるまでの間に、他のプログ
ラムが他のデータベース操作を実行することがあります。あるユーザのプログラムが問
合せにより生成された行を取り出すときに、別のユーザのプログラムが次の更新を実行
する可能性もあります。
EXEC SQL UPDATE stock
SET unit_price = 1.15 * unit_price
WHERE manu_code = ’ANZ’;
2 つのプログラムは、同じ表にアクセスすることになり、一方はある行を取り出し、も
う一方はその行を更新します。以下のようなケースが考えられます。
1. 作成したプログラムが最初の行を取り出すときには、他のプログラムは更新をすでに
終了している。
この場合、作成したプログラムが取り出すのは更新後の行です。
2. 作成したプログラムは、他のどのプログラムが変更するよりも早く表の行を取り出
す。
この場合、作成したプログラムが取り出すのは更新前の古い行です。
3. 作成したプログラムが更新前の行を何行か取り出した後で、他のプログラムが追いつ
き、ユーザのプログラムがまだ取り出していない行を更新してしまう。更新が終了す
ると、他のプログラムは COMMIT WORK 文を実行する。
第 10 章 マルチユーザ環境のためのプログラミング
281
この場合、作成したプログラムが取り出すのは、一部は更新前の行、残りは更新後の
行です。
4. 表の更新が終了すると、他のプログラムが ROLLBACK WORK 文を発行する以外
は、3 番目の場合と同じ。
この場合も、作成したプログラムが取り出すのは、一部は更新前の行、残りは更新後
の行ですが、更新後の行はすでにデータベースに存在しません。
最初の 2 つの可能性は、深刻な事態を招きません。最初の可能性の場合、他のプログラ
ムによる更新は、作成したプログラムが問合せを始める前に完了しています。完了した
のがマイクロ秒前であっても 1 週間前であっても、違いはありません。
2 番目の可能性の場合は、作成したプログラムの問合せは、他のプログラムが更新を始
める前に実質的に完了しています。他のプログラムは、作成したプログラムより 1 行ず
つ遅れて更新するか、もしくは翌日の夜に更新を始める可能性もありますが、詳細を判
別する必要はありません。
これに対し、残りの 2 つの可能性は、アプリケーションの設計によっては非常に深刻な
事態を招くことがあります。3 番目の可能性の場合は、問合せは更新前のデータと更新
後のデータを合わせて戻します。アプリケーションによっては、これが問題になること
があります。しかし、例えばすべての価格の平均を求めるようなアプリケーションの場
合は、まったく問題にならないと考えられます。
4 番目の可能性の場合は、トランザクションが取り消されたために表に既に存在しなく
なった行をプログラムが戻すことがあるため深刻です。
作成したプログラムが、最後に取り出した行の更新あるいは削除を実行できるカーソル
を使用している場合は、別の問題が発生します。次の一連のイベントが行われた場合に
は、その結果は誤ったものになります。
v 作成したプログラムが行を取り出す。
v 他のプログラムがその行を更新あるいは削除する。
v 作成したプログラムが WHERE CURRENT OF cursor_name を更新または削除する。
このような、並行するイベントを制御するには、データベース サーバのロックと排他レ
ベル の機能を使用します。
ロックの動作
Informix データベース サーバは、ここで説明する複雑かつ柔軟な一群のロック機能をサ
ポートします。ロック機能の要約は、「IBM Informix: Dynamic Server スタートアップ
ガイド」を参照してください。
282
IBM Informix SQL ガイド: チュートリアル
ロックの種類
次の表に、Informix データベース サーバがサポートする、状況に応じて使い分けられる
ロックの種類を示します。
ロックの種類
使用方法
共有
共有ロックを設定すると、オブジェクトは読込み専
用になります。共有ロックが設定されている間は、
オブジェクトの変更はできません。同じオブジェク
トに対し、複数のプログラムが共有ロックを設定で
きます。共有モードでロックされたレコードは、複
数のオブジェクトから読み込むことができます。
排他
排他ロックを設定すると、オブジェクトは単一プロ
グラム専用に使用されるようになります。このロッ
クは、このプログラムがオブジェクトを変更しよう
とすると使用されます。
他のタイプのロックが存在する場合は、排他ロック
を設定することはできません。排他ロックを設定し
た後は、同じオブジェクトに別のロックを設定する
ことはできません。
増進可能/更新
増進可能な (または更新) ロックは、更新の意図を
明確にします。このロックは、他の増進可能なロッ
クや排他ロックが設定されていないオブジェクト以
外に設定できません。しかし、共有ロックが設定さ
れているレコードに対しては、増進可能なロックを
設定できます。ロックされたオブジェクトをプログ
ラムが変更しようとするとき、増進可能なロックを
排他ロックに増進することができます。しかし、こ
れは、増進可能なロックから排他ロックに変更され
るときに、共有ロックを含む他のロックがレコード
に対して設定されていない場合に限ります。増進可
能なロックを設定したときに、共有ロックがレコー
ドにあった場合には、増進可能なロックが排他ロッ
クに増進する前に、共有ロックを解除する必要があ
ります。
ロック範囲
ロックは、データベース全体や表全体に対し、あるいは個々のディスク ページ、行単
位、インデックス キー値に対し設定できます。ロックされるオブジェクトのサイズを、
ロック範囲 (またはロックの細分性) と呼びます。一般に、ロック範囲が広くなるほど
同時実行性は低下しますが、プログラミングは簡単になります。
第 10 章 マルチユーザ環境のためのプログラミング
283
データベース ロック
データベース全体をロックできます。データベースをオープンすると、データベースの
名前に共有ロックが設定されます。データベースは CONNECT、DATABASE または
CREATE DATABASE 文でオープンされます。データベースが、あるプログラムによっ
てオープンされている場合、そのデータベースに共有ロックが設定されているため、他
のプログラムはデータベースを削除したり、データベースに対し排他的ロックを設定し
たりすることはできません。
次の文で、データベース全体に排他ロックを設定する方法を示します。
DATABASE database_one EXCLUSIVE
データベースが他のプログラムによりオープンされていなければ、この文は成功しま
す。排他ロックが設定されると、読込みが目的の場合でも、他のプログラムはそのデー
タベースをオープンできなくなります。データベース名に共有ロックが設定できないた
めです。
データベースのロックが解除されるのは、データベースがクローズされるときのみで
す。このアクションは、DISCONNECT または CLOSE DATABASE 文を使用して明示
的に、もしくは別の DATABASE 文を使用して暗黙的に実行できます。
データベースをロックすると、そのデータベースの同時実行性がゼロになるため、同時
実行性の影響を受けず、プログラミングは非常に簡単になります。しかし、データベー
スのロックは、そのデータベースにアクセスすることが必要なプログラムが他に存在し
ない場合にのみ行ってください。データベースのロックが行われるのは、データベース
があまり利用されていない時間帯に、データベースのデータを大規模に更新する場合な
どです。
表ロック
表全体をロックできます。場合によっては、データベース サーバにより自動的にロック
されます。LOCK TABLE 文を使用すると、表全体を明示的にロックできます。
LOCK TABLE 文またはデータベース サーバは、以下の種類の表ロックを設定できま
す。
v 共有ロック
どのユーザも表に書き込めなくなります。共有モードでは、データベース サーバに
よって表に共有ロックが設定され、他のユーザが更新できないことが通知されます。
また、データベース サーバにより、更新、削除、または挿入されたあらゆる行にロ
ックが追加されます。
v 排他ロック
他のユーザは、表の読取りと書込みを実行できなくなります。排他モードでは、デー
タベース サーバによって、更新した行数にかかわらず表に排他ロックが 1 つだけ設
284
IBM Informix SQL ガイド: チュートリアル
定されます。表に対し排他ロックを設定すると、その表を複数のプログラムで同時に
使用することがまったくできなくなります。したがって、多くのプログラムがその表
の使用を要求している場合は、パフォーマンスに重大な影響を与えることがありま
す。しかし、表の大部分の行を更新する必要がある場合は、表に排他ロックを設定し
ます。
LOCK TABLE 文による表のロック: トランザクションによって、データベース
サーバに、表に対して LOCK TABLE 文を使用した表レベルのロックを使用するよう指
定されます。次の例で、表に排他ロックを設定する方法を示します。
LOCK TABLE tab1 IN EXCLUSIVE MODE
次の例で表に共有ロックを設定する方法を示します。
LOCK TABLE tab2 IN SHARE MODE
ヒント: 排他レベルをデータベース サーバに設定することにより、より大きな同時実行
性を提供しながら共有ロックの表と同じ程度の保護を達成できます。
データベース サーバが表を自動的にロックする場合: データベース サーバによ
り、次の文の実行中は常に表全体がロックされます。
v ALTER FRAGMENT 文
Dynamic Server
v ALTER INDEX 文
Dynamic Server の終り
v ALTER TABLE 文
v CREATE INDEX 文
v DROP INDEX 文
v RENAME COLUMN 文
v RERENAME TABLE 文
文の実行が終了すると、またはトランザクションが終了すると、ロックは自動的に解除
されます。後述するように、特定の問合せが実行されているときに、表全体が自動的に
ロックされることもあります。
キーワード ONLINE による表ロックの回避 (IDS): キーワード ONLINE を使用
することで、インデックスの作成または削除時に表ロックを回避できます。インデック
スがオンラインで作成または削除される場合、表での DDL 操作はサポートされません
が、CREATE INDEX 文または DROP INDEX 文の発行と並行して実行されていた操作
は完了できます。他のプロセスが並行して表にアクセスしなくなるまで、指定されたイ
ンデックスは作成または削除されません。そのインデックスに関連付けられたシステム
第 10 章 マルチユーザ環境のためのプログラミング
285
カタログ データに書き込むために、ロックは短時間保留されます。これにより、進行中
のセッションや新規セッションによる表の読込みが可能になるため、システムの可用性
が向上します。次の文で、CREATE INDEX 文でキーワード ONLINE を使用して自動
表ロックを回避する方法を示します。
CREATE INDEX idx_1 ON customer (lname) ONLINE;
LOCK MODE 節による表ロックの設定 (XPS): Extended Parallel Server は、
LOCK TABLE 文を使用するか、または CREATE TABLE 文に含まれる LOCK MODE
節の TABLE ロック モードを使用した、表のロックを可能にします。トランザクショ
ンの排他レベルがトランザクションのロック獲得を必要とする場合、ロック モードが
TABLE に設定されている表をアクセスするすべてのトランザクションは、その表のた
めに表ロックを獲得します。次の文で、表を作成する場合の TABLE ロック モードの
使用方法を示します。
CREATE TABLE tab1
(
col1 ...
) LOCK MODE TABLE
ALTER TABLE 文を使用して、表を 1 つのロック モードから別のロック モード
(TABLE、PAGE、または ROW) に切り替えることができます。
CREATE TABLE または ALTER TABLE 文の LOCK MODE 節を指定しても、LOCK
TABLE 文を使用してロック表を獲得しても、効果は同じです。
TABLE ロック モードは、ページ レベル ロックまたは行レベル ロックを獲得する (ま
たは排他レベルに準じて獲得しようとする) 代わりに、トランザクションが表ロックを
獲得するため、問合せが効果的に増加するデータ ウェアハウス環境で特に有用です。表
レベル ロックは、ロックの要求件数をかなり減少できます。表ロックの不利な点として
は、更新の同時実行性を急激に減少することですが、このことはデータ ウェアハウス環
境では一般に問題ではありません。
行とキーのロック
表の 1 行をロックできます。プログラムは 1 行あるいは複数の行をロックすることが
でき、他のプログラムは、その表のロックされていない行を継続して処理することがで
きます。
行とキーのロックはデフォルトの動作ではありません。表を作成するときに、行レベル
ロックを指定する必要があります。次の例では、行レベル ロックの表を作成します。
CREATE TABLE tab1
(
col1...
) LOCK MODE ROW;
286
IBM Informix SQL ガイド: チュートリアル
表を作成するときに LOCK MODE 節を指定する場合は、ALTER TABLE 文を使用し
て後でロック モードを変更できます。次の文により、予約表上のロック モードがペー
ジ レベル ロックに変更されます。
ALTER TABLE tab1 LOCK MODE PAGE
データベース サーバが、存在しない行をロックしなければならない場合もあります。こ
うした場合、データベース サーバはインデックス キーの値にロックを設定します。キ
ーに対するロックは、行ロックとまったく同じ働きをします。行単位でロックされる表
では、キー ロックは仮想的な行に対するロックとして実現されます。ページ単位でロッ
クされる表では、キー ロックはキーを含むインデックス ページか、存在するならば含
むであろうキーを含むインデックス ページに設定されます。
キーを挿入、更新、または削除すると (行を挿入、更新、または削除すると自動的に行
われます)、データベース サーバはインデックスのキーにロックを設定します。
行とキーのロックは、比較的少数の行を更新する場合は、同時実行性が増すため、通常
は全体的に最高のパフォーマンスを発揮します。ただし、データベース サーバがロック
を取得するためのオーバーヘッドがかかります。
ページ ロック
データベース サーバでは、データはディスク ページ と呼ばれる単位で格納されます。
各ディスク ページには 1 つ以上の行が含まれます。場合によっては、ディスク ページ
の個々の行をロックするよりも、そのディスク ページをロックする方がパフォーマンス
が向上します。例えば、多数の行を変更する必要がある操作では、行レベル ロック (行
ごとに 1 つのロック) は費用効果がないため、ページ レベル ロックを選択します。
表を作成するときに LOCK MODE 節を指定しない場合は、データベース サーバのデ
フォルトの動作はページ レベル ロックになります。ページ ロックでは、データベース
サーバは行を含むページ全体をロックします。同じページに格納されるいくつかの行を
更新する場合は、データベース サーバは 1 ページに 1 ロックのみを使用します。
すべての CREATE TABLE 文の行ロックまたはページ ロック モードの設定
(IDS): Dynamic Server により、ロック モードを、単一ユーザ (各セッション) または
マルチユーザ (各サーバ) 向けに新規に作成されたすべての表の、ページ レベル ロッ
クまたは行レベル ロックに設定できます。 CREATE TABLE 文を使用して新規表を作
成する際に、ロック モードの指定が不要になります。
セッション内で作成された新規表をすべて特定のロック モードで作成する場合、
IFX_DEF_TABLE_LOCKMODE 環境変数を設定する必要があります。例えば、セッショ
ン内で作成された新規表をすべて行ロック モードで作成する場合、
IFX_DEF_TABLE_LOCKMODE を ROW に指定します。この動作を上書きするには、
CREATE TABLE または ALTER TABLE 文を使用し、LOCK MODE 節を再定義して
ください。
第 10 章 マルチユーザ環境のためのプログラミング
287
シングルユーザ ロック モード: セッションで作成したすべての新規表が同じロッ
ク モードを必要とする場合、シングルユーザ ロック モードを設定します。
IFX_DEF_TABLE_LOCKMODE 環境変数を使用して、シングルユーザ ロック モードを
指定してください。例えば、セッション内で作成された新規の表をすべて行レベル ロッ
ク で作成する場合、IFX_DEF_TABLE_LOCKMODE を ROW に指定します。この動作
を上書きするには、CREATE TABLE または ALTER TABLE 文を使用し、LOCK
MODE 節を再定義してください。環境変数の設定の詳細については、「IBM Informix:
SQL ガイド: 参照」を参照してください。
マルチユーザ ロック モード: データベース管理者は、複数ロック モードを使用し
て、ロック モードを同じサーバ上のすべてのユーザに指定することによる高い並行性を
実現できます。これにより、サーバ上で任意のユーザが作成するすべての表には、同じ
ロック モードが指定されます。マルチユーザ ロック モードを有効化するには、データ
ベース サーバの開始前に IFX_DEF_TABLE_LOCKMODE 環境変数を設定するか、また
は DEF_TABLES_LOCKMODE 構成パラメータを設定します。
優先順位の規則: CREATE TABLE または ALTER TABLE のロック モードには、
優先度の高い順にリストされた、以下の優先順位の規則があります。
1. LOCK MODE 節を使用する CREATE TABLE または ALTER TABLE SQL 文
2. シングルユーザ環境変数の設定
3. サーバ環境へのマルチユーザ環境変数の設定
4. ONCONFIG ファイル内の構成パラメータ
5. デフォルト動作 (ページ レベル ロック)
コアース インデックス ロック
インデックスの通常のロック モードをコアース ロック モードに変更する場合、インデ
ックス上に、通常のロックである項目レベル ロックまたはページ レベル ロックの代わ
りに、インデックス レベル ロックを獲得します。このモードは、インデックス上のロ
ック呼出しの回数を削減します。
インデックスが変更されない場合、つまりインデックス上で読込み専用の操作が行われ
る場合は、コアース ロック モードを使用します。
データベース サーバが必要に応じてインデックスに項目レベル ロックまたはページ レ
ベル ロックを設定するようにする場合は、通常のロック モードを使用します。インデ
ックスが頻繁に更新される場合は、このモードを使用します。
データベース サーバがコマンドを実行してロック モードをコアースに変更する場合、
コマンドが継続している間は、表に排他ロックが設定されます。データベース サーバを
コアース ロック モードに変更する前に、その時点で微小細分度のロックを使用してい
るあらゆるトランザクションを完了しておく必要があります。
288
IBM Informix SQL ガイド: チュートリアル
スマート ラージ オブジェクトのロック (IDS)
CLOB 型または BLOB 型列上のロックは、行上のロックと区別されます。スマート ラ
ージ オブジェクトは、アクセスされたときのみロックされます。CLOB 型または
BLOB 型列を含む表をロックする場合、スマート ラージ オブジェクトはすべてロック
されません。書込みのためにアクセスされると、スマート ラージ オブジェクトは更新
モードでロックされ、実際に書込みが行われるときに排他ロックになります。読込みの
ためにアクセスされると、スマート ラージ オブジェクトは共有モードでロックされま
す。データベース サーバはトランザクションの排他モードを認識するため、繰返し可能
読込みの排他レベルが設定されている場合は、トランザクションが終わるまでスマート
ラージ オブジェクトの読込みロックを解除しません。
データベース サーバが行を抽出し、行が指し示すスマート ラージ オブジェクトを更新
すると、更新中はスマート ラージ オブジェクトにだけ排他ロックが設定されます。
バイト範囲ロック: スマート ラージ オブジェクトに対して、ある範囲のバイトをロ
ックできます。バイト範囲ロックを使用すると、トランザクションはロックするバイト
を選択できるので、同じスマート ラージ オブジェクトの異なるバイト範囲に書込みお
よび読込みで同時にアクセスできます。
バイト範囲ロックの使用方法については、「IBM Informix: Dynamic Server パフォーマ
ンス ガイド」を参照してください。
バイト範囲ロックは、デッドロック検出をサポートします。デッドロック検出の詳細に
ついては、300 ページの『デッドロックの処理』を参照してください。
ロックの継続期間
データベースに対するロックの継続期間はプログラムが管理します。データベース ロッ
クは、そのデータベースがクローズされると解除されます。
表に対するロックの継続期間は、データベースがトランザクションの使用状況に応じて
変化します。トランザクションを使用していない場合 (すなわちトランザクション ログ
がなく COMMIT WORK 文が使用されていない場合) は、表ロックは UNLOCK
TABLE 文によって解除されるまで続きます。
表、行、インデックスに対するロックの継続期間は、使用している SQL 文の種類と、
トランザクションの使用状況に応じて変化します。
トランザクションを使用する場合は、トランザクションの終わりに、すべての表、行、
ページ、およびインデックス ロックが解除されます。トランザクションが終了すると
き、すべてのロックが解除されます。
第 10 章 マルチユーザ環境のためのプログラミング
289
データ修正中のロック
UPDATE カーソルを使用して行を取り出す場合、データベース サーバは取り出された
行に対して増進可能なロックを設定します。この設定により、他のプログラムはその行
を変更できなくなります。増進可能なロックは、排他ロックとは異なり、ロック中も他
のプログラムはその行を引き続き読み込むことができます。この結果、その行を取り出
したプログラムが UPDATE 文か DELETE 文を実行するまでに少し時間がかかるとき
でも、他のプログラムは待機する必要がなくなったり、次の行を取り出したりすること
ができるため、同時実行性が高まり、パフォーマンスが向上します。行の更新が必要に
なると、データベース サーバはその行に対し排他ロックを設定します。その行に増進可
能なロックがすでに設定されている場合は、データベース サーバは増進可能なロックを
排他ロックに変更します。
行に対する排他ロックの継続期間は、トランザクションの使用状況に応じて変化しま
す。トランザクションが使用されていない場合は、変更された行がディスクに書き込ま
れると排他ロックはすぐに解除されます。トランザクションが使用されている場合は、
トランザクションが終了するまで排他ロックが続きます。したがって、ロールバックさ
れる可能性のある行を他のプログラムが使用することはありません。
トランザクションが使用されている場合、行が削除されるときは、インデックス キーに
対するロックが常に使用されます。これは、次のようなエラーの発生を防止するためで
す。
v プログラム A が行を削除する。
v プログラム B が、その行と同じキーを持つ行を挿入する。
v プログラム A がトランザクションをロールバックして、削除した行を復元する。
この場合、プログラム B によって挿入された行を処理しようとするため、エラーが
発生します。
インデックスをロックすれば、プログラム A がそのトランザクションを確定するまで
は、プログラム B が行を挿入することはできません。
データベース サーバが行を読み込む間に設定されたロックは、現在の排他レベルに従っ
て制御されます。これについては、次の節で説明します。
SELECT 文でのロック
データベース サーバが設定するロックのタイプと継続期間は、アプリケーションで設定
された排他レベル、および SELECT 文が UPDATE カーソルの範囲内にあるかどうか
により異なります。このセクションでは、異なる排他レベルおよび UPDATE カーソル
について説明します。
290
IBM Informix SQL ガイド: チュートリアル
排他レベルの設定
排他レベル とは、あるプロセスが他のプロセスの並列動作から分離する程度を意味しま
す。データベース サーバでは、プログラムがデータを読み込むときどのようにロックを
使用するか、異なる設定のルールを反映する排他レベルを選択できます。
排他レベルを設定するには、 SET ISOLATION または SET TRANSACTION のいずれ
かを使用してください。さらに、SET TRANSACTION により、アクセス モードの設定
が可能です。アクセス モードの詳細については、299 ページの『アクセス モードによ
るデータ変更の制御』を参照してください。
SET TRANSACTION 文と SET ISOLATION 文の比較
SET TRANSACTION 文は、ANSI SQL-92 に準拠します。この文は、Informix SET
ISOLATION 文と類似しています。ただし、SET ISOLATION 文は ANSI に準拠してお
らず、アクセス モードを提供しません。
以下の表に、SET TRANSACTION および SET ISOLATION 文を使用して設定した、排
他レベル間の関係を示します。
SET TRANSACTION
SET ISOLATION
非確定読込み
単純読込み
確定読込み
確定読込み
サポートなし
カーソル安定性
(ANSI) 繰返し可能読込み
直列化可能
(Informix) 繰返し可能読込み
(Informix) 繰返し可能読込み
SET TRANSACTION 文と SET ISOLATION 文との主な違いは、トランザクション内の
排他レベルの動作です。 SET TRANSACTION 文は、トランザクションに対し 1 回の
み発行できます。トランザクション中にオープンされたカーソルには、必ずその排他レ
ベル (アクセス モードを定義している場合にはアクセス モード) に設定されます。SET
ISOLATION 文ではトランザクション開始後、トランザクション中に排他レベルを何回
も変更することができます。以下の例は、SET ISOLATION の使用と SET
TRANSACTION の使用との違いを示しています。
SET ISOLATION:
EXEC SQL BEGIN WORK;
EXEC SQL SET ISOLATION TO DIRTY READ;
EXEC SQL SELECT ... ;
EXEC SQL SET ISOLATION TO REPEATABLE READ;
EXEC SQL INSERT ... ;
EXEC SQL COMMIT WORK;
-- Executes without error
SET TRANSACTION:
第 10 章 マルチユーザ環境のためのプログラミング
291
EXEC SQL BEGIN WORK;
EXEC SQL SET TRANSACTION ISOLATION LEVEL TO SERIALIZABLE;
EXEC SQL SELECT ... ;
EXEC SQL SET TRANSACTION ISOLATION LEVEL TO READ COMMITTED;
Error -876: Cannot issue SET TRANSACTION once a transaction has started.
排他レベルの非確定読込み (ANSI) と単純読込み (Informix)
最も簡潔な排他レベルである非確定読込み (ANSI) と単純読込みは、実質的に排他性が
ありません。行を取り出すとき、プログラムはロックをまったく設定せず、他のプログ
ラムによるロックも認識しません。データベースの行をコピーするのみで、他のプログ
ラムがどのような操作をしているかについては考慮しません。
プログラムは常に、完全な行を受け取ります。排他レベルの設定が非確定読込み (ANSI)
または単純読込み (Informix) であっても、一部の列のみが更新されている行をプログラ
ムが読み込むことはありません。ただし、あるプログラムが行を更新するトランザクシ
ョンを終了する前に、排他レベルとして非確定読込み (ANSI) または単純読込み
(Informix) を設定してある別のプログラムが、更新後の行を読み込む可能性はありま
す。この場合、更新しているプログラムが後でそのトランザクションをロールバックす
ると、読込みプログラムは実際には存在しなかったデータを処理することになります
(282 ページの同時実行性に関する問題のリストの 4 に該当します)。
非確定読込み (ANSI) または 単純読込み (Informix) は、最も効率的な排他レベルで
す。プログラムが読込みのために待機することはなく、他のプログラムを待機させるこ
ともありません。この排他レベルは、次のような場合によく使用されます。
v どの表も静的な場合。すなわち、並列的に実行されるプログラムはデータを読み込む
だけで、データを変更することは絶対にない場合
v 表に対し排他ロックが設定されている場合
v 表を使用しているプログラムが 1 つのみであることが確実な場合
排他レベルの確定読込み (ANSI) および確定読込み (Informix)
プログラムが排他レベルに確定読込み (ANSI) または確定読込み (Informix) を要求した
場合、データベース サーバでは、確定がまだ済んでいない行は絶対に戻されないように
なります。これにより、確定が済んでいないデータを読み込んだ後で、そのデータがロ
ールバックされる問題は回避されます。
確定読込み (ANSI) または確定読込み (Informix) は、簡潔に実装されます。行を取り出
す前に、データベース サーバは、更新中のプロセスがその行にロックを設定したかどう
かをテストします。ロックが設定されていなければ、データベース サーバはその行を戻
します。更新は済んだがまだ確定されていない行にはロックが設定されているため、こ
のテストを行うことにより、非確定のデータをプログラムが読み取ることはありませ
ん。
確定読込み (ANSI) または確定読込み (Informix) は、取り出された行に実際にロックを
設定するわけではないので、この排他レベルは、非確定読込み (ANSI) または単純読込
292
IBM Informix SQL ガイド: チュートリアル
み (Informix) とほぼ同様に効率的です。この排他レベルは、各行のデータが、他の行
(同じ表、または他の表の) を参照しない、独立した単位として処理される場合に適して
います。
排他レベルのカーソル安定性 (Informix)
次のレベルであるカーソル安定性は、Informix SQL 文である SET ISOLATION を使用
する場合に限り、利用できます。
Dynamic Server
排他レベルにカーソル安定性を設定した場合、Dynamic Server は取り出された最新の行
のみにロックを設定します。通常のカーソルについては共有ロック、UPDATE カーソル
については増進可能なロックを設定します。一度にロックされるのは、1 行のみです。
つまり、1 行取り出されるたびに、前の行に設定されていたロックは解除されます。た
だし、前の行が更新された行である場合は、この行のロックはトランザクションが終了
するまで解除されません。
Dynamic Server の終り
Extended Parallel Server
カーソル安定性が有効になっている場合、Extended Parallel Server は 2 行以上にロック
を設定します。通常のカーソルについては共有ロック、UPDATE カーソルについては増
進可能なロックを設定します。構成パラメータ ISOLATION_LOCKS を使用して、所定
の時刻に所定の走査をロックする最大行数を指定します。データベース サーバには、現
在ロックされている行セットにユーザの現在行が含まれます。次の行がカーソルから読
み込まれるため、前の行が解除される場合も解除されない場合もあります。どの行がロ
ックされ、これらの行がいつ解除されるかは制御できません。データベース サーバは、
最大 n 行が所定のカーソルについて所定の時にロックされること、および現在の行が現
在ロックされている行セットにあることのみを保証します (デフォルト値は 1 行で
す)。ISOLATION_LOCKS パラメータの詳細については、「IBM Informix: Dynamic
Server パフォーマンス ガイド」および「IBM Informix: Dynamic Server 管理者ガイド」
を参照してください。
Extended Parallel Server の終り
カーソル安定性では、1 回にロックされる行の数は、Dynamic Server の場合は 1 行、
Extended Parallel Server の場合は指定された数のみであるため、表やデータベースに対
するロックの場合よりも同時実行性が向上します。
カーソル安定性は、プログラムが行を調べている最中に、その行が変化しないことを保
証します。このことが重要になるのは、その行から読み込んだデータを基に、プログラ
第 10 章 マルチユーザ環境のためのプログラミング
293
ムが他の表を更新する場合です。排他レベルにカーソル安定性が設定されていれば、更
新は必ず現在の情報を基に行われます。これにより、失効したデータ の使用が回避され
ます。
次に排他レベルのカーソル安定性の効果的な使用方法を示します。プログラム A は、
デモンストレーション データベースの表 stock に、ヒーロー スポーツ社 (HRO) の新
しい取扱品目を 1 つ挿入しようとしています。それと同時に、プログラム B は、ヒー
ロー スポーツ社に関する情報と、このメーカーに関係するすべての取扱品目を削除しよ
うとしています。この場合、次のような一連のイベントが発生する可能性があります。
1. 排他レベルにカーソル安定性を使用するプログラム A が、メーカー コードを検出
するために表 manufact から HRO の行を取り出します。これにより、この行には
共有ロックが設定されます。
2. プログラム B は、行に対し DELETE 文を発行します。この行にはロックが設定さ
れているため、データベース サーバはプログラム B を待機させます。
3. プログラム A が、表 manufact から取り出したメーカー コードを使用して、表
stock に新しい行を挿入します。
4. プログラム A が、表 manufact に対するそのカーソルをクローズ、あるいは表
manufact の別の行を読み、そのロックを解除します。
5. 待機状態でなくなったプログラム B が、表 manufact からヒーロー スポーツ社の行
を削除し、さらにメーカー コードが HRO の行を表 stock から削除します。プログ
ラム A が表 stock にいま挿入した行も削除します。
プログラム A が使用する排他レベルがカーソル安定性よりも低い場合には、次のよう
な一連のイベントが発生する可能性があります。
1. プログラム A が、メーカー コードを検出するために表 manufact から HRO の行
を読み込みます。ロックは設定されません。
2. プログラム B は、行に対し DELETE 文を発行します。実行は成功します。
3. プログラム B が、メーカー コードが HRO のすべての行を表 stock から削除しま
す。
4. プログラム B が終了します。
5. 読み込んだ HRO の行が無効となったことを認識しないプログラム A が、メーカー
コード HRO を使用し表 stock に新しい行を挿入します。
6. プログラム A が終了します。
プログラム A が終了した時点では、メーカー コードが表 manufact にない行が表
stock に 1 行存在するという結果になります。さらに、プログラム B にはバグがある
かのように見えます。つまり、プログラム B が削除すべき行を削除しなかったことに
なります。プログラム A が排他レベルとしてカーソル安定性を使用すれば、このよう
な結果にはなりません。
294
IBM Informix SQL ガイド: チュートリアル
排他レベルとしてカーソル安定性が使用されていてもエラーが発生するように、この例
の順序を並び替えることもできます。プログラム A とは逆の順番でプログラム B が表
を操作するように並び替えればいいのです。例えば、プログラム B が表 manufact を
削除する前に、表 stock の行を削除した場合、どのレベルの排他を行ってもエラーの発
生を防止できません。このようなエラーが発生する可能性がある場合は、関係するすべ
てのプログラムが同じ順番で表にアクセスするようにすることが必要です。
直列化可能 (ANSI)、繰返し可能読込み (ANSI)、および繰返し可能読込み
(Informix) 排他レベル
直列化可能 (ANSI) または繰返し可能読込み (ANSI) が必要な場合、繰返し可能読込み
(Informix) と呼ばれる単一の排他レベルが提供されます。これは、論理的に 直列化可能
(ANSI) と同等です。直列化可能 (ANSI) は繰返し可能読込み (ANSI) よりも制限される
ため、繰返し可能読込み (ANSI) が望ましい場合、(このようなコンテキストでは繰返し
可能読込み (Informix) が必要以上に制限されるにもかかわらず) 繰返し可能読込み
(Informix) を使用できます。
繰返し可能読込みの排他レベルでは、データベース サーバは、プログラムが検証し、取
り出すすべての行にロックを設定します。通常のカーソルについては共有ロック、
UPDATE カーソルについては増進可能なロックが設定されます。各行が検証される際、
ロックは個別に設定されます。カーソルがクローズされるかトランザクションが終了す
るまで、ロックは解除されません。
排他レベルに繰返し可能読込みを設定すると、スクロール カーソルを使用するプログラ
ムは、一度読み込んだ行を再び読み込むまでの間に、行が更新されたり削除されたりし
ていないことを確かめるために、選択された行を何度でも繰返し読み込むことができま
す (第 8 章で、スクロール カーソルについて説明しています)。繰返し可能読込みより
低い排他レベルでは、行がまだ存在することと、2 回目の読込みでも変化しないことは
保証されません。
排他レベルを繰返し可能読込みにすると、最大限のロック数が設定され、これらのロッ
クはそのほかのレベルと比べ最も長く保持されます。このため、このレベルでは並行性
は最も低くなります。プログラムがこの排他レベルを使用する場合は、設定されるロッ
クの数、継続期間、他のプログラムに対する影響について慎重に検討することが必要で
す。
ロックの数が多いことは、同時実行性に影響するだけでなく、困難な状況をもたらすこ
とがあります。データベース サーバは各プログラムのロック数をロック表に記録しま
す。ロック数が最大数を超えるとロック表はフルになり、データベース サーバはそれ以
上ロックを設定できなくなります。その場合、エラー コードが戻されます。Informix デ
ータベース サーバ システムの管理者は、このロック表を監視し、表の使用頻度に注意
してください。
第 10 章 マルチユーザ環境のためのプログラミング
295
ANSI 標準準拠のデータベースでは、排他レベルがデフォルトで直列化可能に設定され
ます。直列化可能排他レベルでは、SQL の ANSI 標準に準拠して動作しているか、確
認が必要です。
UPDATE カーソル
UPDATE カーソルは、行が更新される可能性があるときにアプリケーションが使用でき
る特殊なカーソルです。UPDATE カーソルを使用するには、SELECT FOR UPDATE 文
をアプリケーションにて実行します。UPDATE カーソルは増進可能ロック を使用しま
す。つまり、データベース サーバはアプリケーションが行を取り出す場合に、更新ロッ
ク (他のユーザはまだ行を表示できることを意味します) を設定します。しかし、アプ
リケーションが UPDATE カーソルおよび UPDATE...WHERE CURRENT OF 文を使用
して行を更新する場合は、ロックは排他ロックに変更されます。
UPDATE カーソルを使用する利点は、行を表示していれば更新するまでの間、他のユー
ザは UPDATE カーソルでその行を変更または表示できないことです。
ヒント: ANSI 準拠のデータベースでは、SELECT カーソルが UPDATE カーソルと同
じ動作を行うため、UPDATE カーソルは不要です。
図 356 の疑似コードは、データベース サーバがいつ、どこでカーソルにロックを設定
し解除するかを示します。
UPDATE
(WHERE CURRENT OF
)
図 356. 更新のために設定するロック
更新ロックの保存
ユーザが繰返し可能読込みより低い排他レベルを設定している場合は、データベース サ
ーバは、カーソルから次の行が取り出されるとすぐに、行に設定された更新ロックを解
除します。この機能とともに RETAIN UPDATE LOCKS 節を使用することにより、次
の排他レベルのいずれかを設定している場合は、トランザクションの終わりまで更新ロ
ックを保持できます。
v 単純読込み
v 確定読込み
v カーソル安定性
296
IBM Informix SQL ガイド: チュートリアル
この機能により、繰返し可能読込みの排他レベルのオーバーヘッドや行に対するダミー
更新などの対策を回避できます。RETAIN UPDATE LOCKS 機能がオンになり、更新ロ
ックが暗黙的に行に設定されると、 SELECT...FOR UPDATE 文の取出しの間はトラン
ザクションの終わりまで更新ロックは解除されません。RETAIN UPDATE LOCKS 機能
では更新ロックのみがトランザクションの終わりまで保持されますが、繰返し可能読込
みの排他レベルでは更新ロックと共有ロックの両方がトランザクションの終わりまで保
持されます。
次の例では、排他レベルを確定読込みに設定した場合の RETAIN UPDATE LOCKS 節
の使用方法を示します。
SET ISOLATION TO COMMITTED READ RETAIN UPDATE LOCKS
RETAIN UPDATE LOCKS 機能をオフにするには、RETAIN UPDATE LOCKS 節を使
用せずに排他レベルを設定してください。機能をオフにすると、更新ロックは直接解除
されません。しかし、これ以降では、直前の取出しの更新ロックは後続の取出しによっ
て解除されますが、それ以前の取出し操作のロックは解除されません。クローズ カーソ
ルは、現在行の更新ロックを解除します。
排他レベルを指定する場合の RETAIN UPDATE LOCKS 機能の使用方法について、詳
しくは、「IBM Informix: SQL ガイド: 構文」を参照してください。
INSERT 文、UPDATE 文、および DELETE 文により設定するロック
INSERT 文、UPDATE 文、または DELETE 文を実行する場合、データベース サーバ
は排他ロックを使用します。排他ロックは、他のユーザが単純読込みの排他レベルを使
用していない限り、行を表示できないことを意味します。また、他のユーザは、データ
ベース サーバがロックを取り消すまでは、項目を更新または削除できません。
データベース サーバが排他ロックを取り消すタイミングは、データベースに設定された
ログ機能の種類に依存します。データベースがログ機能を持つ場合は、データベース サ
ーバは、トランザクションが完了 (確定またはロールバック) するときに排他ロックを
取り消します。データベースにログ機能がない場合、データベース サーバは、INSERT
文、UPDATE 文、または DELETE 文の完了後、即時にすべての排他ロックを削除しま
す。
ロック タイプの動作の理解
Informix データベース サーバは、内部のロック表にロックを格納します。データベース
サーバは行を読み込むと、その行または関連付けられたページ、表、またはデータベー
スがロック表にリストされているかどうかをチェックします。ロック表にリストされて
いる場合は、データベース サーバはロック タイプもチェックします。ロック表には、
次のロック タイプを含めることができます。
第 10 章 マルチユーザ環境のためのプログラミング
297
ロックの名前
説明
ロックに通常設定される文
S
共有ロック
SELECT
X
排他ロック
INSERT 文、UPDATE 文、DELETE 文
U
更新ロック
UPDATE カーソル中の SELECT 文
B
バイト ロック
可変長文字 (VARCHAR) 型列を更新する任意の文
また、ロック表は意図ロック を格納できます。意図ロックは、共有意図 (IS)、排他意図
(IX)、または共有排他意図 (SIX) に分類されます。意図ロックは、データベース サーバ
(ロック マネージャ) が、細分度の低いオブジェクトにロックを設定する必要がないと
きに、細分度の高いオブジェクトに設定するロックです。例えば、ユーザが行またはペ
ージを共有ロック モードでロックすると、データベース サーバは IS (共有意図) ロッ
クを表に設定して、他のユーザが表に X ロックを保持していないかどうかをすぐにチ
ェックします。この場合、意図ロックは表にのみ設定され、行またはページには設定さ
れません。意図ロックは、行、ページ、または表のレベルのみで設定できます。
ユーザは、意図ロックを直接制御できません。ロック マネージャがすべての意図ロック
を内部で管理します。
次の表は、他のユーザ (またはデータベース サーバ) が特定のタイプのロックを保持し
ている場合に、ユーザ (またはデータベース サーバ) が設定できるロックを示します。
例えば、あるユーザが項目に排他ロックを保持している場合は、別のユーザがどのよう
な種類のロック (排他、更新、または共有) を要求してもエラーを受け取ります。ま
た、ユーザが項目に排他ロックを保持している場合は、データベース サーバはその項目
にどのような意図ロックも設定することはできません。
X ロック U ロック S ロック
を保持
を保持
を保持
IS ロック SIX ロック IX ロック
を保持
を保持
を保持
X ロックを要求 不可
不可
不可
不可
不可
不可
U ロックを要求 不可
不可
可
可
不可
不可
S ロックを要求 不可
可
可
可
不可
不可
IS ロックを要
求
可
可
可
可
可
SIX ロックを要 不可
求
不可
不可
可
不可
不可
IX ロックを要
求
不可
不可
可
不可
可
不可
不可
ロックがパフォーマンスに及ぼす影響について、詳細は「IBM Informix: Dynamic Server
パフォーマンス ガイド」を参照してください。
298
IBM Informix SQL ガイド: チュートリアル
アクセス モードによるデータ変更の制御
Informix データベース サーバでは、アクセス モードをサポートしています。アクセス
モードは SET TRANSACTION 文で設定され、トランザクション中の行の読込みと書込
みの同時実行性に影響を与えます。アクセス モードを使用して共有ファイル間のデータ
更新を制御できます。
トランザクションはデフォルトでは読込みと書込みが可能です。トランザクションを読
込み専用に指定すると、そのトランザクションでは次のタスクは実行できません。
v 行の挿入、削除、または更新
v スキーマ、表、一時表、インデックス、またはストアド ルーチンなどのデータベー
ス オブジェクトの作成、変更、削除
v アクセス権の付与と取消し
v 統計情報の更新
v 列名および行名の変更
読込み専用アクセス モードは更新を禁止します。
ルーチンが制限付きの文の実行を試行しない限り、ストアド ルーチンは読込み専用トラ
ンザクションで実行できます。
アクセス モードを指定するための SET TRANSACTION 文の使用方法については、
「IBM Informix: SQL ガイド: 構文」を参照してください。
ロック モードの設定
ロック モードにより、プログラムが操作しようとするデータがロックされている場合の
プログラムの動作が制御されます。ロックされている行をプログラムが取り出そうとし
たり、変更しようとした場合は、次の 3 つの結果のいずれかになります。
v データベース サーバは、SQLCODE または SQLSTATE に含まれるエラー コードを
即時にプログラムに戻します。
v データベース サーバは、ロックを設定されたプログラムがロックを解除するまで、
このプログラムをサスペンドします。
v データベース サーバは、しばらくの間プログラムをサスペンドし、その後ロックが
解除されない場合、このプログラムはデータベース サーバからエラーの戻りコード
を受け取ります。
SET LOCK MODE 文を使用して、3 つの結果のうちいずれかを選択します。
第 10 章 マルチユーザ環境のためのプログラミング
299
ロックの待機
ロックされている場合、データベース サーバはデフォルトの動作により、アプリケーシ
ョンにエラーを戻します。ロックが解除されるまで待機する場合 (これは多くのアプリ
ケーションで最適の選択です) は、次の SQL 文を実行します。
SET LOCK MODE TO WAIT
このロック モードが設定されたプログラムでは、同時に実行される他のプログラムの存
在を、通常は無視できます。他のプログラムがロックした行にアクセスしなければなら
ない事態になった場合は、このプログラムはロックが解除されるまで待機し、解除され
てからアクセスします。ほとんどの場合、遅延は認識できません。
また、次の例のように特定の秒数の間、待機することができます。
SET LOCK MODE TO WAIT 20
ロックの解除を待機しない
ロックの解除を待つことの欠点は、待ち時間が長くなる可能性があることです (適切に
設計されたアプリケーションのロック保持は短時間)。長時間の遅延の可能性が受け入れ
られない場合は、プログラムは次の文を実行できます。
SET LOCK MODE TO NOT WAIT
このモードが設定されると、ロックされている行にプログラムがアクセスした場合はす
ぐに、行がロックされていることを示す -107 DTP 行はロックされています。 などのエ
ラー番号がプログラムに戻され、実行中の SQL 文は終了します。プログラムは現行ト
ランザクションをロールバックして、操作を再試行する必要があります。
プログラム始動時の初期設定では、待機 しません。SQL を対話的に使用していて、ロ
ックに関連するエラーが表示された場合は、ロック モードを WAIT モードに設定して
ください。プログラムを作成している場合は、プログラムが実行する組込み SQL 文の
1 つを検討してください。
一定時間ロックの解除を待機する
次の文により、待機時間の上限を設定するようにデータベース サーバに要求することが
できます。
SET LOCK MODE TO WAIT 17
この文は、待機時間の上限を 17 秒に設定します。この時間が経過するまでにロックが
解除されない場合は、エラーが戻されます。
デッドロックの処理
デッドロック とは、2 つのプログラムが互いに他の実行を妨害しあう状態のことです。
プログラム同士は、相手のプログラムがアクセスするオブジェクトにロックを設定して
300
IBM Informix SQL ガイド: チュートリアル
います。デッドロックが検出される可能性があるのは、関係するすべてのプログラムが
そのロック モードを WAIT モードに設定している場合のみです。
Informix データベース サーバでは、デッドロックが単一のネットワーク サーバのデー
タのみに関係する場合は、すぐにデッドロックを検出できます。デッドロックの発生を
防止するために、エラー コード (-143 SAM エラー: デッドロックが検出されました。)
を 2 番目のプログラムに戻してロックを要求します。このエラーは、そのプログラムが
ロック モードを NOT WAIT モードに設定した場合に受け取るはずのエラーです。し
たがって、プログラムがロック モードを WAIT モードに設定したにもかかわらず、ロ
ックに関連するエラー番号を受け取った場合は、デッドロックの発生が事前に検出され
たことがわかります。
外部デッドロックの処理
異なるデータベース サーバ上のプログラムの間でも、デッドロックが検出されることが
あります。この場合、データベース サーバはデッドロックをすぐには検出できません
(ネットワーク上のすべてのデータベース サーバ間で膨大な量の通信を行わない場合
は、デッドロックを完全には検出できません)。その代わり、各データベース サーバ
は、異なるデータベース サーバのロックされたデータを取得するまでにプログラムが待
機できる時間の上限を設定します。その制限時間が経過した場合は、データベース サー
バはデッドロックが原因であったと想定し、ロックに関連するエラー番号を戻します。
すなわち、外部データベースが関係する場合は、どのプログラムも、そのロックの最大
待機時間が設定された状態で実行されます。DBA は、データベース サーバに対する最
大待機時間を設定または修正できます。
単純な並行性
ロックと同時実行性に関する設定を確定できない場合、次のガイドラインを使用できま
す。アプリケーションが非静的表にアクセスし、デッドロックのリスクがない場合、起
動の際 (最初の CONNECT 文または DATABASE 文の直後) に次の文をプログラムに
実行させます。
SET LOCK MODE TO WAIT
SET ISOLATION TO REPEATABLE READ
これらの文が戻す値は無視してください。他のプログラムは存在しないものとして、実
行を続けてください。これでパフォーマンスに関する問題が発生しなければ、設定を検
討し直す必要はありません。
第 10 章 マルチユーザ環境のためのプログラミング
301
HOLD カーソル
Dynamic Server
トランザクション ログ機能が使用される場合、Dynamic Server は、トランザクション
内で実行されるすべての処理がその終わりにロールバックされることを保証します。ト
ランザクションを確実に扱うために、データベース サーバには、通常次のルールが適用
されます。
v トランザクションが終了するとき、すべてのカーソルがクローズされる。
v トランザクションが終了するとき、すべてのロックが解除される。
Dynamic Server の終り
Extended Parallel Server
Extended Parallel Server はトランザクションの終了時に、ロックを解除しないことがあ
ります。表ロックを獲得する方法を示すために、データベース サーバが表の一部を格納
するすべてのコサーバのロックを獲得すると仮定します。トランザクションがまず
SHARED モード表ロックを獲得し、EXCLUSIVE モード表ロックにアップグレードしよ
うとする場合、ロックはトランザクションの終了時に解除されない場合もあります。こ
れは、トランザクションがを実行し、その後ロック モード TABLE を使用して表内の
INSERT 文を実行する場合に発生します。この場合、コサーバによってはアップグレー
ドに成功するものとしないものがあります。成功したアップグレードにはロールバック
は試行されません。これは、いくつかのコサーバについては、トランザクションが表の
EXCLUSIVE ロックで終了する場合があることを意味します。
Extended Parallel Server の終り
トランザクションを確実に処理するこれらのルールは、トランザクションをサポートす
るデータベース システムでは通常のルールです。そしてほとんどのアプリケーションで
は問題の原因になりません。しかし、カーソルとともに標準トランザクションを使用で
きない場合があります。例えば、次のコードはトランザクションがなくても正常に動作
します。しかし、トランザクションが追加されると、2 つのカーソルを並行して使用す
ることにより、カーソルのクローズで衝突が生じます。
EXEC SQL DECLARE master CURSOR FOR
EXEC SQL DECLARE detail CURSOR FOR
EXEC SQL OPEN master;
while(SQLCODE == 0)
{
EXEC SQL FETCH master INTO
if(SQLCODE == 0)
{
EXEC SQL BEGIN WORK;
EXEC SQL OPEN detail USING
302
IBM Informix SQL ガイド: チュートリアル
FOR UPDATE
EXEC SQL FETCH detail
EXEC SQL UPDATE WHERE CURRENT OF detail
EXEC SQL COMMIT WORK;
}
}
EXEC SQL CLOSE master;
この設計では、カーソルの 1 つは表の走査に使用されます。表から取り出されたレコー
ドを基にして、別の表が更新されます。問題は、前述の例の疑似コードに示したとお
り、各更新が個別のトランザクションとして扱われるとき、UPDATE 文に続く
COMMIT WORK 文が主カーソルを含むすべてのカーソルをクローズすることです。
この問題に対するもっとも簡単な解決策は、主表全体に対する走査が 1 つの大きなトラ
ンザクションになるように、COMMIT WORK 文と BEGIN WORK 文がそれぞれ最後
と最初の文になるようにすることです。主表に対する走査を 1 つの大きなトランザクシ
ョンとして扱う場合もありますが、更新すべき行が非常に多い場合は非実際的になりま
す。ロックの数が膨大になります。しかも、これらのロックはプログラムの実行が終了
するまで保持されます。
この問題の解決策として、Informix データベース サーバでは、主カーソルの宣言にキー
ワード WITH HOLD を追加できます。このキーワードを付けて宣言されたカーソルは
HOLD カーソル と呼ばれ、トランザクションが終了してもクローズされません。その
他のすべてのカーソルはクローズされ、ロックもすべて解除されますが、HOLD カーソ
ルは明示的にクローズされるまでオープンされた状態を保ちます。
HOLD カーソルを使用する場合は、その前に、ここで説明したロック機能を十分理解す
るとともに、同時実行される他のプログラムについても十分理解してください。ロック
と同時実行性に関する理解が必要になるのは、COMMIT WORK 文を実行すると、ロッ
クがすべて解除されてしまうためです。HOLD カーソルを使用して取り出された行に設
定されていたロックも、解除されてしまいます。
カーソルが、表全体を順方向に 1 回走査する目的で使用される場合は、HOLD カーソ
ルを宣言してもあまり意味はありません。しかし、キーワード WITH HOLD を、
UPDATE カーソル、スクロール カーソルを含む、あらゆるカーソルにも指定できま
す。これを実行する前に、表全体のロックを含むすべてのロックが、トランザクション
の終了時に解放されることを理解してください。
SQL 文キャッシュの使用
SQL 文のキャッシュ機能を使用すると、繰返し実行される同一の SQL 文をバッファに
格納して、異なるユーザのセッションで文を再使用できるため、セッションのたびにメ
モリを割当てる必要がありません。文をキャッシュすると、処理された文を多く含むア
プリケーションのパフォーマンスを著しくに改善できます。ただし、1 回だけ処理して
何回も実行する文をキャッシュするために、文のキャッシュを使用する場合は、パフォ
ーマンス改善はそれほど顕著ではありません。
第 10 章 マルチユーザ環境のためのプログラミング
303
データベース サーバについて文のキャッシュが可能である場合は、SQL 文を使用し
て、個別のデータベース セッションについて文のキャッシュを行なうかを切り替えま
す。次に、SQL 文を使用して、現在のデータベース セッションのキャッシュをオンに
する方法を示します。
SET STATEMENT CACHE ON
次の文で、SQL における現在のデータベース セッションのキャッシュをオフにする方
法を示します。
SET STATEMENT CACHE OFF
キャッシュが無効になっている場合に、文のキャッシュをオンまたはオフにしようとす
ると、データベース サーバはエラーを戻します。
SET STATEMENT CACHE 文の構文について、詳しくは、「IBM Informix: SQL ガイド
: 構文」を参照してください。STMT_CACHE および STMT_CACHE_SIZE 構成パラ
メータについては、「IBM Informix: Dynamic Server 管理者の参照」および
「IBM Informix: Dynamic Server パフォーマンス ガイド」を参照してください。
STMT_CACHE 環境変数については、「IBM Informix: SQL ガイド: 参照」を参照して
ください。
サマリ
複数のプログラムが並行してデータベースにアクセスしている場合 (そのうち 1 つでも
データを変更することができる場合)、すべてのプログラムは他のプログラムが、仮にデ
ータを読み込むだけであっても、データを変更できる可能性のあることを理解しなけれ
ばなりません。データベース サーバは、プログラムがあたかもデータを占有しているか
のように実行することを許す、ロックと排他レベルの機構を提供します。
SET STATEMENT CACHE 文により、繰り返し使用される同一の SQL 文をバッファに
格納できます。文のキャッシュをオンにすると、データベース サーバは同一の文を格納
するため、異なるユーザ セッションで再使用が可能であり、セッションのたびにメモリ
を割当てる必要がありません。
304
IBM Informix SQL ガイド: チュートリアル
第 11 章 SPL ルーチンの作成と使用
SPL ルーチンの概要. . . . . . . . . . . . . . . . . . . .
SPL ルーチンの機能. . . . . . . . . . . . . . . . . . .
Extended Parallel Server での SPL ルーチンの動作 . . . . . . . .
SPL ルーチンの作成. . . . . . . . . . . . . . . . . . . .
CREATE PROCEDURE 文または CREATE FUNCTION 文の使用. . . .
ルーチンの開始と終了 . . . . . . . . . . . . . . . . .
ルーチン名の指定 . . . . . . . . . . . . . . . . . .
固有名の追加 (IDS) . . . . . . . . . . . . . . . . . .
パラメータ リストの追加 . . . . . . . . . . . . . . . .
RETURN 節の追加 . . . . . . . . . . . . . . . . . .
表示ラベルの追加 (IDS) . . . . . . . . . . . . . . . .
SPL 関数がバリアントであるかどうかの指定 . . . . . . . . .
修飾子の追加 (IDS) . . . . . . . . . . . . . . . . . .
DOCUMENT 節の指定 . . . . . . . . . . . . . . . . .
リスト ファイルの指定 . . . . . . . . . . . . . . . . .
コメントの追加 . . . . . . . . . . . . . . . . . . .
完全なルーチンの例 . . . . . . . . . . . . . . . . . . .
プログラム内の SPL ルーチンの作成 . . . . . . . . . . . . .
分散操作でのルーチン . . . . . . . . . . . . . . . . . .
変数の定義と使用 . . . . . . . . . . . . . . . . . . . .
局所変数の宣言 . . . . . . . . . . . . . . . . . . . .
局所変数の範囲 . . . . . . . . . . . . . . . . . . .
組込み型変数の宣言 . . . . . . . . . . . . . . . . . .
スマート ラージ オブジェクト用の変数の宣言 (IDS) . . . . . . .
シンプル ラージ オブジェクト用の変数の宣言 . . . . . . . . .
コレクション (COLLECTION) 型変数の宣言 (IDS) . . . . . . .
行 (ROW) 型変数の宣言 (IDS) . . . . . . . . . . . . . .
不透明 (OPAQUE) 型およびディスティンクト (DISTINCT) 型変数の宣言
LIKE 節による列データ用変数の宣言 . . . . . . . . . . . .
PROCEDURE 型変数の宣言 . . . . . . . . . . . . . . .
変数とサブスクリプトの使用 . . . . . . . . . . . . . . .
変数およびキーワードのあいまいさ . . . . . . . . . . . .
広域変数の宣言 . . . . . . . . . . . . . . . . . . . .
変数への値の代入 . . . . . . . . . . . . . . . . . . .
LET 文 . . . . . . . . . . . . . . . . . . . . . .
変数に値を代入する他の方法 . . . . . . . . . . . . . . .
SPL ルーチンの式 . . . . . . . . . . . . . . . . . . . .
文ブロックの記述 . . . . . . . . . . . . . . . . . . . .
暗黙的および明示的文ブロック . . . . . . . . . . . . . . .
カーソルの使用 . . . . . . . . . . . . . . . . . . . .
© Copyright IBM Corp. 1996, 2004
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
(IDS) .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
307
308
308
309
309
309
310
311
312
314
315
316
316
318
318
319
320
321
321
323
323
324
324
325
325
325
326
328
328
329
330
330
332
333
333
335
336
336
336
337
305
FOREACH ループを使用したカーソルの定義 . . . . . . . . . . . . . . . .
IF - ELIF - ELSE 構造の使用 . . . . . . . . . . . . . . . . . . . . .
WHILE ループと FOR ループの追加 . . . . . . . . . . . . . . . . . . .
ループの終了 . . . . . . . . . . . . . . . . . . . . . . . . . . .
SPL 関数からの値の戻り . . . . . . . . . . . . . . . . . . . . . . . .
単一値の戻り . . . . . . . . . . . . . . . . . . . . . . . . . . .
複数値の戻り . . . . . . . . . . . . . . . . . . . . . . . . . . .
行 (ROW) 型データの処理 (IDS) . . . . . . . . . . . . . . . . . . . . .
ピリオド表記の優先順位 . . . . . . . . . . . . . . . . . . . . . . .
行 (ROW) 型式の更新 . . . . . . . . . . . . . . . . . . . . . . . .
コレクションの処理 (IDS) . . . . . . . . . . . . . . . . . . . . . . . .
コレクション (COLLECTION) 型の使用 . . . . . . . . . . . . . . . . . .
コレクション (COLLECTION) 型の準備 (IDS) . . . . . . . . . . . . . . . .
コレクション (COLLECTION) 型変数の宣言. . . . . . . . . . . . . . . .
要素変数の宣言 . . . . . . . . . . . . . . . . . . . . . . . . .
コレクション (COLLECTION) 型変数へのコレクション (COLLECTION) 型データの選択.
コレクション (COLLECTION) 型変数への要素の挿入. . . . . . . . . . . . . .
セット (SET) 型データまたはマルチセット (MULTISET) 型データへの挿入 . . . . .
リスト (LIST) 型データへの挿入 . . . . . . . . . . . . . . . . . . .
リスト (LIST) 型のコレクションの基数検査 . . . . . . . . . . . . . . . .
VALUES 節の構文 . . . . . . . . . . . . . . . . . . . . . . . .
コレクション (COLLECTION) 型データからの要素の選択 . . . . . . . . . . . .
コレクション (COLLECTION) 型データ問合せ . . . . . . . . . . . . . . .
コレクション (COLLECTION) 型データ問合せの SPL ルーチンへの追加 . . . . . .
コレクション (COLLECTION) 型要素の削除. . . . . . . . . . . . . . . . .
データベース内のコレクション (COLLECTION) 型データの更新 . . . . . . . . .
コレクション全体の削除 . . . . . . . . . . . . . . . . . . . . . .
コレクション (COLLECTION) 型要素の更新. . . . . . . . . . . . . . . . .
変数によるコレクション (COLLECTION) 型データの更新 . . . . . . . . . . .
コレクション全体の更新 . . . . . . . . . . . . . . . . . . . . . . .
行 (ROW) 型のコレクション (COLLECTION) 型データの更新. . . . . . . . . .
入れ子コレクション (COLLECTION) 型データの更新. . . . . . . . . . . . .
コレクション (COLLECTION) 型データへの挿入 . . . . . . . . . . . . . . .
入れ子コレクションへの挿入 . . . . . . . . . . . . . . . . . . . . .
ルーチンの実行 . . . . . . . . . . . . . . . . . . . . . . . . . . .
EXECUTE 文の使用 . . . . . . . . . . . . . . . . . . . . . . . . .
CALL 文の使用 . . . . . . . . . . . . . . . . . . . . . . . . . .
式の中のルーチンの実行 . . . . . . . . . . . . . . . . . . . . . . .
RETURN 文による外部関数の実行 . . . . . . . . . . . . . . . . . . . .
SPL ルーチンからのカーソル関数の実行 . . . . . . . . . . . . . . . . . .
動的ルーチン名の指定 . . . . . . . . . . . . . . . . . . . . . . . .
ルーチンのアクセス権 . . . . . . . . . . . . . . . . . . . . . . . . .
ルーチンを登録する権限 . . . . . . . . . . . . . . . . . . . . . . .
ルーチンを実行する権限 . . . . . . . . . . . . . . . . . . . . . . .
Execute アクセス権の付与と取消し . . . . . . . . . . . . . . . . . . .
COMMUTATOR 関数および NEGATOR 関数の Execute アクセス権 (IDS) . . . . .
306
IBM Informix SQL ガイド: チュートリアル
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
338
340
342
344
344
345
346
348
348
349
349
350
351
351
352
352
353
353
354
355
356
356
357
358
359
361
362
363
364
364
365
366
368
369
373
373
375
376
377
377
377
379
379
380
380
381
ルーチンに関連付けられたオブジェクトのアクセス権 .
ルーチンを実行するための DBA アクセス権 . . . .
SPL ルーチンのエラー検出 . . . . . . . . . . .
コンパイル時の警告の表示 . . . . . . . . . .
ルーチンのテキストの生成 . . . . . . . . . .
SPL ルーチンのデバッグ . . . . . . . . . . . .
例外処理 . . . . . . . . . . . . . . . . .
エラー トラッピングと復旧 . . . . . . . . . .
ON EXCEPTION 文の制御の有効範囲 . . . . . . .
ユーザが生成する例外 . . . . . . . . . . . .
SQL エラーのシミュレート . . . . . . . . .
入れ子コードを終了する RAISE EXCEPTION の使用.
SPL ルーチンで処理される行数のチェック . . . . . .
サマリ . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
382
383
384
384
385
386
388
388
389
390
391
391
392
393
本章について
この章では、SPL ルーチンの作成方法と使用方法を説明します。SPL ルーチンは、
IBM Informix ストアド プロシジャ言語 (SPL) で記述されたユーザ定義ルーチンです。
IBM Informix SPL は SQL を拡張したものであり、ループやコントロールなどのフロー
制御を実現します。データベースに対する Resource アクセス権を所有するすべてのユ
ーザが SPL ルーチンを作成できます。
SQL で書かれたルーチンは、可能な限り構文解析され、最適化され、次に、実行可能形
式でシステム カタログ表に格納されます。SPL ルーチンは、SQL 主体のタスクに効果
的です。SPL ルーチンは、C を始めとする外部言語で記述されたルーチンを実行でき、
逆に外部ルーチンも SPL ルーチンを実行できます。
SQL で実行できるタスクは、すべて SPL ルーチンでも実行可能です。また、SQL より
も多くの機能を備えています。SPL はデータベースに対して固有であり、SPL ルーチン
は実行時よりも作成時に構文解析および最適化されます。このため、SPL ルーチンで
は、特定のタスクのパフォーマンスを改善することができます。また、SPL ルーチン
は、クライアント アプリケーションとデータベース サーバ間のトラフィックを削減
し、プログラムの複雑さを解消します。
SPL 文の各構文については、「IBM Informix: SQL ガイド: 構文」に記載されていま
す。各文の構文には例が示されています。
SPL ルーチンの概要
SPL ルーチン には、SPLプロシジャ および SPL 関数 が含まれます。SPLプロシジャ
は、値を戻さない SPL および SQL で記述されたルーチンです。SPL 関数 は、単一
値、複合データ型を含む値、または複数値を戻す SPL および SQL で記述されたルー
チンです。通常、値を戻す SPL で記述されたルーチンは、SPL 関数になります。
第 11 章 SPL ルーチンの作成と使用
307
SPL ルーチンを作成するには、SQL および SPL 文を使用します。SPL 文は、CREATE
PROCEDURE、CREATE PROCEDURE FROM、CREATE FUNCTION、および CREATE
FUNCTION FROM 文内でのみ使用できます。これらの文はすべて、IBM Informix
ESQL/C のような SQL API で使用できます。なお、CREATE PROCEDURE および
CREATE FUNCTION 文は、DB–Access で使用できます。
SPL ルーチンの機能
SPL ルーチンを使用して、データベースのパフォーマンス向上、アプリケーション記述
の単純化、およびデータ アクセスの制限または監視などの、幅広い目標を達成できま
す。
SPL ルーチンは、実行可能形式で格納されるため、頻繁に繰り返されるタスクの実行に
使用することにより、パフォーマンスを向上できます。SQL のみのコードに代わり、
SPL ルーチンを使用することで、構文解析、妥当性検査、および問合せ最適化の反復を
バイパスできます。
SPL ルーチンを使用して、データを操作する SQL 文に値を渡すことができます。例え
ば、ルーチンを使用すると次のことが実行可能です。
v 表に挿入する値を渡す。
v SELECT、DELETE、または UPDATE 文の条件節を構成する値を渡す。
データ操作ステートメントでルーチンを使用する 2 つアクションを紹介しましたが、こ
れら以外にも様々な用途があります。実際のところ、データ操作 SQL 文の式はすべ
て、ルーチン呼出しで構成できます。
SQL 文を SPL ルーチン内で発行し、それらの SQL 文をデータベースから隠すことも
できます。すべてのユーザが SQL を習得するよりは、SQL を習得した 1 人のユーザ
が SQL の動作をカプセル化する SPL ルーチンを作成してデータベースに格納し、他
のユーザが実行できるようにする方が効率的です。
DBA アクセス権を持たないユーザが実行できる、DBA アクセス権付きの SPL ルーチ
ンを作成できます。この機能を使用することで、データベース内のデータへのアクセス
を制限し、制御することができます。あるいは、SPL ルーチンによって、特定の表また
はデータにアクセスするユーザを監視できます。SPL ルーチンを使用してデータへのア
クセスを制御する方法については、「IBM Informix: データベース設計および実装 ガイ
ド」を参照してください。
Extended Parallel Server での SPL ルーチンの動作
Extended Parallel Server は SPL プロシジャをサポートしますが、SPL 関数はサポート
しません。
Extended Parallel Server では、以下の SPL プロシジャが、Dynamic Server の場合と異
なる動作をします。
308
IBM Informix SQL ガイド: チュートリアル
v SYSPROCPLAN システム カタログ表
すべての Informix データベース サーバは、SPL プロシジャが作成されるたびに、
SYSPROCPLAN システム カタログ表を修正します。Dynamic Server では、SPL プ
ロシジャが実行中に新規問合せ実行計画を生成する場合、その SPL プロシジャの実
行中にも SYSPROCPLAN システム カタログ表を修正します。しかし Extended
Parallel Server では、SPL プロシジャの実行中に新規問合せ実行計画が生成される場
合でも、表 SYSPROCPLAN を修正することはありません。例えば、SYSPROCPLAN
システム カタログ表から計画が削除され、コサーバからプロシジャが実行された場
合、計画は SYSPROCPLAN には復元されません。ただし、コサーバから UPDATE
STATISTICS FOR PROCEDURE 文が実行された場合は、SYSPROCPLAN の計画が
更新されます。
v SPL プロシジャ呼出し
SPL プロシジャ呼出しは、現行データベースおよびデータベース サーバ内の SPL プ
ロシジャに対してのみ行うことができます。
SPL ルーチンの作成
SPL ルーチンは、開始文、文ブロック、および終了文から構成されます。文ブロックの
中で、SQL または SPL 文を使用できます。
SPL ルーチンの最大サイズは 64KB です。最大サイズには、データベースおよびルー
チン自体のあらゆる SPL 広域変数が含まれます。
CREATE PROCEDURE 文または CREATE FUNCTION 文の使用
作成しているルーチンが値を戻すかどうかを最初に決定する必要があります。ルーチン
が値を戻さない場合は、CREATE PROCEDURE 文を使用して、SPL プロシジャを作成
します。ルーチンが値を戻す場合は、CREATE FUNCTION 文を使用して SPL 関数を
作成します。
SPL ルーチンを作成する場合は、1 つの CREATE PROCEDURE 文または CREATE
FUNCTION 文を使用して、ルーチンの本体を記述し、それを登録します。
ルーチンの開始と終了
値を戻さない SPL ルーチンを作成する場合は、CREATE PROCEDURE 文で始め、キー
ワード END PROCEDURE で終了します。図 357 に、SPL プロシジャの開始と終了の
記述方法を示します。
第 11 章 SPL ルーチンの作成と使用
309
CREATE PROCEDURE new_price( per_cent REAL )
. . .
END PROCEDURE;
図 357.
命名規則の詳細については、「IBM Informix: SQL ガイド: 構文」の識別子に関する説
明を参照してください。
1 つ以上の値を戻す SPL 関数を作成するには、CREATE FUNCTION 文で始め、キー
ワード END FUNCTION で終了します。図 358 に、SPL 関数の開始と終了の記述方法
を示します。
CREATE FUNCTION discount_price( per_cent REAL)
RETURNING MONEY;
. . .
END FUNCTION;
図 358.
SPL ルーチンのテキストは、スペースとタブを含み全体で 64KB を超えることはでき
ません。SPL ルーチンでは、キーワード END PROCEDURE または END FUNCTION
が必須です。
重要: 以前の IBM Informix 製品との互換性を保つためには、CREATE PROCEDURE を
RETURNING 節とともに使用し、値を戻すユーザ定義ルーチンを作成します。こ
れにより、使用するコードがより読みやすく、管理しやすくなります。ただし、
CREATE PROCEDURE を値を戻さない SPL ルーチン (SPL プロシジャ) で使用
し、CREATE FUNCTION を 1 つ以上の値を戻す SPL ルーチン (SPL 関数) で
使用する場合に限ります。
ルーチン名の指定
SPL ルーチンの名前を、CREATE PROCEDURE または CREATE FUNCTION 文の直
後、パラメータ リストの前に指定します。図 359 に例を示します。
CREATE PROCEDURE add_price (arg INT )
図 359.
310
IBM Informix SQL ガイド: チュートリアル
Dynamic Server
Dynamic Server を使用すると、複数の SPL ルーチンを同じ名前でも異なるパラメータ
で指定できます。この機能は、ルーチン オーバロード と呼ばれます。例えば、次の
SPL ルーチンを、それぞれデータベースの中に作成できます。
CREATE PROCEDURE multiply (a INT, b FLOAT)
CREATE PROCEDURE multiply (a INT, b SMALLINT)
CREATE PROCEDURE multiply (a REAL, b REAL)
multiply() という名前のルーチンを呼び出す場合、データベース サーバがルーチンの名
前と引数を評価し、実行するルーチンを決定します。
Dynamic Server の終り
ルーチン解決 は、データベース サーバが、ルーチンの名前と引数のリストを基に、使
用できるルーチン シグニチャを検索するプロセスのことです。すべてのルーチンは、以
下の情報に基づいた固有のシグニチャ を持ちます。
v ルーチンの型 (プロシジャまたは関数)
v ルーチン名
v パラメータの数
v パラメータのデータ型
v パラメータの順序
ルーチンのシグニチャは、そのルーチンの完全なパラメータ リストを入力した場合、
CREATE、DROP、または EXECUTE 文で使用されます。例えば、図 360 の各文では、
ルーチンのシグニチャが使用されています。
CREATE FUNCTION multiply(a INT, b INT);
DROP PROCEDURE end_of_list(n SET, row_id INT);
EXECUTE FUNCTION compare_point(m point, n point);
図 360.
固有名の追加 (IDS)
Dynamic Server ではルーチン オーバロードをサポートするため、名前のみでは SPL ル
ーチンを個別に識別できない場合があります。このような場合は、固有名 を使用するこ
とで、個別に識別できます。固有名 という固有 ID は、ルーチン名に加え、CREATE
PROCEDURE または CREATE FUNCTION 文で指定します。固有名は、キーワード
第 11 章 SPL ルーチンの作成と使用
311
SPECIFIC とともに定義し、データベース内で一意になります。同じデータベース内の
2 つのルーチンは、それぞれが異なる所有者に属していたとしても、同じ固有名を持つ
ことはできません。
固有名は、最長 128 バイトです。図 361 では、calculate() 関数を作成する CREATE
FUNCTION 文で、固有名 calc を定義しています。
CREATE FUNCTION calculate(a INT, b INT, c INT)
RETURNING INT
SPECIFIC calc1;
. . .
END FUNCTION;
図 361.
所有者 bsmith が SPL 関数に calc1 という固有名を指定したため、他のユーザは SPL
ルーチンにも、外部ルーチンにも固有名 calc1 を使用することができません。固有名を
つけたルーチンは、以降 bsmith.calculate、またはキーワード SPECIFIC を必須とする
すべての文の中ではキーワード SPECIFIC とともに calc1 として使用できます。
パラメータ リストの追加
SPL ルーチンの作成時には、ルーチンがその起動時に 1 つ以上の引数を受け入れるよ
う、パラメータ リストを定義できます。パラメータ リストはオプションです。
SPL ルーチンへのパラメータには名前が必要であり、デフォルト値で定義できます。パ
ラメータで指定する、異なる Informix データベース サーバのデータ型のカテゴリを次
の表に示します。
Dynamic Server
Extended Parallel Server
組込みデータ型
組込みデータ型
不透明 (OPAQUE) 型
ディスティンクト (DISTINCT) 型
行 (ROW) 型
コレクション (COLLECTION) 型
スマート ラージ オブジェクト
(CLOB 型および BLOB 型)
すべての Informix データベース サーバについて、次のデータ型をパラメータで定義す
ることはできません。
v シリアル (SERIAL) 型
v 8 バイト シリアル (SERIAL8) 型
312
IBM Informix SQL ガイド: チュートリアル
v テキスト (TEXT) 型
v バイト (BYTE) 型
図 362 に、異なるパラメータ リストの例を示します。
CREATE PROCEDURE raise_price(per_cent INT)
CREATE FUNCTION
raise_price(per_cent INT DEFAULT 5)
CREATE PROCEDURE update_emp(n employee_t)
CREATE FUNCTION update_nums( list1 LIST (ROW a varchar(10),
b varchar(10),
c int) NOT NULL )
図 362.
パラメータを定義すると、2 つのタスクを一度に達成できます。
v ルーチンが実行されるとユーザに値の入力を要求します。
v 局所変数としてルーチン本体の中で使用できるように、変数をパラメータと同じ名前
で暗黙的に定義します。
パラメータをデフォルト値で定義すると、ユーザは対応する引数の有無にかかわらず
SPL ルーチンを実行できます。ユーザが引数を使用せずに SPL ルーチンを実行する
と、データベース サーバではデフォルト値が引数としてパラメータに割り当てられま
す。
SPL ルーチンを起動すると、引数に NULL 値を渡すことができます。SPL ルーチンは
デフォルトで NULL 値を処理します。ただし、引数がコレクション (COLLECTION)
型要素の場合は、引数に NULL 値を渡すことができません。
パラメータとしてシンプル ラージ オブジェクトを使用: シンプル ラージ オブ
ジェクト (テキスト (TEXT) 型またはバイト (BYTE) 型を含むラージ オブジェクト)
でパラメータを定義することはできませんが、図 363 に示すように、キーワード
REFERENCES を使用してシンプル ラージ オブジェクトを指すパラメータを定義でき
ます。
CREATE PROCEDURE proc1(lo_text REFERENCES TEXT)
CREATE FUNCTION proc2(lo_byte REFERENCES BYTE DEFAULT NULL)
図 363.
第 11 章 SPL ルーチンの作成と使用
313
キーワード REFERENCES は、オブジェクト自体ではなくシンプル ラージ オブジェク
トのポインタを含む記述子を SPL ルーチンが渡すことを意味します。
未定義の引数: SPL ルーチンを起動すると、定義済み引数のすべてまたは一部を指定
できることも、まったく定義できないこともあります。引数を定義しておらず、対応す
るパラメータがデフォルト値を持たない場合は、SPL ルーチン内で変数として使用され
る引数には、未定義 の状態になります。
未定義 は、値を持たない SPL 変数に使用される特殊な状態を指します。SPL ルーチン
は、その本文中に未定義 の状態の変数を使用しない限り、正常に実行できます。
未定義 の状態は、NULL 値とは異なります (NULL 値は、値が不明な場合、値が存在
しない場合、または値が適切でない場合に使用されます)。
RETURN 節の追加
CREATE FUNCTION 文を使用して SPL ルーチンを作成する場合は、1 つ以上の値を
戻す RETURN 節を指定する必要があります。
ヒント: CREATE PROCEDURE 文を使用して SPL ルーチンを作成する場合、任意で
RETURN 節を指定できます。これによりコードがより読みやすく、管理しやす
くなりますが、値を戻すルーチンを作成するには、CREATE FUNCTION 文を
使用することをお勧めします。
RETURN 節を指定するには、キーワード RETURNING または RETURNS を、ルーチ
ンが戻すデータ型のリストとともに使用します。データ型には、シリアル (SERIAL)
型、 8 バイト シリアル (SERIAL8) 型、テキスト (TEXT) 型、または バイト (BYTE)
型を除く任意の SQL データ型を使用できます。
図 364 の RETURN 節は、SPL ルーチンがINT 値および REAL 値を戻すことを指定し
ています。
NCTION find_group(id INT)
RETURNING INT, REAL;
. . .
END FUNCTION;
図 364.
RETURN 節を指定した後、ルーチンの本文中にも RETURN 文を指定し、呼出しルーチ
ンに明示的に値を戻す必要があります。RETURN 文の記述に関する詳細は、344 ページ
の『SPL 関数からの値の戻り』に記載されています。
関数でシンプル ラージ オブジェクト (テキスト (TEXT) 型またはバイト (BYTE) 型
値) を戻すように指定する場合は、図 365 に示すように、REFERENCES 節を使用しま
314
IBM Informix SQL ガイド: チュートリアル
す。これが必要なのは、SPL ルーチンがオブジェクトにポインタを戻し、オブジェクト
自体を戻さないためです。
CREATE FUNCTION find_obj(id INT)
RETURNING REFERENCES BYTE;
図 365.
表示ラベルの追加 (IDS)
CREATE FUNCTION を使用して、戻り値の表示ラベルの名前を指定するルーチンを作
成できます。表示ラベルに名前を指定しないと、そのラベルは式として表示します。
値を戻すルーチンには CREATE FUNCTION の使用が推奨されますが、CREATE
PROCEDURE を使用して値を戻し、戻り値の表示ラベルを指定することもできます。
1 つの戻り値に対して表示ラベルを指定する場合、すべての戻り値に対して表示ラベル
を指定する必要があります。加えて、各戻り値にはそれぞれ固有の表示ラベルが必要で
す。
表示ラベルを追加するには、キーワード RETURNING を使用して RETURN 節を指定
します。図 366 の RETURN 節は、ルーチンが serial_num 表示ラベルを持つ整数
(INT) 型値、name 表示ラベルを持つ文字 (CHAR) 型値、points 表示ラベルを持つ整数
(INT) 型値を戻すことを指定しています。図 366 では、CREATE FUNCTION と
CREATE PROCEDURE のいずれも使用できます。
CREATE FUNCTION p(inval INT DEFAULT 0)
RETURNING INT AS serial_num, CHAR (10) AS name, INT AS points;
RETURN (inval + 1002), "Newton", 100;
END PROCEDURE;
図 366.
図 367 に戻り値とその表示ラベルを示します。
第 11 章 SPL ルーチンの作成と使用
315
serial_num
name
points
1002
Newton
100
図 367.
ヒント: 戻り値の表示ラベルは、SELECT 文で直接指定できるため、SPL ルーチンが
SELECT 文で使用されている場合は、ラベルが式として表示されます。
SELECT 文で戻り値の表示ラベルを指定する方法の詳細については、 17 ページ
の『第 2 章 SELECT 文の作成』 を参照してください。
SPL 関数がバリアントであるかどうかの指定
SPL 関数を作成すると、関数はデフォルトでバリアントになります。同じ引数で起動し
たとき異なる結果を戻す関数、あるいはデータベースまたは変数の状態を変更する関数
はバリアントです。例えば、現在の日付または時刻を戻す関数は、バリアント関数で
す。
SPL 関数はデフォルトでバリアントになりますが、その関数の作成時に WITH NOT
VARIANT を指定した場合、その関数には SQL 文を含めることができなくなります。
非バリアント関数上に関数インデックスを作成することができます。
修飾子の追加 (IDS)
SPL 関数を作成する場合、WITH 節を使用して CREATEFUNCTION 文に修飾子を追加
できます。WITH 節では、COMMUTATOR または NEGATOR 関数を指定できます。
他の修飾子は外部ルーチン用です。
重要: COMMUTATOR または NEGATOR 修飾子は、SPL 関数でのみ使用できます。
SPL プロシジャでは、修飾子を使用できません。
COMMUTATOR 修飾子: COMMUTATOR 修飾子を使用して、作成している SPL
関数の交換子関数 である SPL 関数を指定できます。交換子関数は、作成している SPL
関数と同じ引数を適用しますが、同じ値を逆の順序で戻します。交換子関数を使用する
と、SQL オプティマイザが実行する場合の対費用効果が大きくなることがあります。
例えば、a が b よりも小さい場合に TRUE を戻す関数 lessthan(a,b) と、b が a より
も大きいか等しい場合に TRUE を戻す関数 greaterthan(b,a) は、交換子関数です。図
368 では、WITH 節を使用して交換子関数を定義しています。
316
IBM Informix SQL ガイド: チュートリアル
CREATE FUNCTION lessthan( a dtype1, b dtype2 )
RETURNING BOOLEAN
WITH ( COMMUTATOR = greaterthan );
. . .
END FUNCTION;
図 368.
オプティマイザは、lessthan(a,b) を実行するよりも費用が安い場合に、greaterthan(b,a)
を使用します。交換子関数を指定するには、交換子関数と、記述する SPL 関数の両方
を所有する必要があります。また、SPL 関数のユーザに両方の関数の Execute アクセス
権を与える必要があります。
アクセス権の付与に関する詳細は、「IBM Informix: SQL ガイド: 構文」のGRANT に
関する説明を参照してください。
NEGATOR 修飾子: NEGATOR 修飾子は、ブール関数に使用できます。2 つのブー
ル関数が、同じ引数を同じ順序で取り、補数のブール (Boolean) 型値を戻す場合、それ
らは 否定素子関数 になります。
例えば、a が b と等しい場合に TRUE を戻す関数 equal(a,b) と、a が b と等しい場
合に FALSE を戻す関数 notequal(a,b) は、否定素子関数です。オプティマイザは、指
定した否定素子関数の費用が元の関数より安い場合に否定素子関数の実行を選択しま
す。
図 369 に、CREATE FUNCTION 文の WITH 節を使用して否定素子関数を指定する方
法を示します。
CREATE FUNCTION equal( a dtype1, b dtype2 )
RETURNING BOOLEAN
WITH ( NEGATOR = notequal );
. . .
END FUNCTION;
図 369.
ヒント: すべての SPL ルーチンは、引数リストで渡された NULL 値をデフォルトで処
理できます。つまり、SPL ルーチンでは HANDLESNULLS 修飾子が YES に
設定されており、それを変更できないのです。
COMMUTATOR および NEGATOR 修飾子の詳細については、「IBM Informix: SQL ガ
イド: 構文」のルーチン 修飾子に関する説明を参照してください。
第 11 章 SPL ルーチンの作成と使用
317
DOCUMENT 節の指定
DOCUMENT および WITH LISTING IN 節は、END PROCEDURE または END
FUNCTION 文の後に続きます。
DOCUMENT 節を使用すると、SPL ルーチンにコメントを追加できるため、別のルーチ
ンは必要に応じてシステム カタログ表から選択できます。図 370 の DOCUMENT 節に
は、SPL ルーチンの実行方法を示す文が含まれます。
CREATE FUNCTION raise_prices(per_cent INT)
. . .
END FUNCTION
DOCUMENT "USAGE: EXECUTE FUNCTION raise_prices (xxx)",
"xxx = percentage from 1 - 100";
図 370.
一重または二重引用符でリテラル節を囲むことを忘れないでください。リテラル節が 1
行を超える場合は、各行を引用符で囲んでください。
リスト ファイルの指定
オプション WITH LISTING IN を使用すると、ファイルに発生するコンパイル時のあら
ゆる警告を表示できます。
UNIX のみ
図 371 は、UNIX で /tmp/warn_file にあるコンパイル時の警告をログに記録する方法を
示します。
CREATE FUNCTION raise_prices(per_cent INT)
. . .
END FUNCTION
WITH LISTING IN ’/tmp/warn_file’
図 371.
UNIX のみ の終り
318
IBM Informix SQL ガイド: チュートリアル
Windows のみ
図 372 は、Windows で ¥tmp¥listfile にあるコンパイル時の警告をログに記録する方法
を示します。
CREATE FUNCTION raise_prices(per_cent INT)
. . .
END FUNCTION
WITH LISTING IN ’C:¥tmp¥listfile’
図 372.
Windows のみ の終り
常に、一重または二重引用符でファイル名またはパス名を囲むことを忘れないでくださ
い。
コメントの追加
ブランク行も含み SPL ルーチンのあらゆる行にコメントを追加できます。
コメントを追加するには、二重ハイフン (--) をコメントの前に挿入するか、またはコメ
ントを中括弧 ({ }) で囲みます。二重ハイフンは、ANSI/ISO の SQL 標準に準拠して
います。中括弧は、ANSI/ISO 標準に対する Informix 拡張です。
複数行のコメントを追加するには、次のいずれかを実行します。
v コメントの各行の前に二重ハイフンを挿入する。
v コメント全体を中括弧で囲む。
図 373 の例はすべて、有効なコメントです。
第 11 章 SPL ルーチンの作成と使用
319
SELECT * FROM customer -- Selects all columns and rows
SELECT * FROM customer
-- Selects all columns and rows
-- from the customer table
SELECT * FROM customer
{ Selects all columns and rows
from the customer table }
図 373.
警告: 中括弧 ({ }) ではコメントを区切ることができるほか、コレクション内の要素の
リストも区切ることができます。パーサがコメントまたはコレクション内の要素
リストの終わりを正確に認識できるよう、SPL ルーチン内の、コレクション
(COLLECTION) 型を処理するコメントに二重ハイフン (--) を使用します。
完全なルーチンの例
以下の CREATE FUNCTION 文は、顧客の住所を読み取るルーチンを作成します。
CREATE FUNCTION read_address
(lastname CHAR(15)) -- one argument
RETURNING CHAR(15), CHAR(15), CHAR(20), CHAR(15),CHAR(2)
CHAR(5); -- 6 items
DEFINE p_lname,p_fname, p_city CHAR(15);
--define each routine variable
DEFINE p_add CHAR(20);
DEFINE p_state CHAR(2);
DEFINE p_zip CHAR(5);
SELECT fname, address1, city, state, zipcode
INTO p_fname, p_add, p_city, p_state, p_zip
FROM customer
WHERE lname = lastname;
RETURN p_fname, lastname, p_add, p_city, p_state, p_zip;
--6 items
END FUNCTION;
DOCUMENT ’This routine takes the last name of a customer as’,
--brief description
’its only argument. It returns the full name and address’,
’of the customer.’
WITH LISTING IN ’pathname’ -- modify this pathname according
-- to the conventions that your operating system requires
-- compile-time warnings go here
; -- end of the routine read_address
320
IBM Informix SQL ガイド: チュートリアル
プログラム内の SPL ルーチンの作成
SQL API を使用して SPL ルーチンを作成する場合は、CREATE PROCEDURE または
CREATE FUNCTION 文のテキストをファイルに書き込みます。CREATE PROCEDURE
FROM または CREATE FUNCTION FROM 文を使用してファイルを参照し、ルーチン
をコンパイルします。例えば、顧客名を読み取るルーチンを作成するには、前述の例の
ような文を使用してファイルに格納します。ファイルの名前が read_add_source である
場合は、次の文が read_address ルーチンをコンパイルします。
CREATE PROCEDURE FROM ’read_add_source’;
次の例に、上述の SQL 文が ESQL/C プログラムではどのように記述されるか示しま
す。
/* This program creates whatever routine is in *
* the file ’read_add_source’.
*/
#include <stdio.h>
EXEC SQL include sqlca;
EXEC SQL include sqlda;
EXEC SQL include datetime;
/* Program to create a routine from the pwd */
main()
{
EXEC SQL database play;
EXEC SQL create procedure from ’read_add_source’;
}
分散操作でのルーチン
SPL ルーチンを作成した後で、ルーチンの本体を変更することはできません。それに
は、ルーチンを削除して再作成する必要があります。ただし、ルーチンを削除する前
に、必ずデータベース以外の場所にそのテキストのコピーをとる必要があります。
通常は DROP PROCEDURE を SPL プロシジャ名とともに使用し、DROP FUNCTION
を SPL 関数名とともに使用してください。図 374 に例を示します。
DROP PROCEDURE raise_prices;
DROP FUNCTION read_address;
図 374.
ヒント: DROP PROCEDURE を関数名とともに使用し、SPL 関数を削除することもで
きます。ただし、DROP PROCEDURE はプロシジャ名のみと使用し、DROP
FUNCTION は関数名のみと使用することをお勧めします。
第 11 章 SPL ルーチンの作成と使用
321
一方、データベースに同じ名前の他のルーチン (オーバーロード ルーチン) がある場合
は、ルーチン名だけで SPL ルーチンを削除することはできません。オーバーロードさ
れたルーチンを削除するには、シグニチャまたは固有名のいずれかを指定する必要があ
ります。図 375 に、オーバーロードされたルーチンを削除する 2 つの方法を示しま
す。
DROP FUNCTION calculate( a INT, b INT, c INT);
-- this is a signature
DROP SPECIFIC FUNCTION calc1;
-- this is a specific name
図 375.
ルーチンの種類 (関数またはプロシジャ) がわからない場合は、 DROP ROUTINE 文を
使用して削除することができます。DROP ROUTINE は、関数とプロシジャ両方と使用
することができます。また、DROP ROUTINE は、図 376 に示すように、キーワード
SPECIFIC を持ちます。
DROP ROUTINE calculate;
DROP SPECIFIC ROUTINE calc1;
図 376.
リモート データベース サーバに格納される SPL ルーチンを削除する前に、次の制限
に注意してください。引数なしのルーチン名だけで、ルーチンを識別するのに十分であ
る場合に限り、フォーム database@dbservername:owner.routinename の完全修飾ルーチ
ン名で SPL ルーチンを削除できます。非ローカル データベース サーバのデータベー
スの表にアクセスする SPL ルーチンや、別のデータベース サーバのデータベースの
UDR として起動される SPL ルーチンは、引数または戻り値として組込み非不透明
(OPAQUE) 型以外使用できません。ただし、表または UDR が同じ Dynamic Server イ
ンスタンスの別のデータベース上にある場合は、SPL (または Dynamic Server でサポー
トされる外部言語) で作成されるルーチンは、引数および戻り値として組込み不透明
(OPAQUE) 型の BLOB 型、ブール (BOOLEAN) 型、CLOB 型および、ラージ可変長文
字 (LVARCHAR) 型を使用できます。次の条件が真である場合は、UDT とディスティ
ンクト (DISTINCT) 型も使用できます。
v リモート データベースに現行データベースと同じサーバがある。
v UDT 引数が明示的に組込みデータ型にキャストされる。
v ディスティンクト (DISTINCT) 型が組込み型に基づいており、明示的に組込み型にキ
ャストされる。
v SPL ルーチンとすべてのキャストがすべての関与データベースで定義されている。
322
IBM Informix SQL ガイド: チュートリアル
変数の定義と使用
SPL ルーチンで使用するあらゆる変数は、ルーチンのパラメータ リストの中で暗黙的
に定義される変数を除き、ルーチン本体の中で定義する必要があります。
変数の値はメモリ内に保持されます。変数はデータベース オブジェクトではありませ
ん。そのため、トランザクションをロールバックしても SPL 変数の値は復元されませ
ん。
SPL ルーチンで変数を定義するには、DEFINE 文を使用します。 DEFINE は実行可能
文ではありません。DEFINE は、CREATE PROCEDURE 文の後、その他の文の前に置
きます。図 377 の例は、すべて有効な変数定義です。
DEFINE a INT;
DEFINE person person_t;
DEFINE GLOBAL gl_out INT DEFAULT 13;
図 377.
DEFINE の詳細については、「IBM Informix: SQL ガイド: 構文」の説明を参照してく
ださい。
SPL 変数は名前とデータ型を持ちます。変数名は、有効な識別子である必要がありま
す。これについては、「IBM Informix: SQL ガイド: 構文」の識別子に関する説明を参
照してください。
局所変数の宣言
変数には、ローカル またはグローバル な範囲を定義できます。ここでは局所変数を説
明します。SPL ルーチンで使用する局所変数 には、以下の特徴があります。
v SPL ルーチンのみに有効。
v ルーチンが実行されるたびに、初期値またはユーザがルーチンに渡す値にリセットさ
れる。
v デフォルト値を持つことはできない。
次のいずれのデータ型でも局所変数を定義できます。
v 組込みデータ型 (シリアル (SERIAL) 型、8 バイト シリアル (SERIAL8) 型、テキス
ト (TEXT) 型、または バイト (BYTE) 型を除く)
v SPL ルーチンを実行する前にデータベースの中で定義されたあらゆる拡張データ型
(行 (ROW) 型、不透明 (OPAQUE) 型、ディスティンクト (DISTINCT) 型、またはコ
レクション (COLLECTION) 型)
第 11 章 SPL ルーチンの作成と使用
323
局所変数の有効範囲は、局所変数が宣言された文ブロックです。同じ変数名は、文ブロ
ックの外で異なる定義の場合には使用できます。
広域変数を定義する詳細については、332 ページの『広域変数の宣言』を参照してくだ
さい。
局所変数の範囲
局所変数は、文ブロックの範囲内で変数を再定義しない限り、定義されている文ブロッ
クの範囲内、およびあらゆる入れ子文ブロックの範囲内で有効です。
図 378 の SPL プロシジャの始めに、整数 (INTEGER) 型変数 x、y、および z が定義
され初期化されています。
CREATE PROCEDURE scope()
DEFINE x,y,z INT;
LET x = 5;
LET y = 10;
LET z = x + y; --z is 15
BEGIN
DEFINE x, q INT;
DEFINE z CHAR(5);
LET x = 100;
LET q = x + y; -- q = 110
LET z = ’silly’; -- z receives a character value
END
LET y = x; -- y is now 5
LET x = z; -- z is now 15, not ’silly’
END PROCEDURE;
図 378.
BEGIN 文および END 文は、整数 (INTEGER) 型変数 x、q、および文字 (CHAR) 型変
数 z が定義されている入れ子文ブロックを示します。入れ子ブロックの範囲内で、再定
義変数 x は元の変数 x をマスクします。入れ子ブロックの終わりを示す END 文の後
で、元の値の x が再度アクセス可能になります。
組込み型変数の宣言
組込み変数 は、組込みデータ型から抽出したデータを保持します。SPL 変数は、シリ
アル (SERIAL) 型および 8 バイト シリアル (SERIAL8) 型を除くすべての組込みデー
タ型を定義できます。図 379 に例を示します。
324
IBM Informix SQL ガイド: チュートリアル
DEFINE
DEFINE
DEFINE
DEFINE
x INT;
y INT8;
name CHAR(15);
today DATETIME YEAR TO DAY;
図 379.
スマート ラージ オブジェクト用の変数の宣言 (IDS)
BLOB 型または CLOB 型オブジェクト (またはスマート ラージ オブジェクトを含む
データ型) 用の変数は、オブジェクトそのものではなく、そのオブジェクトへのポイン
タを含みます。図 380 に、BLOB 型および CLOB 型オブジェクト用の変数を定義する
方法を示します。
DEFINE a_blob BLOB;
DEFINE b_clob CLOB;
図 380.
シンプル ラージ オブジェクト用の変数の宣言
シンプル ラージ オブジェクト (テキスト (TEXT) 型またはバイト (BYTE) 型オブジェ
クト) 用の変数は、オブジェクト自体ではなく、オブジェクトを指すポインタを含みま
す。テキスト (TEXT) 型またはバイト (BYTE) 型で変数を定義する場合は、キーワード
REFERENCES をデータ型の前に使用する必要があります。図 381 に例を示します。
DEFINE t REFERENCES TEXT;
DEFINE b REFERENCES BYTE;
図 381.
コレクション (COLLECTION) 型変数の宣言 (IDS)
データベースから取り出したコレクションを保持するためには、変数がセット (SET)
型、マルチセット (MULTISET) 型、または リスト (LIST) 型である必要があります。
第 11 章 SPL ルーチンの作成と使用
325
重要: コレクション (COLLECTION) 型変数は、局所変数として定義する必要がありま
す。コレクション (COLLECTION) 型の変数を広域変数として定義することはで
きません。
セット (SET) 型、マルチセット (MULTISET) 型、またはリスト (LIST) 型の変数は、
コレクション (COLLECTION) 型変数であり、DEFINE 文で指定された型のコレクショ
ンを保持します。図 382 に、型付きコレクション (COLLECTION) 型変数を定義する方
法を示します。
DEFINE a SET ( INT NOT NULL );
DEFINE b MULTISET ( ROW (
b1 INT,
b2 CHAR(50),
) NOT NULL );
DEFINE c LIST ( SET (DECIMAL NOT NULL) NOT NULL);
図 382.
コレクション (COLLECTION) 型変数の要素は、必ず NOT NULL として定義する必要
があります。この例では、変数 a は非 NULL 整数のセット (SET) 型を保持し、変数
b は非 NULL 行 (ROW) 型のマルチセット (MULTISET) 型を保持し、変数 c は非
NULL 10 進数値の非 NULL の集合のリスト (LIST) 型を保持すると定義します。
変数定義では、データベースに格納されるデータ型に一致させるために、あらゆる組合
せまたは深さで複合データ型を入れ子にできます。
あるデータ型のコレクション (COLLECTION) 型変数を別のデータ型のコレクション
(COLLECTION) 型変数に代入することはできません。例えば、コレクション
(COLLECTION) 型変数をセット (SET) 型に定義する場合、それに対してマルチセット
(MULTISET) 型またはリスト (LIST) 型の別のコレクション (COLLECTION) 型変数を
割り当てることはできません。
行 (ROW) 型変数の宣言 (IDS)
行 (ROW) 型変数は、名前付きまたは名前なしの行 (ROW) 型のデータを保持します。
名前付き行型変数 または名前なし行型変数 を定義できます。図 383 に示す名前付き行
型を定義すると仮定します。
326
IBM Informix SQL ガイド: チュートリアル
CREATE ROW TYPE zip_t
(
z_code
CHAR(5),
z_suffix
CHAR(4)
);
CREATE ROW TYPE address_t
(
street
VARCHAR(20),
city
VARCHAR(20),
state
CHAR(2),
zip
zip_t
);
CREATE ROW TYPE employee_t
(
name
VARCHAR(30),
address
address_t
salary
INTEGER
);
CREATE TABLE employee OF TYPE employee_t;
図 383.
名前付き行型の名前とともに変数を定義した場合、変数は行 (ROW) 型のデータのみを
保持できます。図 384 では、変数 person は employee_t 型のデータのみを保持できま
す。
DEFINE person employee_t;
図 384.
名前なし行型に格納されるデータを保持する変数を定義するには、図 385 に示すよう
に、行 (ROW) 型フィールドの前にキーワード ROW を使用します。
DEFINE manager ROW (name
VARCHAR(30),
department VARCHAR(30),
salary
INTEGER );
図 385.
名前なし行型は、構造的同等性について型のチェックをするのみなので、名前なし行型
で定義した変数は、同じフィールド数で同じ型定義のあらゆる名前なし行型のデータを
第 11 章 SPL ルーチンの作成と使用
327
保持できます。そのため、変数 manager は図 386 のあらゆる行 (ROW) 型のデータを
保持できます。
ROW ( name
department
salary
VARCHAR(30),
VARCHAR(30),
INTEGER );
ROW ( french
spanish
number
VARCHAR(30),
VARCHAR(30),
INTEGER );
ROW ( title
musician
price
VARCHAR(30),
VARCHAR(30),
INTEGER );
図 386.
重要: 行 (ROW) 型変数を使用する前に、その変数を LET 文または SELECTINTO 文
で初期化する必要があります。
不透明 (OPAQUE) 型およびディスティンクト (DISTINCT) 型変数の宣言
(IDS)
不透明 (OPAQUE) 型変数 は、不透明 (OPAQUE) 型から抽出されたデータを保持しま
す。ディスティンクト (DISTINCT) 型変数 は、ディスティンクト (DISTINCT) 型から
抽出したデータを保持します。不透明 (OPAQUE) 型またはディスティンクト
(DISTINCT) 型で定義した変数は、その型のデータだけを保持できます。
point という名前の不透明 (OPAQUE) 型および centerpoint という名前のディスティン
クト (DISTINCT) 型を定義した場合は、図 387 に示すように、2 つの型のデータをそれ
ぞれ保持する SPL 変数を定義できます。
DEFINE a point;
DEFINE b centerpoint;
図 387.
変数 a は point 型のデータのみを保持でき、変数 b は centerpoint 型のデータのみを
保持できます。
LIKE 節による列データ用変数の宣言
LIKE 節を使用すると、データベース サーバにより表またはビューの列と同じデータ型
を持つように変数が定義されます。
328
IBM Informix SQL ガイド: チュートリアル
列に、行 (ROW) 型または入れ子複合データ型のコレクション (COLLECTION) 型デー
タが含まれる場合は、その列の変数は複合データ型または入れ子複合データ型に定義さ
れます。
図 388 において、変数 loc1 は、表 image の列 locations のデータ型を定義します。
DEFINE loc1 LIKE image.locations;
図 388.
PROCEDURE 型変数の宣言
SPL ルーチンでは、PROCEDURE 型の変数を定義し、それに既存の SPL ルーチン名ま
たは外部ルーチン名を割り当てることができます。PROCEDURE 型の変数を定義すると
いうことは、その変数はユーザ定義ルーチンへの呼出しであり、同じ名前の組込みルー
チンではないことを示します。
例えば、図 389 の文では、length を組込み LENGTH 関数としてではなく、SPLプロシ
ジャまたは SPL 関数として定義します。
DEFINE length PROCEDURE;
LET x = length( a,b,c );
図 389.
この定義によって組込み関数 LENGTH は文ブロックの有効範囲内で使用不可になりま
す。こうした定義は、SPL ルーチンまたは外部ルーチンを LENGTH という名前で既に
作成していた場合に使用します。
Dynamic Server
Dynamic Server によりルーチン オーバーロードがサポートされているため、複数の
SPL ルーチンまたは外部ルーチンを同じ名前で定義できます。SPL ルーチンから任意の
ルーチンを呼び出す場合は、Dynamic Server により、指定された引数とルーチン決定規
則に基づいて使用するルーチンが決定されます。ルーチン オーバロードおよびルーチン
決定の詳細については、「IBM Informix: ユーザ定義ルーチンおよびデータ タイプ 開発
者ガイド」を参照してください。
Dynamic Server の終り
第 11 章 SPL ルーチンの作成と使用
329
ヒント: SPL ルーチンを、集計関数 (SUM、MAX、MIN、AVG、COUNT) と同じ名
前、または extend という名前で作成する場合は、ルーチン名を所有者名で修
飾する必要があります。
変数とサブスクリプトの使用
サブスクリプトは、文字 (CHAR) 型、可変長文字 (VARCHAR) 型、各国語文字
(NCHAR) 型、ラージ可変長文字 (LVARCHAR) 型、バイト (BYTE) 型、またはテキス
ト (TEXT) 型の変数で使用できます。サブスクリプトは、変数の範囲内で使用する文字
の開始位置と終了位置を示します。
サブスクリプトは、常に定数である必要があります。変数は、サブスクリプトとして使
用することはできません。図 390 に、サブスクリプトを CHAR(15) 型変数と使用する
方法を示します。
DEFINE name CHAR(15);
LET name[4,7] = ’Ream’;
SELECT fname[1,3] INTO name[1,3] FROM customer
WHERE lname = ’Ream’;
図 390.
この例では、顧客の姓を、名前の位置 4 と 7 の間に置きます。顧客のファースト ネー
ムの最初の 3 文字は、名前の位置 1 から 3 に抽出されます。2 つのサブスクリプトで
区切られた変数の一部はサブ文字列 といいます。
変数およびキーワードのあいまいさ
SQL キーワードと同じ名前の変数を宣言する場合、あいまいさが発生する可能性があり
ます。ID に関する以下のルールにより、SPL 変数、SPL ルーチン名、および組込み関
数名に関するあいまいさを回避できます。
v 定義済みの変数が、最も優先される。
v DEFINE 文でキーワード PROCEDURE とともに定義されたルーチンは、SQL 関数よ
りも優先される。
v SQL 関数は、存在はするが DEFINE 文でキーワード PROCEDURE とともに識別さ
れていない SPL ルーチンよりも優先される。
一般的に、ANSI 標準の予約語を変数の名前として使用することは避けるようにしま
す。例えば、変数を count または max という集計関数の名前で定義することはできま
せん。変数名として使用すべきでない予約キーワードのリストは、「IBM Informix: SQL
ガイド: 構文」の修飾子に関する説明を参照してください。
330
IBM Informix SQL ガイド: チュートリアル
変数と列の名前: 列の名前と同じ識別子を SPL 変数について使用すると、データベ
ース サーバは識別子の各実現値は変数であると判断します。識別子を列の名前として使
用するには、ピリオド表記を使用して列の名前を表の名前で限定します。
図 391 の SELECT 文では、customer.lname が列名、lname が変数名です。
CREATE PROCEDURE table_test()
DEFINE lname CHAR(15);
LET lname = ’Miller’;
SELECT customer.lname INTO lname FROM customer
WHERE customer_num = 502;
. . .
END PROCEDURE;
図 391.
変数および SQL 関数: SPL 変数に SQL 関数と同じ識別子を使用すると、データ
ベース サーバは実現値の識別子が変数であると判断して、SQL 関数の使用を許可しま
せん。変数が定義されているコードのブロックでは、SQL 関数を使用できません。図
392 の例では、user という変数を定義する SPL プロシジャ内のブロックを示します。
この定義により、BEGIN END ブロックでは USER 関数を使用できなくなります。
CREATE PROCEDURE user_test()
DEFINE name CHAR(10);
DEFINE name2 CHAR(10);
LET name = user; -- the SQL function
BEGIN
DEFINE user CHAR(15); -- disables user function
LET user = ’Miller’;
LET name = user; -- assigns ’Miller’ to variable name
END
. . .
LET name2 = user; -- SQL function again
図 392.
SPL ルーチン名および SQL 関数: SPL ルーチン名と SQL 関数名のあいまいさ
に関する詳細は、「IBM Informix: SQL ガイド: 構文」を参照してください。
第 11 章 SPL ルーチンの作成と使用
331
広域変数の宣言
広域変数 の値はメモリに格納され、同じデータベース上の同じユーザ セッションによ
り実行される他の SPL ルーチンにとって利用可能になります。広域変数には次の特性
があります。
v デフォルト値を必要とします。
v あらゆる SPL ルーチンで使用できますが、その変数を使用する各ルーチンの中には
必ず定義する必要があります。
v セッションが終わるまで、値を SPL ルーチンから別の SPL ルーチンへ運びます。
重要: コレクション (COLLECTION) 型の変数を広域変数として定義することはできま
せん。
図 393 に、1 つの広域変数を共用する 2 つの SPL 関数を示します。
CREATE FUNCTION func1() RETURNING INT;
DEFINE GLOBAL gvar INT DEFAULT 2;
LET gvar = gvar + 1;
RETURN gvar;
END FUNCTION;
CREATE FUNCTION func2() RETURNING INT;
DEFINE GLOBAL gvar INT DEFAULT 5;
LET gvar = gvar + 1;
RETURN gvar;
END FUNCTION;
図 393.
広域変数にデフォルト値を定義する必要がありますが、変数は最初に使用するときのみ
デフォルトに設定されます。図 394 に示す順序で 2 つの関数を実行すると、gvar の値
は 4 になります。
EXECUTE FUNCTION func1();
EXECUTE FUNCTION func2();
図 394.
ただし、図 395 に示すように関数を逆の順序で実行すると、gvar の値は 7 になりま
す。
332
IBM Informix SQL ガイド: チュートリアル
EXECUTE FUNCTION func2();
EXECUTE FUNCTION func1();
図 395.
詳しくは、373 ページの『ルーチンの実行』を参照してください。
変数への値の代入
SPL ルーチン内では、LET 文を使用して、定義済みの変数に値を割り当てます。
ルーチンに渡される引数または LET 文のいずれかにより、変数に値を代入しない場合
は、変数は未定義の値を持ちます。
未定義の値は、NULL 値とは異なります。SPL ルーチン内で未定義の値とともに変数を
使用しようとすると、エラーになります。
次のいずれかの方法により、ルーチンの変数に値を代入できます。
v LET 文を使用する。
v SELECTINTO 文を使用する。
v RETURNING 節をもつプロシジャで CALL 文を使用する。
v EXECUTE PROCEDUREINTO または EXECUTE FUNCTION INTO 文を使用する。
LET 文
LET 文とともに、等号 (=)、および有効な式または関数名を持つ、1 つ以上の変数名を
使用できます。図 396 の例はすべて、有効な LET 文です。
LET
LET
LET
LET
a = 5;
b = 6; LET c = 10;
a,b = 10,c+d;
a,b = (SELECT cola,colb
FROM tab1 WHERE cola=10);
LET d = func1(x,y);
図 396.
Dynamic Server
Dynamic Server を使用すると、不透明 (OPAQUE) 型変数、行 (ROW) 型変数、または
行 (ROW) 型のフィールドに値を代入できます。また、外部関数または別の SPL 関数
第 11 章 SPL ルーチンの作成と使用
333
の値を、SPL 変数に戻すこともできます。
Dynamic Server の終り
名前付き行型の zip_t および address_t を 327 ページの図 383 に示すように定義する
と仮定します。行 (ROW) 型変数を定義するときは使用する前に必ず変数を初期化する
必要があります。図 397 に、行 (ROW) 型変数を定義および初期化する方法を示しま
す。変数を初期化するには、行 (ROW) 型の任意の値を使用できます。
DEFINE a address_t;
LET a = ROW (’A Street’, ’Nowhere’, ’AA’,
ROW(NULL, NULL))::address_t
図 397.
行 (ROW) 型変数を定義および初期化した後、図 398 に示す LET 文を記述することが
できます。
LET a.zip.z_code = 32601;
LET a.zip.z_suffix = 4555;
-- Assign values to the fields of address_t
図 398.
ヒント: variable.field または variable.field.field のようにピリオド表記を使用し、行
(ROW) 型のフィールドにアクセスします。348 ページの『行 (ROW) 型データ
の処理 (IDS)』 に例を示します。
2 次元のポイントを定義する 2 つの値を含む不透明 (OPAQUE) 型のポイントを定義
し、値のテキスト表現が ’(x,y)’ であると仮定します。また、関数 circum() があり、特
定のポイント ’(x,y)’ および半径 r の円の円周を計算するものとします。
円の中心である点を定義する不透明 (OPAQUE) 型の center、およびその円の面積を中
心点と半径を基に計算する関数 circum() を定義する場合、それぞれに対して変数定義
を記述できます。図 399 に示す c は不透明 (OPAQUE) 型の変数であり、d は外部関数
circum() が戻す値を保持します。
334
IBM Informix SQL ガイド: チュートリアル
DEFINE c point;
DEFINE r REAL;
DEFINE d REAL;
LET c = ’(29.9,1.0)’ ;
-- Assign a value to an opaque type variable
LET d = circum( c, r );
-- Assign a value returned from circum()
図 399.
LET 文の構文の詳細については、「IBM Informix: SQL ガイド: 構文」に記載されてい
ます。
変数に値を代入する他の方法
図 400 に示すように、SELECT 文を使用してデータベースから値を取り出して、変数に
直接代入することができます。
SELECT fname, lname INTO a, b FROM customer
WHERE customer_num = 101
図 400.
CALL または EXECUTE PROCEDURE 文を使用して、SPL 関数または外部関数が戻し
た値を、1 つ以上の SPL 変数に割り当てることができます。図 401 のいずれかの文を
使用して、フルネームおよびアドレスを SPL 関数 read_address から特定の SPL 変数
に戻すことができます。
EXECUTE FUNCTION read_address(’Smith’)
INTO p_fname, p_lname, p_add, p_city, p_state,
p_zip;
CALL read_address(’Smith’)
RETURNING p_fname, p_lname, p_add, p_city,
p_state, p_zip;
図 401.
第 11 章 SPL ルーチンの作成と使用
335
SPL ルーチンの式
SPL ルーチンでは、集計式を除くすべての SQL 式を使用できます。SQL 式の構文およ
び説明は、「IBM Informix: SQL ガイド: 構文」に記載されています。
次の例には、SQL 式が含まれます。
var1
var1 + var2 + 5
read_address(’Miller’)
read_address(lastname = ’Miller’)
get_duedate(acct_num) + 10 UNITS DAY
fname[1,5] || ’’|| lname ’(415)’ || get_phonenum(cust_name)
文ブロックの記述
すべての SPL ルーチンは、1 つ以上の文ブロックを持ちます。これは、CREATE 文か
ら END 文までの SQL 文と SPL 文のグループです。文ブロック内では、SPL 文およ
び許可された SQL 文はすべて使用することができます。SPL 文ブロックで使用できな
い SQL 文については、「IBM Informix: SQL ガイド: 構文」の文ブロックに関する説明
を参照してください。
暗黙的および明示的文ブロック
SPL ルーチンでは、暗黙的文ブロック は CREATE 文の終わりから END 文の始めま
でを指します。一方、明示的文ブロック は、BEGIN 文で始まり、 END 文で終わりま
す。図 402 に例を示します。
BEGIN
DEFINE distance INT;
LET distance = 2;
END
図 402.
明示的文ブロックを使用すると、文ブロックの中でのみ有効な変数または処理を定義で
きます。例えば、明示的文ブロックの有効範囲内に対して、変数の定義、再定義、ある
いは例外処理を個々に実行できます。
図 403 の SPL 関数は、暗黙的文ブロックで定義済みの変数を再定義する明示的文ブロ
ックを持ちます。
336
IBM Informix SQL ガイド: チュートリアル
CREATE FUNCTION block_demo()
RETURNING INT;
DEFINE distance INT;
LET distance = 37;
BEGIN
DEFINE distance INT;
LET distance = 2;
END
RETURN distance;
END FUNCTION;
図 403.
この例では、暗黙的文ブロックで変数 distance を定義し、値 37 を渡します。明示的文
ブロックは別の変数 distance を定義し、値 2 を渡します。ただし、RETURN 文は、最
初の distance 変数が保持する値、つまり 37 を戻します。
カーソルの使用
FOREACH ループは特別な識別子 cursor を定義します。この識別子はコレクション
(COLLECTION) 型データの中の行のグループまたは要素のグループの中の 1 項目を指
します。
FOREACH ループは、カーソルを宣言しオープンして、データベースから行を取り出
し、グループ内の各項目について動作し、次にカーソルをクローズします。
SELECT、EXECUTE PROCEDURE、または EXECUTE FUNCTION 文が複数の行を戻
す可能性がある場合は、カーソルを宣言する必要があります。カーソルを宣言した後、
SELECT、 EXECUTE PROCEDURE、または EXECUTE FUNCTION 文をそのカーソル
内に置きます。
戻されるデータにアクセスするにはカーソルを使用する必要があるため、行のグループ
を戻す SPL ルーチンをカーソル ルーチン と呼びます。値を戻さないか、1 つまたは
その他のカーソルを必要としない値を戻す SPL ルーチンを、非カーソル ルーチン と
呼びます。FOREACH ループは、カーソルを宣言してオープンし、データベースから行
またはコレクション (COLLECTION) 型データを取り出し、グループ内の各項目を操作
し、カーソルをクローズします。SELECT、EXECUTE PROCEDURE、または
EXECUTE FUNCTION 文が、複数の行、またはコレクションを戻す可能性がある場合
は、カーソルを宣言する必要があります。カーソルを宣言した後、SELECT、
EXECUTE PROCEDURE、または EXECUTE FUNCTION 文をそのカーソル内に置きま
す。
FOREACH ループでは、EXECUTEFUNCTION または SELECTINTO 文を使用して、反
復関数である外部関数を実行できます。
第 11 章 SPL ルーチンの作成と使用
337
FOREACH ループを使用したカーソルの定義
FOREACH ループはキーワード FOREACH で始まり、END FOREACH で終わります。
FOREACH と END FOREACH の間であれば、カーソルを宣言するか、 EXECUTE
PROCEDURE または EXECUTE FUNCTION を使用できます。図 404 の 2 つの例は、
FOREACH ループの構造を示します。
FOREACH cursor FOR
SELECT column FROM table INTO variable;
. . .
END FOREACH;
FOREACH
EXECUTE FUNCTION name() INTO variable;
END FOREACH;
図 404.
図 405 では、 FOREACH ループを使用し、表 employee を操作するルーチンを作成し
ます。
CREATE_PROCEDURE increase_by_pct( pct INTEGER )
DEFINE s INTEGER;
FOREACH sal_cursor FOR
SELECT salary INTO s FROM employee
WHERE salary > 35000;
LET s = s + s * ( pct/100 );
UPDATE employee SET salary = s
WHERE CURRENT OF sal_cursor;
END FOREACH;
END PROCEDURE;
図 405.
図 405 のルーチンは、 FOREACH ループ内で以下のタスクを実行します。
v カーソルの宣言。
v employee から salary の値を 1 つずつ選択する。
v 給与を割合により増加する。
v employee を新しい給与で更新する。
v 次の給与値を取り出す。
338
IBM Informix SQL ガイド: チュートリアル
SELECT 文は、表の中で 35000 より大きいすべての給与を戻すため、カーソルの範囲
内に置きます。
UPDATE 文内の WHERE CURRENT OF 節は、カーソルが現在配置されている行のみ
を更新し、現在行で UPDATE カーソル を設定します。UPDATE カーソルは行に関し
て更新ロックを設定するため、他のユーザは更新が発生するまで行を更新することはで
きません。
FOREACH ループ内の UPDATE または DELETE 文が WHERE CURRENT OF 節を使
用する場合、SPL ルーチンは自動的に UPDATE カーソルを設定します。WHERE
CURRENT OF を使用する場合は、 FOREACH 文内で明示的にカーソルを参照する必
要があります。UPDATE カーソルを使用している場合は、BEGIN WORK 文を
FOREACH 文の前に、COMMIT WORK 文を END FOREACH の後ろに追加できます。
図 406 に例を示します。
BEGIN WORK;
FOREACH sal_cursor FOR
SELECT salary INTO s FROM employee WHERE salary > 35000;
LET s = s + s * ( pct/100 );
UPDATE employee SET salary = s WHERE CURRENT OF sal_cursor
END FOREACH
COMMIT WORK;
図 406.
図 406 では、 FOREACH ループが反復されるたびに、新しいロックが必要です (行レ
ベル ロックを使用する場合)。FOREACH ループの最後の反復の後、 COMMIT WORK
文がすべてのロックを解放します。また、更新されたすべての行を単一トランザクショ
ンとしてコミットします。
ループの各反復後に更新済みの行をコミットするには、次の SPL ルーチンに示すよう
に、カーソル WITH HOLD をオープンし、BEGIN WORK および COMMIT WORK
文を FOREACH ループ内 にインクルードする必要があります。
第 11 章 SPL ルーチンの作成と使用
339
CREATE PROCEDURE serial_update();
DEFINE p_col2 INT;
DEFINE i INT;
LET i = 1;
FOREACH cur_su WITH HOLD FOR
SELECT col2 INTO p_col2 FROM customer WHERE 1=1;
BEGIN WORK;
UPDATE customer SET col2 = p_col2 WHERE CURRENT OF cur_su
COMMIT WORK;
LET i = i+1
END FOREACH
END PROCEDURE;
図 407.
SPL ルーチン serial_update( ) は、各行を個別のトランザクションとしてコミットしま
す。
IF - ELIF - ELSE 構造の使用
図 408 の SPL ルーチンでは、IF - ELIF - ELSE 構造を使用し、そのルーチンが受け入
れる 2 つの引数を比較します。
CREATE FUNCTION str_compare( str1 CHAR(20), str2 CHAR(20))
RETURNING INTEGER;
DEFINE result INTEGER;
IF str1 > str2 THEN
result = 1;
ELIF str2 > str1 THEN
result = -1;
ELSE
result = 0;
END IF
RETURN result;
END FUNCTION;
図 408.
図 409 に示す列について manager という名前の表を定義すると仮定します。
340
IBM Informix SQL ガイド: チュートリアル
CREATE TABLE manager
(
mgr_name
VARCHAR(30),
department VARCHAR(12),
dept_no
SMALLINT,
direct_reports SET( VARCHAR(30) NOT NULL ),
projects LIST( ROW ( pro_name VARCHAR(15),
pro_members SET( VARCHAR(20) NOT NULL ) )
NOT NULL),
salary
INTEGER,
);
図 409.
図 410 の SPL ルーチンでは、IF - ELIF - ELSE 構造を使用して、列 direct_reports
の セット (SET) 型の数をチェックし、その結果に基づいてさまざまな外部ルーチンを
呼び出します。
CREATE FUNCTION checklist( d SMALLINT )
RETURNING VARCHAR(30), VARCHAR(12), INTEGER;
DEFINE name VARCHAR(30);
DEFINE dept VARCHAR(12);
DEFINE num INTEGER;
SELECT mgr_name, department,
CARDINALITY(direct_reports)
FROM manager INTO name, dept, num
WHERE dept_no = d;
IF num > 20 THEN
EXECUTE FUNCTION add_mgr(dept);
ELIF num = 0 THEN
EXECUTE FUNCTION del_mgr(dept);
ELSE
RETURN name, dept, num;
END IF;
END FUNCTION;
図 410.
cardinality( ) 関数は、コレクションに含まれる要素数をカウントします。詳しくは、
115 ページの『計数関数 (IDS)』を参照してください。
SPL ルーチン内の IF - ELIF - ELSE 構造は、以下の 4 つのパーツで構成されます。
v IF THEN 条件
第 11 章 SPL ルーチンの作成と使用
341
IF 文に続く条件がTRUE の場合、このルーチンは IF ブロック内の文を実行します。
条件が FALSE である場合は、ルーチンは ELIF 条件を評価します。
IF 文内の式は、有効な条件であれはすべて使用できます。これについては、
「IBM Informix: SQL ガイド: 構文」の条件に関する説明を参照してください。IF 文
の構文および詳細については、「IBM Informix: SQL ガイド: 構文」を参照してくだ
さい。
v 1 つ以上の ELIF 条件 (オプション)
ルーチンは、IF 条件が FALSE の場合のみ、 ELIF 条件を評価します。ELIF 条件が
TRUE の場合、そのルーチンは ELIF ブロック内の文を実行します。ELIF 条件が
FALSE の場合、ルーチンは次の ELIF ブロックを評価するか、ELSE 文を実行しま
す。
v ELSE 条件 (オプション)
ルーチンは、IF 条件およびすべての ELIF 条件が FALSE の場合に ELSE ブロック
の文を実行します。
v END IF 文
END IF 文は、文ブロックを終了します。
WHILE ループと FOR ループの追加
WHILE 文と FOR 文は、両方とも SPL ルーチンで実行ループを作成します。WHILE
ループは、WHILE 条件 で始まり、その条件が TRUE である間文ブロックを実行し、
END WHILE で終了します。
図 411 に、有効な WHILE 条件を示します。ルーチンは WHILE 文で指定した条件が
TRUE である限り WHILE ループを実行します。
CREATE PROCEDURE test_rows( num INT )
DEFINE i INTEGER;
LET i = 1;
WHILE i < num
INSERT INTO table1 (numbers) VALUES (i);
LET i = i + 1;
END WHILE;
END PROCEDURE;
図 411.
342
IBM Informix SQL ガイド: チュートリアル
図 411 の SPL ルーチンは引数として整数を受け入れ、WHILE ループを実行するたび
に整数値を table1 の列 numbers に挿入します。挿入された値は 1 で始まり、num - 1
まで増加します。
図 412 に示すような無限ループを作らないよう注意してください。
CREATE PROCEDURE endless_loop()
DEFINE i INTEGER;
LET i = 1;
WHILE ( 1 = 1 )
-- don’t do this!
LET i = i + 1;
INSERT INTO table1 VALUES (i);
END WHILE;
END PROCEDURE;
図 412.
FOR ループは FOR 文から END FOR 文までを指し、FOR 文で指定する回数だけ反復
します。図 413 に、FOR ループで反復を定義する方法をいくつか示します。
FOR ループの反復ごとに反復変数 (次の例で i として宣言されています) がリセットさ
れるため、ループ内の文は新しい変数値で実行されます。
FOR i = 1 TO 10
. . .
END FOR;
FOR i = 1 TO 10 STEP 2
. . .
END FOR;
FOR i IN (2,4,8,14,22,32)
. . .
END FOR;
FOR i IN (1 TO 20 STEP 5, 20 to 1 STEP -5, 1,2,3,4,5)
. . .
END FOR:
図 413.
最初の例では、SPL プロシジャは、i が 1 から 10 のいずれかである限り FOR ループ
を実行します。2 番目の例では、i は 1、3、5、7、のようにステップしますが、10 を
第 11 章 SPL ルーチンの作成と使用
343
超えることはありません。3 番目の例では、i が定義された値セットの範囲内かチェッ
クします。4 番目の例では、SPL プロシジャは、i が 1、6、11、16、20、15、10、5、
1、2、3、4、または 5 の場合、つまり 13 回ループを実行します。
ヒント: WHILE ループと FOR ループの最も大きい違いは、FOR ループが必ず終了す
るのに対し、 WHILE ループには終了する保証がないという点です。FOR 文
は、文がルーチンのループを終了することがない限り、ループの完全な実行回
数を指定します。WHILE では、エンドレス ループになる可能性があります。
ループの終了
FOR、FOREACH、または WHILE ループでは、CONTINUE または EXIT 文を使用し
てループの実行を制御できます。
CONTINUE 文を使用すると、ルーチンはループに残された文をスキップして、FOR 文
の次の反復に移動できます。EXIT 文を使用すると、ループは終了し、ルーチンは END
FOR文に続く最初の文を継続して実行します。EXIT の後には、ルーチンが実行してい
るループのキーワードを置いてください。例えば、EXIT FOR または EXIT FOREACH
のようにします。
図 414 に、FOR ループ内の CONTINUE および EXIT の例を示します。
FOR i = 1 TO 10
IF i = 5 THEN
CONTINUE FOR;
. . .
ELIF i = 8 THEN
EXIT FOR;
END IF;
END FOR;
図 414.
ヒント: CONTINUE および EXIT を使用して、SPL ルーチンのパフォーマンスを改善
し、必要のないループを実行しないようすることができます。
SPL 関数からの値の戻り
SPL 関数は、1 つ以上の値を戻すことができます。SPL 関数が値を戻すには、次の 2
つの部分を含める必要があります。
1. CREATE PROCEDURE 文または CREATE FUNCTION 文の中に RETURNING 節を
記述し、戻す値の数とそのデータ型を指定します。
2. 明示的に値を戻す RETURN 文を関数の本体に入れます。
344
IBM Informix SQL ガイド: チュートリアル
ヒント: ルーチンは値を戻す CREATE PROCEDURE 文で定義できますが、この場合、
そのルーチンは事実上の関数になります。ルーチンが値を戻す場合は、
CREATE FUNCTION 文を使用することをお勧めします。
RETURNING 文で RETURN 節を定義した場合 SPL 関数は、指定された数とデータ型
に一致する値を戻すことも、まったく値を戻さないことも可能です。RETURN 節を指定
したのに SPL ルーチンが実際に値を戻さない場合でも、なおルーチンは関数であると
考えることができます。このような場合には、ルーチンは RETURN 節で定義した各値
に NULL 値を戻します。
SPL 関数は、変数、式、または別の関数呼出しの結果を戻すことができます。SPL 関数
が変数を戻す場合は、最初に次のいずれかの方法で変数に値を代入する必要がありま
す。
v LET 文
v デフォルト値
v SELECT 文
v 値を変数に渡すその他の関数
SPL 関数が戻す各値は、最大 32KB です。
重要: SPL 関数の戻り値は、特定のデータ型を持ちます。戻り値のデータ型として、一
般的な行または一般的なコレクション (COLLECTION) 型を指定することはでき
ません。
単一値の戻り
図 415 では、SPL 関数で単一値を戻します。
CREATE FUNCTION increase_by_pct(amt DECIMAL, pct DECIMAL)
RETURNING DECIMAL;
DEFINE result DECIMAL;
LET result = amt + amt * (pct/100);
RETURN result;
END FUNCTION;
図 415.
第 11 章 SPL ルーチンの作成と使用
345
関数 increase_by_pct は、10 進数 (DECIMAL) 型の値で増分とその割合の 2 つの引数
を受け取ります。RETURN 節では、関数が 1 つの 10 進数 (DECIMAL) 型の値を戻す
ことを指定します。RETURN 文は、result に格納された 10 進数 (DECIMAL) 型値を
戻します。
複数値の戻り
SPL 関数は、表の単一行から複数の値を戻すことができます。図 416 に示す SPL 関数
は、表の単一行から 2 つの列値を戻します。
CREATE FUNCTION birth_date( num INTEGER )
RETURNING VARCHAR(30), DATE;
DEFINE n VARCHAR(30);
DEFINE b DATE;
SELECT name, bdate INTO n, b FROM emp_tab
WHERE emp_no = num;
RETURN n, b;
END FUNCTION;
図 416.
図 416 の関数は、表 emp_tab の単一行からの 2 つの値 (name および birthdate) を呼
出しルーチンに戻します。この場合、呼出しルーチンには、戻される可変長文字
(VARCHAR) 型および日付 (DATE) 型の値を処理する準備の必要があります。
図 417 に示す SPL 関数は複数の行から複数の値を戻します。
CREATE FUNCTION birth_date_2( num INTEGER )
RETURNING VARCHAR(30), DATE;
DEFINE n VARCHAR(30);
DEFINE b DATE;
FOREACH cursor1 FOR
SELECT name, bdate INTO n, b FROM emp_tab
WHERE emp_no > num;
RETURN n, b WITH RESUME;
END FOREACH
END FUNCTION;
図 417.
346
IBM Informix SQL ガイド: チュートリアル
346 ページの図 417 の SELECT 文は、ユーザが入力した番号より大きい従業員番号の
行の集合から 2 つの値を取り出します。条件を満たす行の集合には、0 行、1 行、また
は多くの行が含まれることがあります。SELECT 文は多くの行を戻すことができるた
め、カーソルの範囲内に置くことができます。
ヒント: SPL ルーチン内の文が行を戻さない場合、それに対応する SPL 変数にはNULL
値が割り当てられます。
RETURN 文ではキーワード WITH RESUME を使用します。RETURN WITH RESUME
が実行される場合、コントロールは呼出しルーチンに戻ります。ただし、次回 FETCH
文または呼出ルーチンの次のカーソルの反復により SPL 関数が呼び出されると、SPL
関数のすべての変数は同じ値を保ち、RETURN WITH RESUME 文の直後の文で実行が
継続されます。
SPL ルーチンが複数の値を戻す場合は、呼出しルーチンは次のようにカーソルまたはル
ープを通して複数の値を扱うことができる必要があります。
v 呼出しルーチンが SPL ルーチンである場合、FOREACH ループが必要。
v 呼出しルーチンが ESQL/C プログラムである場合、DECLARE 文で宣言されたカー
ソルが必要。
v 呼出しルーチンが外部ルーチンである場合、ルーチンを記述した言語に適したカーソ
ルまたはループが必要。
注: UDR によってローカル サーバの外部データベースから戻される値は、明示的に組
込み型にキャストされる組込みデータ型または UDT であるか、組込み型に基づき
明示的に組込み型にキャストされるディスティンクト (DISTINCT) 型である必要が
あります。また、関与するデータベースで UDR とすべてのキャストを定義する必
要があります。
データベース間で実行できる SQL 操作の例を次に示します。
database db1;
create table ltab1(lcol1 integer, lcol2 boolean, lcol3 lvarchar);
insert into ltab1 values(1, ’t’, "test string 1");
database db2;
create table rtab1(r1col1 boolean, r1col2 blob, r1col3 integer)
put r1col2 in (sbsp);
create table rtab2(r2col1 lvarchar, r2col2 clob) put r2col2 in (sbsp);
create table rtab3(r3col1 integer, r3col2 boolean,
r3col3 lvarchar, r3col4 circle);
create view rvw1 as select
* from rtab3;
この例はクロス データベース挿入です。
database db1;
create view lvw1 as select * from db2:rtab2;
insert into db2:rtab1 values(’t’,
第 11 章 SPL ルーチンの作成と使用
347
filetoblob(’blobfile’, ’client’, ’db2:rtab1’, ’r1col2’), 100);
insert into db2:rtab2 values("inserted directly to rtab2",
filetoclob(’clobfile’, ’client’, ’db2:rtab2’, ’r2col2’));
insert into db2:rtab3 (r3col1, r3col2, r3col3)
select lcol1, lcol2, lcol3 from ltab1;
insert into db2:rvw1 values(200, ’f’, "inserted via rvw1");
insert into lvw1 values ("inserted via lvw1", NULL);
行 (ROW) 型データの処理 (IDS)
SPL ルーチンでは、名前付き行型および名前なし行型をパラメータ定義、引数、変数定
義、および戻り値として使用できます。SPL で行 (ROW) 型変数を宣言する方法につい
ては、326 ページの『行 (ROW) 型変数の宣言 (IDS)』を参照してください。
図 418 では、ここで使用する例として、行 (ROW) 型変数 salary_t および表 emp_info
を定義します。
CREATE ROW TYPE salary_t(base MONEY(9,2), bonus MONEY(9,2))
CREATE TABLE emp_info (emp_name VARCHAR(30), salary salary_t);
図 418.
表 emp_info は、従業員名および給与情報の列を持ちます。
ピリオド表記の優先順位
Dynamic Server では、SPL ルーチンの SQL 文でピリオド表記を使用する値
(proj.name のように) が、以下の優先順位の付いた 3 つの意味のうちいずれかに解釈
されます。
1. variable.field
2. column.field
3. table.column
つまり、式 proj.name は、まず variable.field として評価されます。そしてルーチンが
変数 proj を検出できない場合、この式は column.field として評価されます。さらにル
ーチンが列 proj を検出できない場合、この式は table.column として評価されます (こ
の名前が SPL ルーチンで宣言されている変数やフィールド、そしてデータベース内の
オブジェクト識別子として解決できない場合は、エラーが戻ります)。
348
IBM Informix SQL ガイド: チュートリアル
行 (ROW) 型式の更新
SPL ルーチン内から、行 (ROW) 型変数を使用して行 (ROW) 型式を更新できます。図
419 に示す SPL プロシジャ emp_raise は、従業員の給与が特定の割合増加した場合に
表 emp_info を更新します。
CREATE PROCEDURE emp_raise( name VARCHAR(30),
pct DECIMAL(3,2) )
DEFINE row_var salary_t;
SELECT salary INTO row_var FROM emp_info
WHERE emp_name = name;
LET row_var.base = row_var.base * pct;
UPDATE emp_info SET salary = row_var
WHERE emp_name = name;
END PROCEDURE;
図 419.
SELECT 文は、emp_info 表の salary 列の行を選択し、行 (ROW) 型変数 row_var に
代入します。
プロシジャ emp_raise は、SPL ピリオド表記を使用して変数 row_var のフィールド
base に直接アクセスします。この場合、ピリオド表記は variable.field を意味します。
emp_raise プロシジャは、row_var.base の値を (row_var.base * pct) として再計算し
ます。プロシジャは、次に表 emp_info の列 salary を、新しい row_var の値で更新し
ます。
重要: 行 (ROW) 型変数は、そのフィールドが設定または参照される前に、行として初
期化する必要があります。行 (ROW) 型は、SELECTINTO 文または LET 文で初
期化することができます。
コレクションの処理 (IDS)
コレクション は、セット (SET) 型、マルチセット (MULTISET) 型、またはリスト
(LIST) 型のような同じデータ型の要素をグループ化したものです。
表は、列の内容として、または列の中の行 (ROW) 型フィールドとして格納されるコレ
クション (COLLECTION) 型データを含むことができます。コレクション
(COLLECTION) 型データには、単純コレクション (COLLECTION) 型または入れ子コレ
クション (COLLECTION) 型が可能です。単純コレクション (COLLECTION) 型 は、組
込み型、不透明 (OPAQUE) 型、またはディスティンクト (DISTINCT) 型の セット
第 11 章 SPL ルーチンの作成と使用
349
(SET) 型、マルチセット (MULTISET) 型、またはリスト (LIST) 型です。入れ子コレク
ション (COLLECTION) 型 は、他のコレクションを含むコレクションです。
コレクション (COLLECTION) 型の使用
この章の次のセクションでは、いくつかの異なる例により、SPL プログラムでコレクシ
ョン (COLLECTION) 型データを操作する方法を説明します。
SPL プログラム内でのコレクションの処理の基本については、図 420 のように表
numbers を使用して説明します。
CREATE TABLE numbers
(
id INTEGER PRIMARY KEY,
primes
SET( INTEGER NOT NULL ),
evens
LIST( INTEGER NOT NULL ),
twin_primes LIST( SET( INTEGER NOT NULL )
NOT NULL )
図 420.
列 primes および列 evens は単純コレクション (COLLECTION) 型を保持します。列
twin_primes は入れ子コレクション (COLLECTION) 型 (SET の LIST) を保持します。
対の素数 (twin prime) とは、差が 2 で連続した素数の組であり、5 と 7、または 11
と 13 などです。列 twin_primes はこのようなペアを入力できるように設計されていま
す。
この章のいくつかの例は、図 421 に示す表 polygons を使用してコレクション
(COLLECTION) 型データの操作方法を説明します。表 polygons に含まれるコレクショ
ン (COLLECTION) 型データは 2次元のグラフィック データを表します。例えば、2 次
元ポイントの x 座標と y 座標を ’1.0, 3.0’ として表示するような 2 つの実数
(DOUBLE PRECISION) 型の値を持つ point という名前の不透明 (OPAQUE) 型を定義
すると仮定します。point データ型を使用して、多角形を定義するポイントのセットを
含む表を作成できます。
350
IBM Informix SQL ガイド: チュートリアル
CREATE OPAQUE TYPE point ( INTERNALLENGTH = 8);
CREATE TABLE polygons
(
id
INTEGER PRIMARY KEY,
definition SET( point NOT NULL )
);
図 421.
表 polygons の列 definition は、単純コレクション (COLLECTION) 型であるセット
(SET) 型の値 point を含みます。
コレクション (COLLECTION) 型の準備 (IDS)
単純コレクション (COLLECTION) 型または入れ子コレクション (COLLECTION) 型の
各要素にアクセスし、操作する前に、以下のタスクを実行してください。
v コレクション (COLLECTION) 型データを保持するようコレクション (COLLECTION)
型変数を宣言します。
v コレクション (COLLECTION) 型データの各要素を保持するよう要素変数を宣言しま
す。
v データベースからコレクション (COLLECTION) 型変数へコレクション
(COLLECTION) 型データを選択します。
これらの初期手順を実行した後には、コレクション (COLLECTION) 型データに要素を
挿入したり、既にコレクション (COLLECTION) 型データにある要素を選択または処理
することができます。
これらの各手順は、次のセクションで表 numbers を例として使用して説明します。
ヒント: すべての SPL ルーチン内のコレクションを処理できます。
コレクション (COLLECTION) 型変数の宣言
データベースからコレクションを SPL ルーチンに抽出する前に、コレクション
(COLLECTION) 型変数を宣言する必要があります。図 422 では、コレクション
(COLLECTION) 型変数を宣言して、表 numbers から列 primes を抽出します。
DEFINE p_coll SET( INTEGER NOT NULL );
図 422.
第 11 章 SPL ルーチンの作成と使用
351
DEFINE 文は、列 primes に格納されるコレクション (COLLECTION) 型データとデー
タ型が一致するコレクション (COLLECTION) 型変数 p_coll を宣言します。
要素変数の宣言
コレクション (COLLECTION) 型変数を宣言した後で、コレクション (COLLECTION)
型データの各要素を保持するために要素変数を宣言します。要素変数のデータ型は、コ
レクション (COLLECTION) 型データ要素のデータ型と一致する必要があります。
例えば、セット (SET) 型の要素を列 primes で保持するには、図 423 に示すような要
素変数宣言を使用します。
DEFINE p INTEGER;
図 423.
入れ子コレクション (COLLECTION) 型変数を保持し、列 twin_primes の要素を保持す
る変数を宣言するには、図 424 に示すような変数宣言を使用します。
DEFINE s SET( INTEGER NOT NULL );
図 424.
変数 s は、整数の セット (SET) 型を保持します。各 セット (SET) 型は、
twin_primes に格納されたリスト (LIST) 型の要素です。
コレクション (COLLECTION) 型変数へのコレクション (COLLECTION) 型デ
ータの選択
コレクション (COLLECTION) 型変数を宣言した後で、コレクション (COLLECTION)
型データをその変数に取り出すことができます。コレクション (COLLECTION) 型変数
へコレクション (COLLECTION) 型データを取り出すには、SELECTINTO 文を入力し
て、名前を付けたコレクション (COLLECTION) 型変数へコレクション (COLLECTION)
型データ列をデータベースから選択します。
例えば、表 numbers の列 primes の 1 行に格納されたコレクション (COLLECTION)
型データを選択するには、図 425 に示すように SELECT 文を SPL ルーチンに追加し
ます。
352
IBM Informix SQL ガイド: チュートリアル
SELECT primes INTO p_coll FROM numbers
WHERE id = 220;
図 425.
表 numbers の 1 行のみに格納するコレクション (COLLECTION) 型データを選択する
場合は、SELECT 文の WHERE 節で指定します。この文により、コレクション
(COLLECTION) 型データは、351 ページの図 422 で宣言したコレクション
(COLLECTION) 型変数 p_coll に置かれます。
これで、変数 p_coll は、値 SET {5,7,31,19,13} を含む列 primes からのコレクション
(COLLECTION) 型データを保持します。
コレクション (COLLECTION) 型変数への要素の挿入
コレクション (COLLECTION) 型変数にコレクション (COLLECTION) 型データを抽出
したら、コレクション (COLLECTION) 型変数に値を挿入できます。INSERT 文の構文
は、値を追加しようとするコレクション (COLLECTION) 型データの種類によって少し
異なります。
セット (SET) 型データまたはマルチセット (MULTISET) 型データへの挿入
コレクション (COLLECTION) 型変数に格納されたセット (SET) 型またはマルチセット
(MULTISET) 型データに挿入するには、INSERT 文を使用し、キーワード TABLE の後
にコレクション (COLLECTION) 型変数を置きます。図 426 に例を示します。
INSERT INTO TABLE(p_coll) VALUES(3);
図 426.
キーワード TABLE により、コレクション (COLLECTION) 型変数はコレクション
(COLLECTION) 型導出表になります。コレクション (COLLECTION) 型導出表について
は、167 ページの『SELECT 文でのコレクションの処理 (IDS)』に記載されています。
図 426 で導出するコレクション (COLLECTION) 型データは、コレクション
(COLLECTION) 型データの各要素が表の行に相当する 1 列の仮想表です。挿入する前
の p_coll は図 427 に示すような行 (要素) を含む仮想表とします。
第 11 章 SPL ルーチンの作成と使用
353
5
7
31
19
13
図 427.
挿入後の p_coll は、図 428 に示すような仮想表になります。
5
7
31
19
13
3
図 428.
コレクション (COLLECTION) 型データはセット (SET) 型なので、新しい値がコレクシ
ョン (COLLECTION) 型データに追加されますが、新しい要素の位置は未定義です。こ
の原則はマルチセット (MULTISET) 型にも適用されます。
ヒント: 単純コレクション (COLLECTION) 型には、値を 1 つずつしか挿入できませ
ん。
リスト (LIST) 型データへの挿入
コレクション (COLLECTION) 型がリスト (LIST) 型の場合、リスト (LIST) 型の特定の
位置または最後に新しい要素を追加できます。セット (SET) 型またはマルチセット
(MULTISET) 型については、最初にコレクション (COLLECTION) 型変数を定義して、
データベースからコレクション (COLLECTION) 型変数へコレクション (COLLECTION)
型データを選択する必要があります。
図 429 では、コレクション (COLLECTION) 型変数を定義して、表 numbers からコレ
クション (COLLECTION) 型変数へリスト (LIST) 型を選択するのに必要な文を示しま
す。
354
IBM Informix SQL ガイド: チュートリアル
DEFINE e_coll LIST(INTEGER NOT NULL);
SELECT evens INTO e_coll FROM numbers
WHERE id = 99;
図 429.
この時点の変数 e_coll の値は LIST {2,4,6,8,10} のようになります。変数 e_coll はリ
スト (LIST) 型を保持するため、各要素のリスト内の位置には番号が付けられます。リ
スト (LIST) 型の特定の位置に要素を追加する場合は、AT 位置 節を INSERT 文に追
加します。図 430 に例を示します。
INSERT AT 3 INTO TABLE(e_coll) VALUES(12);
図 430.
これにより、e_coll のリスト (LIST) 型に、要素 {2,4,12,6,8,10} がこの順で追加され
ます。
AT 節の位置 に入力する値は、数値または変数にすることができます。ただし、整数
(INTEGER) 型または小桁整数 (SMALLINT) 型である必要があります。文字、浮動小数
点数、10 進数値、または式は使用できません。
リスト (LIST) 型のコレクションの基数検査
場合により、リスト (LIST) 型データの終わりに要素を追加する必要があります。この
とき、cardinality( ) 関数を使用して、リスト (LIST) 型データの要素数を検出し、次に
cardinality が戻す値より大きい位置を入力することができます。
Dynamic Server では、cardinality 関数とともに列に格納されるコレクション
(COLLECTION) 型データを使用できますが、コレクション (COLLECTION) 型変数に格
納されるコレクション (COLLECTION) 型データは使用できません。SPL ルーチンで
は、列のコレクション (COLLECTION) 型データの基数を SELECT 文でチェックし、
値を変数に戻すことができます。
表 numbers には、列 id が 99 である行の列 evens にはコレクション (COLLECTION)
型データ LIST {2,4,6,8,10}がまだ含まれていると仮定します。このとき、リスト
(LIST) 型データの最後に要素 12 を追加すると仮定します。これは、図 431 に示すよう
に、SPL プロシジャ end_of_list を使用することで実行可能です。
第 11 章 SPL ルーチンの作成と使用
355
CREATE PROCEDURE end_of_list()
DEFINE n SMALLINT;
DEFINE list_var LIST(INTEGER NOT NULL);
SELECT CARDINALITY(evens) FROM numbers INTO n
WHERE id = 100;
LET n = n + 1;
SELECT evens INTO list_var FROM numbers
WHERE id = 100;
INSERT AT n INTO TABLE(list_var) VALUES(12);
END PROCEDURE;
図 431.
end_of_list の変数 n は、CARDINALITY() が戻す値、つまりリスト (LIST) 型の項目数
を保持します。LET 文は n をインクリメントし、INSERT 文でリスト (LIST) 型の最
後の位置に値を挿入できるようにします。SELECT 文は、表の 1 行からコレクション
(COLLECTION) 型変数 list_var へコレクション (COLLECTION) 型データを選択しま
す。INSERT 文でリストの最後に要素 12 を挿入します。
VALUES 節の構文
VALUES 節の構文は、SPL コレクション (COLLECTION) 型変数に挿入する場合とコ
レクション (COLLECTION) 型列に挿入する場合とで異なります。コレクション
(COLLECTION) 型変数にリテラルを挿入するための構文規則は次のとおりです。
v キーワード VALUES の後の値の完全なリストを括弧で囲みます。
v 単純コレクション (COLLECTION) 型に挿入する場合は、型コンストラクタまたは大
括弧を使用する必要はありません。
v 入れ子コレクション (COLLECTION) 型に挿入する場合は、リテラル コレクション
(COLLECTION) 型データを指定する必要があります。
コレクション (COLLECTION) 型データからの要素の選択
要素を扱うために、コレクション (COLLECTION) 型変数に格納されるコレクション
(COLLECTION) 型データから SPL ルーチンで一度に 1 つの要素を選択すると仮定し
ます。
コレクション (COLLECTION) 型データの要素を移動するには、行の集合を移動するカ
ーソルを宣言する場合のように、まず FOREACH 文を使用してカーソルを宣言する必
356
IBM Informix SQL ガイド: チュートリアル
要があります。図 432 では、 FOREACH 文と END FOREACH 文の間に、文がありま
せん。
FOREACH cursor1 FOR
. . .
END FOREACH
図 432.
FOREACH 文については、337 ページの『カーソルの使用』および「IBM Informix: SQL
ガイド: 構文」に記載されています。
次の『コレクション (COLLECTION) 型データ問合せ』では、FOREACH 文と END
FOREACH 文の間で省略されている文について説明します。
次のセクションで使用する例は、351 ページの図 421 の表 polygons を基にしていま
す。
コレクション (COLLECTION) 型データ問合せ
FOREACH 文と END FOREACH 文の間でカーソルを宣言した後、コレクション
(COLLECTION) 型データ問合せ と呼ばれる特殊かつ制限付きの SELECT 文を入力しま
す。
コレクション (COLLECTION) 型データ問合せは、キーワード FROM TABLE とそれに
続くコレクション (COLLECTION) 型変数名を使用する SELECT 文です。図 433 に、
コレクション (COLLECTION) 型導出表 と呼ばれるこの構造を示します。
FOREACH cursor1 FOR
SELECT * INTO pnt FROM TABLE(vertexes)
. . .
END FOREACH
図 433.
図 433 の SELECT 文では、コレクション (COLLECTION) 型変数 vertexes をコレクシ
ョン (COLLECTION) 型導出表として使用しています。コレクション (COLLECTION)
型導出表は、コレクション (COLLECTION) 型データの各要素が表の行になっている、1
列の表と考えることができます。例えば、vertexes に格納された 4 つのセット (SET)
型ポイントを、4 つの行を持つ表 として使用できます。図 434 に例を示します。
第 11 章 SPL ルーチンの作成と使用
357
’(3.0,1.0)’
’(8.0,1.0)’
’(3.0,4.0)’
’(8.0,4.0)’
図 434.
図 434 の FOREACH 文の最初の反復の後、コレクション (COLLECTION) 型データ問
合せは vertexes の最初の要素を選択し、それを pnt に格納します。つまり、pnt は値
’(3.0,1.0)’ を保持するようになります。
ヒント: コレクション (COLLECTION) 型変数 vertexes がリスト (LIST) 型ではなくセ
ット (SET) 型を保持するため、vertexes の要素には決まった順序がありませ
ん。実際のデータベースでは、値 ’(3.0,1.0)’ がセット (SET) 型データの最
初になっていない場合があります。
コレクション (COLLECTION) 型データ問合せの SPL ルーチンへの追加
これで、SPL ルーチンに FOREACH およびコレクション (COLLECTION) 型データ問
合せで定義したカーソルを追加できます。図 435 に例を示します。
CREATE PROCEDURE shapes()
DEFINE vertexes SET( point NOT NULL );
DEFINE pnt point;
SELECT definition INTO vertexes FROM polygons
WHERE id = 207;
FOREACH cursor1 FOR
SELECT * INTO pnt FROM TABLE(vertexes);
. . .
END FOREACH
. . .
END PROCEDURE;
図 435.
図 435 の文は、コレクション (COLLECTION) 型変数を処理する SPL ルーチンのフレ
ームワークを形成します。コレクションを要素に分解するには、コレクション
(COLLECTION) 型導出表 を使用します。コレクション (COLLECTION) 型データを要
素に分解した後では、ルーチンは、コレクション (COLLECTION) 型導出表の行のよう
に、要素に個別にアクセスできます。pnt の要素を 1 つ選択し、それを更新または削除
できます。363 ページの『コレクション (COLLECTION) 型要素の更新』と 359 ページ
の『コレクション (COLLECTION) 型要素の削除』で説明します。
358
IBM Informix SQL ガイド: チュートリアル
コレクション (COLLECTION) 型データ問合せの構文については、「IBM Informix: SQL
ガイド: 構文」の SELECT 文に関する説明を参照してください。コレクション
(COLLECTION) 型導出表の構文については、「IBM Informix: SQL ガイド: 構文」のコ
レクション (COLLECTION) 型導出表に関する説明を参照してください。
ヒント: 要素を含まないか、あるいはゼロ要素を含むコレクション (COLLECTION) 型
データから選択する場合は、カーソルを宣言しないでコレクション
(COLLECTION) 型データの問合せを使用することができます。ただし、コレク
ション (COLLECTION) 型データに複数の要素が含まれており、カーソルを使
用しない場合には、エラー メッセージが表示されます。
コレクション (COLLECTION) 型要素の削除
コレクション (COLLECTION) 型変数から要素変数へ各要素を選択した後では、コレク
ション (COLLECTION) 型データから要素を削除できます。例えば、コレクション問合
せによってコレクション (COLLECTION) 型変数 vertexes からあるポイントを選択した
ら、コレクション (COLLECTION) 型データからそのポイントを削除できます。
コレクション (COLLECTION) 型データ要素の削除に必要な手順は次のとおりです。
1. コレクション (COLLECTION) 型変数と要素変数を宣言します。
2. データベースからコレクション (COLLECTION) 型変数へコレクション
(COLLECTION) 型データを選択します。
3. コレクション (COLLECTION) 型変数から一度に 1 つの要素を選択できるようにカ
ーソルを宣言します。
4. 削除する要素を検索するループまたは分岐を記述します。
5. コレクション (COLLECTION) 型変数をコレクション (COLLECTION) 型導出表とし
て使用する DELETE WHERE CURRENT OF 文を使用してコレクション
(COLLECTION) 型データから要素を削除します。
図 436 に示すルーチンは vertexes の 4 ポイントの 1 つを削除するため、多角形は四
角形ではなく三角形になります。
第 11 章 SPL ルーチンの作成と使用
359
CREATE PROCEDURE shapes()
DEFINE vertexes SET( point NOT NULL );
DEFINE pnt point;
SELECT definition INTO vertexes FROM polygons
WHERE id = 207;
FOREACH cursor1 FOR
SELECT * INTO pnt FROM TABLE(vertexes)
IF pnt = ’(3,4)’ THEN
-- calls the equals function that
-- compares two values of point type
DELETE FROM TABLE(vertexes)
WHERE CURRENT OF cursor1;
EXIT FOREACH;
ELSE
CONTINUE FOREACH;
END IF;
END FOREACH
. . .
END PROCEDURE;
図 436.
図 436 では、 FOREACH 文でカーソルを宣言しています。SELECT 文はコレクション
(COLLECTION) 導出型問合せであり、コレクション (COLLECTION) 型変数 vertexes
から要素変数 pnt へ要素を 1 回に 1 つ選択します。
IF THEN ELSE 構造が、現在 pnt に格納されている値をテストし、それがポイント
’(3,4)’ であるかどうか調べます。式 pnt = ’(3,4)’ は point データ型について定義さ
れた関数 equal() の実現値を呼び出すことに注意してください。pnt の現行値が
’(3,4)’ の場合、 DELETE 文がそれを削除し、EXIT FOREACH 文がカーソルを終了
します。
ヒント: コレクション (COLLECTION) 型変数に格納されたコレクション
(COLLECTION) 型データから要素を削除しても、データベースに格納されたコ
レクション (COLLECTION) 型データからは削除されません。コレクション
(COLLECTION) 型変数から要素を削除した場合は、データベースに格納されて
いるコレクション (COLLECTION) 型データを新しいコレクション
(COLLECTION) 型データに更新する必要があります。コレクション
(COLLECTION) 型データの列を更新する方法を示す例については、361 ページ
の『データベース内のコレクション (COLLECTION) 型データの更新』を参照
してください。
DELETE 文の構文については、「IBM Informix: SQL ガイド: 構文」に記載されていま
す。
360
IBM Informix SQL ガイド: チュートリアル
データベース内のコレクション (COLLECTION) 型データの更新
要素の削除、更新、または挿入により、SPL ルーチンの中のコレクション
(COLLECTION) 型変数の内容を変更した場合は、データベースを新しいコレクション
(COLLECTION) 型データで更新する必要があります。
データベース内のコレクション (COLLECTION) 型データを更新するには、 UPDATE
文を追加して、表の中のコレクション (COLLECTION) 型の列を、更新されたコレクシ
ョン (COLLECTION) 型変数の内容に設定します。例えば、図 437 の UPDATE 文は、
コレクション (COLLECTION) 型変数 vertexes に格納される新しいコレクション
(COLLECTION) 型データに列 definition を設定して、表 polygons を更新する方法を示
します。
CREATE PROCEDURE shapes()
DEFINE vertexes SET(point NOT NULL);
DEFINE pnt point;
SELECT definition INTO vertexes FROM polygons
WHERE id = 207;
FOREACH cursor1 FOR
SELECT * INTO pnt FROM TABLE(vertexes)
IF pnt = ’(3,4)’ THEN
-- calls the equals function that
-- compares two values of point type
DELETE FROM TABLE(vertexes)
WHERE CURRENT OF cursor1;
EXIT FOREACH;
ELSE
CONTINUE FOREACH;
END IF;
END FOREACH
UPDATE polygons SET definition = vertexes
WHERE id = 207;
END PROCEDURE;
図 437.
これで shapes( ) ルーチンは完成です。shapes( ) ルーチンを実行すれば、列 ID が 207
である行に格納されるコレクション (COLLECTION) 型データは更新されて、4 つでは
なく 3 つの値が含まれます。
コレクション (COLLECTION) 型データを操作する他の SPL ルーチンを記述するため
に、shapes( ) ルーチンをフレームワークとして使用することができます。
第 11 章 SPL ルーチンの作成と使用
361
表 polygons の行 207 の列 definition に、現在格納されるコレクション
(COLLECTION) 型データの要素は次のようにリストされます。
’(3,1)’
’(8,1)’
’(8,4)’
コレクション全体の削除
コレクションのすべての要素を削除する場合は、単一の SQL 文を使用できます。カー
ソルを宣言する必要はありません。コレクション全体を削除するには、次のタスクを行
う必要があります。
v コレクション (COLLECTION) 型変数を定義します。
v データベースからコレクション (COLLECTION) 型変数へコレクションを選択しま
す。
v コレクション (COLLECTION) 型変数をコレクション (COLLECTION) 型導出表とし
て使用する DELETE 文を入力します。
v データベースからコレクションを更新します。
図 438 に、SPL ルーチンでコレクション全体を削除するのに使用する文を示します。
DEFINE vertexes SET( INTEGER NOT NULL );
SELECT definition INTO vertexes FROM polygons
WHERE id = 207;
DELETE FROM TABLE(vertexes);
UPDATE polygons SET definition = vertexes
WHERE id = 207;
図 438.
このフォームの DELETE 文は、コレクション (COLLECTION) 型変数 vertexes のコレ
クション (COLLECTION) 型データ全体を削除します。コレクション (COLLECTION)
型導出表を使用する DELETE 文では、WHERE 節を使用できません。
UPDATE 文の後の表 polygons には空のコレクションが含まれ、列 id は 207 に等しく
なります。
DELETE 文の構文については、「IBM Informix: SQL ガイド: 構文」に記載されていま
す。
362
IBM Informix SQL ガイド: チュートリアル
コレクション (COLLECTION) 型要素の更新
各要素を選択あるいは削除するように、カーソルの範囲内でコレクション
(COLLECTION) 型データにアクセスすることにより、コレクション (COLLECTION) 型
データの要素を更新できます。
コレクション SET{100, 200, 300, 500} を更新して値 500 を 400 にする場合、図 439
に示すようにデータベースからコレクション (COLLECTION) 型変数にセット (SET) 型
を抽出し、その後カーソルを宣言してセット (SET) 型の要素内を移動させます。
DEFINE s SET(INTEGER NOT NULL);
DEFINE n INTEGER;
SELECT numbers INTO s FROM orders
WHERE order_num = 10;
FOREACH cursor1 FOR
SELECT * INTO n FROM TABLE(s)
IF ( n == 500 ) THEN
UPDATE TABLE(s)(x)
SET x = 400 WHERE CURRENT OF cursor1;
EXIT FOREACH;
ELSE
CONTINUE FOREACH;
END IF;
END FOREACH
図 439.
UPDATE 文では、コレクション (COLLECTION) 型変数 s をコレクション
(COLLECTION) 型導出表として使用します。コレクション (COLLECTION) 型導出表を
指定するには、キーワード TABLE を使用します。UPDATE 文内で (s) に続く値 (x)
は、導出列 です。この列名は、コレクション (COLLECTION) 型導出表には列がないに
もかかわらず、SET 節には必要です。
次のような 1 行を持つコレクション (COLLECTION) 型導出表を想定してください。
100
200
300
500
この例では、x は値 500 を持つ「列」の架空の列名です。導出列は、組込み型、不透明
(OPAQUE) 型、ディスティンクト (DISTINCT) 型、またはコレクション
(COLLECTION) 型要素のコレクションを更新するときにのみ指定します。行 (ROW) 型
のコレクション (COLLECTION) 型データを更新する場合は、365 ページの『行 (ROW)
型のコレクション (COLLECTION) 型データの更新』で説明するように導出列の代わり
にフィールド名を使用します。
第 11 章 SPL ルーチンの作成と使用
363
変数によるコレクション (COLLECTION) 型データの更新
リテラル値の代わりに変数に格納された値でも、コレクション (COLLECTION) 型デー
タを更新することができます。
図 440 の SPL プロシジャでは、図 439 に示したのと同じような文を使用しています。
ただし、このプロシジャでは、表 manager の列 direct_reports の セット (SET) 型デ
ータを、リテラル値ではなく変数を使用して更新しています。表 manager は、341 ペ
ージの図 410 で定義されています。
CREATE PROCEDURE new_report(mgr VARCHAR(30),
old VARCHAR(30), new VARCHAR(30) )
DEFINE s SET (VARCHAR(30) NOT NULL);
DEFINE n VARCHAR(30);
SELECT direct_reports INTO s FROM manager
WHERE mgr_name = mgr;
FOREACH cursor1 FOR
SELECT * INTO n FROM TABLE(s)
IF ( n == old ) THEN
UPDATE TABLE(s)(x)
SET x = new WHERE CURRENT OF cursor1;
EXIT FOREACH;
ELSE
CONTINUE FOREACH;
END IF;
END FOREACH
UPDATE manager SET mgr_name = s
WHERE mgr_name = mgr;
END PROCEDURE;
図 440.
FOREACH ループに入れ子になっている UPDATE 文は、コレクション (COLLECTION)
型導出表 s および導出列 x を使用します。現在値の n が old と同じであれば、
UPDATE 文はこれを new の値に変更します。2 番目の UPDATE 文は、表 manager
の新しいコレクションを格納します。
コレクション全体の更新
コレクション (COLLECTION) 型データのすべての要素を同じ値に更新する場合、ある
いはコレクション (COLLECTION) 型データに含まれる要素が 1 つのみの場合は、カー
ソルを使用する必要がありません。図 441 の文は、コレクション (COLLECTION) 型デ
364
IBM Informix SQL ガイド: チュートリアル
ータをコレクション (COLLECTION) 型変数へ抽出して、次に 1 つの文で更新する方法
を示します。
DEFINE s SET (INTEGER NOT NULL);
SELECT numbers INTO s FROM orders
WHERE order_num = 10;
UPDATE TABLE(s)(x) SET x = 0;
UPDATE orders SET numbers = s
WHERE order_num = 10;
図 441.
この例の最初の
(COLLECTION)
べての要素に値
(COLLECTION)
UPDATE 文では x という名前の導出列とコレクション
型導出表 s を使用して、コレクション (COLLECTION) 型データのす
0 を与えます。2 番目の UPDATE 文は新しいコレクション
型データをデータベースに格納します。
行 (ROW) 型のコレクション (COLLECTION) 型データの更新
行 (ROW) 型のコレクション (COLLECTION) 型データを更新する場合は、導出列の名
前の代わりに更新するフィールドの名前を UPDATE 文の中で使用できます。
341 ページの図 410 の manager 表には、図 442 のように定義される projects という
列があり、行 (ROW) 型のリスト (LIST) 型データを含みます。
projects
LIST( ROW( pro_name VARCHAR(15),
pro_members SET(VARCHAR(20) NOT NULL) ) NOT NULL)
図 442.
リスト (LIST) 型データの中の各行 (ROW) 型にアクセスするには、カーソルを宣言し
て、リスト (LIST) 型データを選択してコレクション (COLLECTION) 型変数に格納し
ます。各行 (ROW) 型を抽出した後は、図 443 に示すように、フィールド名および新し
いデータを指定することによりフィールド pro_name または pro_members を更新でき
ます。
第 11 章 SPL ルーチンの作成と使用
365
CREATE PROCEDURE update_pro( mgr VARCHAR(30),
pro VARCHAR(15) )
DEFINE p LIST(ROW(a VARCHAR(15), b SET(VARCHAR(20)
NOT NULL) ) NOT NULL);
DEFINE r ROW(p_name VARCHAR(15), p_member SET(VARCHAR(20) NOT NULL) );
LET r = ROW("project", "SET{’member’}");
SELECT projects INTO p FROM manager
WHERE mgr_name = mgr;
FOREACH cursor1 FOR
SELECT * INTO r FROM TABLE(p)
IF (r.p_name == ’Zephyr’) THEN
UPDATE TABLE(p) SET pro_name = pro
WHERE CURRENT OF cursor1;
EXIT FOREACH;
END IF;
END FOREACH
UPDATE manager SET projects = p
WHERE mgr_name = mgr;
END PROCEDURE;
図 443.
SPL プログラムで行 (ROW) 型変数を使用する前に、 LET 文または SELECTINTO 文
で行 (ROW) 型変数を初期化する必要があります。図 443 の FOREACH ループに入れ
子になっている UPDATE 文は、行 (ROW) 型のフィールド pro_name を、変数 pro
に格納された値に設定します。
ヒント: 行 (ROW) 型の pro_members フィールドの SET 内の値を更新するには、カー
ソルを宣言し、導出列に対して UPDATE 文を使用します。この操作について
は、363 ページの『コレクション (COLLECTION) 型要素の更新』で説明され
ています。
入れ子コレクション (COLLECTION) 型データの更新
コレクションのコレクション (COLLECTION) 型データを更新する場合は、カーソルを
宣言して外部コレクション (COLLECTION) 型データにアクセスし、次に、入れ子カー
ソルを宣言して内部コレクション (COLLECTION) 型データにアクセスする必要があり
ます。
例えば、表 manager には図 444 に示すような追加の列 scores があり、要素型が整数
のマルチセット (MULTISET) 型であるリスト (LIST) 型を含むと仮定します。
366
IBM Informix SQL ガイド: チュートリアル
scores
LIST(MULTISET(INT NOT NULL) NOT NULL)
図 444.
マルチセット (MULTISET) 型の値を更新するには、図 445 に示すように、リスト
(LIST) 型の各値を移動するカーソルと、マルチセット (MULTISET) 型の中の各値を移
動する入れ子カーソルを宣言します。
CREATE FUNCTION check_scores ( mgr VARCHAR(30) )
SPECIFIC NAME nested;
RETURNING INT;
DEFINE
DEFINE
DEFINE
DEFINE
l
m
n
c
LIST( MULTISET( INT NOT NULL ) NOT NULL );
MULTISET( INT NOT NULL );
INT;
INT;
SELECT scores INTO l FROM manager
WHERE mgr_name = mgr;
FOREACH list_cursor FOR
SELECT * FROM TABLE(l) INTO m;
FOREACH set_cursor FOR
SELECT * FROM TABLE(m) INTO n;
IF (n == 0) THEN
DELETE FROM TABLE(m)
WHERE CURRENT OF set_cursor;
ENDIF;
END FOREACH;
LET c = CARDINALITY(m);
RETURN c WITH RESUME;
END FOREACH
END FUNCTION
WITH LISTING IN ’/tmp/nested.out’;
図 445.
図 445 の SPL 関数は、列 scores の マルチセット (MULTISET) 型を l に選択し、マ
ルチセット (MULTISET) 型の各値を m に選択します。m の値が 0 の場合、関数はそ
れをマルチセット (MULTISET) 型から削除します。0 の値を削除した後で、関数は各
マルチセット (MULTISET) 型の中に残った要素をカウントして、整数を戻します。
ヒント: この関数はリスト (LIST) 型の各 マルチセット (MULTISET) 型に値を戻すた
め、関数を実行するときはカーソルを使用して EXECUTE FUNCTION 文を囲
む必要があります。
第 11 章 SPL ルーチンの作成と使用
367
コレクション (COLLECTION) 型データへの挿入
カーソルを宣言しないでコレクション (COLLECTION) 型データに値を挿入できます。
コレクション (COLLECTION) 型データがセット (SET) 型またはマルチセット
(MULTISET) 型の場合は、コレクション (COLLECTION) 型データに値を追加できます
が、コレクション (COLLECTION) 型データは特定の順序を持たないため新しい要素の
位置は未定義です。値がリスト (LIST) 型の場合は、新しい要素をリスト (LIST) 型の特
定のポイントか、またはリスト (LIST) 型の終わりに追加できます。
表 manager の列 direct_reports はセット (SET) 型のコレクション (COLLECTION) 型
データを含み、列 projects はリスト (LIST) 型を含みます。列 direct_reports のセット
(SET) 型に名前を追加するには、図 446 に示すように、INSERT 文とコレクション
(COLLECTION) 型導出表を使用します。
CREATE PROCEDURE new_emp( emp VARCHAR(30), mgr VARCHAR(30) )
DEFINE r SET(VARCHAR(30) NOT NULL);
SELECT direct_reports INTO r FROM manager
WHERE mgr_name = mgr;
INSERT INTO TABLE (r) VALUES(emp);
UPDATE manager SET direct_reports = r
WHERE mgr_name = mgr;
END PROCEDURE;
図 446.
この SPL プロシジャは、引数として従業員名とマネージャ名を取ります。次にプロシ
ジャはユーザが入力した manager について列 direct_reports のコレクション
(COLLECTION) 型データを選択し、ユーザが入力した従業員名を追加し、新しいコレク
ション (COLLECTION) 型データにより表 manager を更新します。
図 446 の INSERT 文はユーザが入力する新しい従業員名を、コレクション
(COLLECTION) 型変数 r に含まれるセット (SET) 型データに挿入します。次に
UPDATE 文が新しいコレクション (COLLECTION) 型データを表 manager に格納しま
す。
VALUES 節の構文に注意してください。リテラル データと変数をコレクション
(COLLECTION) 型変数に挿入するための構文規則は次のとおりです。
v キーワード VALUES の後の値の完全なリストを括弧で囲みます。
v コレクション (COLLECTION) 型データがセット (SET) 型、マルチセット
(MULTISET) 型、またはリスト (LIST) 型の場合は、型コンストラクタとその後にブ
368
IBM Informix SQL ガイド: チュートリアル
ラケットで囲んだ挿入する値のリストを使用します。また、コレクション
(COLLECTION) 型の値は引用符で囲みます。
VALUES( "SET{ 1,4,8,9 }" )
v コレクション (COLLECTION) 型データが行 (ROW) 型を含む場合は、行 (ROW) 型
と、その後に括弧で囲んだ挿入する値のリストを使用します。
VALUES( ROW( ’Waters’, ’voyager_project’ ) )
v コレクション (COLLECTION) 型データが入れ子コレクション (COLLECTION) 型、
入れ子キーワード、括弧、および大括弧の場合は、データ型の定義方法に従います。
VALUES( "SET{ ROW(’Waters’, ’voyager_project’),
ROW(’Adams’, ’horizon_project’) }")
コレクション (COLLECTION) 型データへの値の挿入の詳細については、第 6 章を参照
してください。
入れ子コレクションへの挿入
入れ子コレクション (COLLECTION) 型へ挿入する場合は、 VALUES 節の構文を変更
します。例えば、350 ページの図 420 に示すように、表 numbers の列 twin_primes に
値を挿入すると仮定します。
また、列 twin_primes について、セット (SET) 型をリスト (LIST) 型に挿入、あるいは
要素を内側の セット (SET) 型に挿入する場合も考えられます。次のセクションでは、
このような各タスクを説明します。
外部コレクション(COLLECTION) 型データへのコレクション
(COLLECTION) 型データの挿入: セット (SET) 型をリスト (LIST) 型へ挿入する
ことは、単一値を単純コレクション (COLLECTION) 型に挿入するのと類似していま
す。
セット (SET) 型をリスト (LIST) 型に挿入するには、コレクション (COLLECTION) 型
変数を宣言して、リスト (LIST) 型を保持し、その中にコレクション (COLLECTION)
型データ全体を選択します。コレクション (COLLECTION) 型変数をコレクション
(COLLECTION) 型導出表として使用すると、リスト (LIST) 型の中の各セット (SET)
型が表 の中の行 になります。これで、別のセット (SET) 型をリスト (LIST) 型の終わ
りまたは指定したポイントに挿入できます。
例えば、表 number の 1 行の列 twin_primes は図 447 に示すように、次のリスト
(LIST) 型を含む可能性があります。
第 11 章 SPL ルーチンの作成と使用
369
LIST( SET{3,5}, SET{5,7}, SET{11,13} )
図 447.
リスト (LIST) 型をコレクション (COLLECTION) 型導出表として考える場合は、図 448
に示すようになります。
{3,5}
{5,7}
{11,13}
図 448.
値 "SET{17,19}" をリスト (LIST) 型の 2 番目の項目として挿入する場合は、図 449 の
ように記述します。
CREATE PROCEDURE add_set()
DEFINE l_var LIST( SET( INTEGER NOT NULL ) NOT NULL );
SELECT twin_primes INTO l_var FROM numbers
WHERE id = 100;
INSERT AT 2 INTO TABLE (l_var) VALUES( "SET{17,19}" );
UPDATE numbers SET twin_primes = l
WHERE id = 100;
END PROCEDURE;
図 449.
INSERT 文の中の VALUES 節は、値 SET {17,19} をリスト (LIST) 型の 2 番目の位
置に挿入します。これで、リスト (LIST) 型データは図 450 に示すように表示されま
す。
370
IBM Informix SQL ガイド: チュートリアル
{3,5}
{17,19}
{5,7}
{11,13}
図 450.
図 451 に示すように、セット (SET) 型を引数として SPL ルーチンに渡すことにより、
同じ内容の挿入を行うことができます。
CREATE PROCEDURE add_set( set_var SET(INTEGER NOT NULL),
row_id INTEGER );
DEFINE list_var LIST( SET(INTEGER NOT NULL) NOT NULL );
DEFINE n SMALLINT;
SELECT CARDINALITY(twin_primes) INTO n FROM numbers
WHERE id = row_id;
LET n = n + 1;
SELECT twin_primes INTO list_var FROM numbers
WHERE id = row_id;
INSERT AT n INTO TABLE( list_var ) VALUES( set_var );
UPDATE numbers SET twin_primes = list_var
WHERE id = row_id;
END PROCEDURE;
図 451.
ユーザは add_set() の中で、リスト (LIST) 型に追加するセット (SET) 型データと、そ
のセット (SET) 型データを挿入する行の id である整数 (INTEGER) 型の値を指定しま
す。
内部コレクション (COLLECTION) 型データへの値の挿入: SPL ルーチンで
は、入れ子コレクションの内部コレクション (COLLECTION) 型データに値を挿入する
こともできます。一般的に、入れ子コレクション (COLLECTION) 型の内部コレクショ
ン (COLLECTION) 型データにアクセスして値を追加するには、次の手順を実行しま
す。
1. コレクション (COLLECTION) 型変数を宣言して、表の 1 行に格納されるコレクシ
ョン (COLLECTION) 型データ全体を保持します。
第 11 章 SPL ルーチンの作成と使用
371
2. 要素変数を宣言して、外部コレクション (COLLECTION) 型データの 1 つの要素を
保持します。要素変数自体はコレクション (COLLECTION) 型変数です。
3. コレクション (COLLECTION) 型変数に対して表の 1 行からコレクション
(COLLECTION) 型データを選択します。
4. 外部コレクション (COLLECTION) 型データの要素を移動できるようにカーソルを宣
言します。
5. 要素変数に対して 1 回に 1 つの要素を選択します。
6. 分岐またはループを使用して、更新する内部コレクション (COLLECTION) 型データ
を検索します。
7. 新しい値を内部コレクション (COLLECTION) 型データに挿入します。
8. カーソルをクローズします。
9. データベース表を新しいコレクション (COLLECTION) 型データで更新します。
例として、表 numbers の列 twin_primes についてこの処理を使用できます。例えば、
twin_primes には図 452 に示す値が含まれており、値 18 をリスト (LIST) 型の最後の
セット (SET) 型に挿入すると仮定します。
LIST( SET( {3,5}, {5,7}, {11,13}, {17,19} ) )
図 452.
図 453 は、値を挿入するプロシジャの先頭を示します。
CREATE PROCEDURE add_int()
DEFINE list_var LIST( SET( INTEGER NOT NULL ) NOT NULL );
DEFINE set_var SET( INTEGER NOT NULL );
SELECT twin_primes INTO list_var FROM numbers
WHERE id = 100;
図 453.
これで、attaint プロシジャはステップ 1、2、および 3 を終了しました。最初の
DEFINE 文は、表 numbers の 1 行に格納されるコレクション (COLLECTION) 型デー
タ全体を保持するコレクション (COLLECTION) 型変数を宣言します。
2 番目の DEFINE 文は、コレクション (COLLECTION) 型データの要素を保持する要素
変数を宣言します。この場合、要素変数自体はセット (SET) 型を保持するのでコレクシ
ョン (COLLECTION) 型変数です。SELECT 文は、コレクション (COLLECTION) 型変
数 list_var に 1 行からコレクション (COLLECTION) 型データ全体を選択します。
372
IBM Informix SQL ガイド: チュートリアル
図 454 に示す方法でカーソルを宣言すれば、外部コレクション (COLLECTION) 型デー
タの要素を移動できます。
FOREACH list_cursor FOR
SELECT * INTO set_var FROM TABLE( list_var);
FOREACH element_cursor FOR
図 454.
ルーチンの実行
SPL ルーチンまたは外部ルーチンは、以下のいずれかの方法で実行できます。
v DB–Access から実行するスタンドアロンの EXECUTE PROCEDURE 文または
EXECUTE FUNCTION 文を使用します。
v 別の SPL ルーチンまたは外部ルーチンから明示的にルーチンを呼び出します。
v SQL 文の式でルーチン名を使用します。
外部ルーチン とは、C または他の外部言語で記述されたルーチンです。
EXECUTE 文の使用
EXECUTE PROCEDURE または EXECUTE FUNCTION を使用して、SPL ルーチンま
たは外部ルーチンを実行できます。一般的に、EXECUTE PROCEDURE をプロシジャに
使用し、EXECUTE FUNCTION を関数に使用するのが最良です。
ヒント: 下位方向の互換性のために、EXECUTE PROCEDURE 文では、SPL 関数名と
INTO 節を使用して値を戻すことができます。ただし、EXECUTE
PROCEDURE 文はプロシジャとともにのみ、また EXECUTE FUNCTION 文は
関数とともにのみ使用することをお勧めします。
EXECUTE PROCEDURE 文と EXECUTE FUNCTION 文はスタンド アロン文として
DB–Access から、または SPL ルーチンまたは外部ルーチン内から発行できます。ルー
チン名は、データベースの範囲内で一意であり、引数を必要としない場合は、図 455 に
示すように、EXECUTE PROCEDURE 文の後にその名前と括弧を入力することにより実
行できます。
第 11 章 SPL ルーチンの作成と使用
373
EXECUTE PROCEDURE update_orders();
図 455.
EXECUTE 文でプロシジャを起動する場合はプロシジャが値を戻さないため INTO 節は
存在しません。
ルーチンに引数が含まれるよう予定されている場合は、図 456 に示すように、引数の値
を括弧で囲んで入力する必要があります。
EXECUTE FUNCTION scale_rectangles(107, 1.9)
INTO new;
図 456.
図 456 の文は関数を実行します。関数は値を戻すため、EXECUTE FUNCTION 文は、
戻り値が格納される変数を指定する INTO 節を使用します。関数を実行するために
EXECUTE 文を使用する場合は、必ず INTO 節が必要です。
Dynamic Server
データベースが同じ名前で複数のプロシジャまたは関数を持つ場合は、Dynamic Server
は引数のデータ型に基づいて正しい関数を検索します。例えば、図 456 の文は引数とし
て整数 (INTEGER) 型および小桁実数 (REAL) 型の値を供給するため、データベースに
scale_rectangles() という名前の複数のルーチンが含まれている場合は、データベース サ
ーバは整数 (INTEGER) 型および小桁実数 (REAL) 型を受け付ける関数
scale_rectangles() のみを実行します。
SPL ルーチンのパラメータ リストは、常にパラメータ名とデータ型を持ちます。ルー
チンを実行すると、パラメータ名はオプションになります。ただし 図 457 のように、
値ではなく名前による引数を EXECUTE PROCEDURE 文または EXECUTE
FUNCTION 文に渡すと、Dynamic Server は部分ルーチン解決 として知られる処理によ
り、ルーチンごとの名前と引数のみを解決します。
EXECUTE FUNCTION scale_rectangles( rectid = 107,
scale = 1.9 ) INTO new_rectangle;
図 457.
Dynamic Server の終り
374
IBM Informix SQL ガイド: チュートリアル
修飾ルーチン名 を文に追加することにより、別のデータベース サーバに格納される
SPL ルーチンを実行することもできます。この名前は、図 458 に示すように、
database@dbserver:owner_name.routine_name というフォームになります。
EXECUTE PROCEDURE informix@davinci:bsmith.update_orders();
図 458.
ルーチンをリモートで実行する場合は、修飾のあるルーチン名の owner_name はオプシ
ョンです。
CALL 文の使用
CALL 文を使用して、SPL ルーチンまたは外部ルーチンを SPL ルーチンから呼び出す
ことができます。CALL は、プロシジャと関数の両方を実行できます。関数を実行する
のに CALL 文を使用する場合は、 RETURNING 節と関数が戻す値 (1 つ以上) を受け
取る SPL 変数 (1 つ以上) の名前を追加します。
例えば、図 459 のように、関数 scale_rectangles で四角形の面積を計算し、次に四角形
の記述とともに面積を戻す外部関数を呼び出すと仮定します。
CREATE FUNCTION scale_rectangles( rectid INTEGER,
scale REAL )
RETURNING rectangle_t, REAL;
DEFINE rectv rectangle_t;
DEFINE a REAL;
SELECT rect INTO rectv
FROM rectangles WHERE id = rectid;
IF ( rectv IS NULL ) THEN
LET rectv.start = (0.0,0.0);
LET rectv.length = 1.0;
LET rectv.width = 1.0;
LET a = 1.0;
RETURN rectv, a;
ELSE
LET rectv.length = scale * rectv.length;
LET rectv.width = scale * rectv.width;
CALL area(rectv.length, rectv.width) RETURNING a;
RETURN rectv, a;
END IF;
END FUNCTION;
図 459.
第 11 章 SPL ルーチンの作成と使用
375
図 459 の SPL 関数は、関数 area( ) を呼び出す CALL 文を使用しています。関数
area( ) が戻す値は a に格納され、RETURN 文により呼出しルーチンに戻されます。
この例では area( ) は外部関数ですが、 CALL 文を同じ方法で SPL 関数でも使用でき
ます。
式の中のルーチンの実行
組込み関数と同じように、SPL ルーチン、および SPL ルーチンからの外部ルーチンを
SQL 文と SPL 文の式で使用することにより、実行することができます。式の中で使用
するルーチンは、他の文に値を戻すため、通常は関数になります。
例えば、LET 文により、戻り値を変数に代入する関数を実行できます。図 460 の文は
これと同じタスクを実行します。これらの文は SPL ルーチンの範囲内の外部関数を実
行して、戻り値を変数 a に代入します。
LET a = area( rectv.length, rectv.width );
CALL area( rectv.length, rectv.width ) RETURNING a;
-- these statements are equivalent
図 460.
また、図 461 に示すように、SQL 文からSPL ルーチンを実行することもできます。特
定の割合で特定の価格を増加する SPL 関数 increase_by_pct を記述すると仮定しま
す。作成した SPL ルーチンは、他のいかなる SPL ルーチンでも使用できます。
CREATE FUNCTION raise_price ( num INT )
RETURNING DECIMAL;
DEFINE p DECIMAL;
SELECT increase_by_pct(price, 20) INTO p
FROM inventory WHERE prod_num = num;
RETURN p;
END FUNCTION;
図 461.
図 461 の例は inventory の指定された行の列 price を選択して、その値を SPL 関数
increase_by_pct への引数として使用します。次に、関数は 20% 増加した price の新し
い値を変数 p に戻します。
376
IBM Informix SQL ガイド: チュートリアル
RETURN 文による外部関数の実行
RETURN 文を使用し て SPL ルーチンの範囲内からあらゆる外部関数を実行できま
す。図 462 に示す外部関数は SPL プログラムの RETURN 文で使用されます。
CREATE FUNCTION c_func() RETURNS int
LANGUAGE C;
CREATE FUNCTION spl_func() RETURNS INT;
RETURN(c_func());
END FUNCTION;
EXECUTE FUNCTION spl_func();
図 462.
関数 spl_func() を実行すると、関数 c_func() が起動され、外部関数が戻す値が SPL 関
数により戻されます。
SPL ルーチンからのカーソル関数の実行
カーソル関数はユーザ定義関数であり、1 つ以上のデータの行を戻します。そのために
実行するカーソルが必要です。カーソル関数は、次の関数のいずれかです。
v キーワード WITH RESUME を含む RETURN 文をともなう SPL 関数
v 反復関数として定義される外部関数
カーソル関数の動作は、関数が SPL 関数でも外部関数でも同じです。ただし、SPL カ
ーソル関数は反復のたびに複数の値を戻すことができますが、外部カーソル関数 (反復
関数) は反復のたびに 1 つの値しか戻すことができません。
SPL ルーチンからカーソル関数を実行するには、SPL ルーチンの FOREACH ループに
関数を含める必要があります。次の例は FOREACH ループの中のカーソル関数を実行
するそれぞれの方法を示します。
FOREACH SELECT cur_func1(col_name) INTO spl_var FROM tab1
INSERT INTO tab2 VALUES (spl_var);
END FOREACH
FOREACH EXECUTE FUNCTION cur_func2() INTO spl_var
INSERT INTO tab2 VALUES (spl_var);
END FOREACH
動的ルーチン名の指定
動的ルーチン名指定 の機能を使用すると、呼出しルーチンの範囲内で呼出されるルーチ
ンの名前を作成することにより、別の SPLルーチンから SPL ルーチンを実行できま
第 11 章 SPL ルーチンの作成と使用
377
す。動的ルーチン名指定の機能は、実行時まで名前がわからない別の SPL ルーチンを
呼び出す SPL ルーチンの記述を簡略化します。データベース サーバでは EXECUTE
PROCEDURE 文または EXECUTE FUNCTION 文中の SPL ルーチンの明示的な名前の
代わりに SPL 変数を指定することができます。
図 463 の SPL プロシジャ company_proc は、サイズの大きい全社販売表を更新しま
す。次に salesperson_proc という名前の SPL 変数を割り当てて、各販売員の月間販売
を含む別の小さい表を更新する SPL プロシジャの動的作成名を保持します。
CREATE PROCEDURE company_proc ( no_of_items INT,
itm_quantity SMALLINT, sale_amount MONEY,
customer VARCHAR(50), sales_person VARCHAR(30) )
DEFINE salesperson_proc VARCHAR(60);
-- Update the company table
INSERT INTO company_tbl VALUES (no_of_items, itm_quantity,
sale_amount, customer, sales_person);
-- Generate the procedure name for the variable salesperson_proc
LET salesperson_proc = sales_person || "." || "tbl" ||
current_month || "_" || current_year || "_proc" ;
-- Execute the SPL procedure that the salesperson_proc
-- variable specifies
EXECUTE PROCEDURE salesperson_proc (no_of_items,
itm_quantity, sale_amount, customer)
END PROCEDURE;
図 463.
図 463 のプロシジャ company _proc は 5 つの引数を受け付けて company_tbl に挿入
します。次に、LET 文は、様々な値と連結演算子 || を使用して別の SPL プロシジャの
名前を生成して実行します。LET 文では、
v sales_person は、プロシジャ company_proc に渡される引数です。
v current_month は、システム日付の今月です。
v current_year は、システム日付の今年です。
そのため、Bill という名前の販売員の 1998 年 7 月の販売の記録は、company_proc が
company_tbl に挿入して、各販売員の月間販売を含む小さい表を更新する SPL プロシ
ジャ bill.tbl07_1998_proc を実行します。
378
IBM Informix SQL ガイド: チュートリアル
動的ルーチン名指定のルール
動的に実行される SPL ルーチンの名前を 文字 (CHAR) 型、可変長文字 (VARCHAR)
型、各国語文字 (NCHAR) 型、または 各国語可変長文字 (NVARCHAR) 型として保持
する SPL 変数を定義する必要があります。また、SPL 変数に有効な非 NULL の名前
を与える必要があります。
動的ルーチン名指定の機能が識別する SPL ルーチンは、実行される前に存在している
必要があります。SPL 変数に、有効な SPL ルーチン名を代入すると、EXECUTE
PROCEDURE 文、または EXECUTE FUNCTION 文は、同じ名前の組込み関数が存在す
る場合でも、変数に含まれる名前のルーチンを実行します。
EXECUTE PROCEDURE 文または EXECUTE FUNCTION 文に 2 つの SPL 変数を使
用して owner.routine_name のような形の変数名を作成することはできません。ただし、
例えば bill.proc1 のような完全修飾ルーチン名を含む SPL 変数を使用することはでき
ます。図 464 で両方の場合を説明します。
EXECUTE PROCEDURE owner_variable.proc_variable
-- this is not allowed ;
LET proc1 = bill.proc1;
EXECUTE PROCEDURE proc1 -- this is allowed ;
図 464.
ルーチンのアクセス権
アクセス権は、ルーチンを作成できるユーザと、ルーチンを実行できるユーザを区別し
ます。アクセス権によっては別のアクセス権の一部として生じるものもあります。例え
ば、DBA アクセス権には、ルーチンを作成し、ルーチンを実行する権限、およびその
アクセス権を他のユーザに付与する権限が含まれます。
ルーチンを登録する権限
ルーチンをデータベースに登録するには、許可されたユーザが CREATE CREATE
FUNCTION 文または CREATE PROCEDURE 文の中の SPL コマンドをラップしま
す。データベース サーバにより、登録された SPL ルーチンが内部に格納されます。次
のユーザは新しいルーチンをデータベースに登録する資格があります。
v DBA アクセス権を持つすべてのユーザは、CREATE 文の中にキーワード DBA があ
ってもなくてもルーチンを登録することができます。
第 11 章 SPL ルーチンの作成と使用
379
DBA キーワードの説明については、383 ページの『ルーチンを実行するための DBA
アクセス権』を参照してください。
v DBA アクセス権を持たないユーザが SPL ルーチンを登録するには Resource アクセ
ス権が必要です。ルーチンの作成者はその所有者になります。
DBA アクセス権を持たないユーザは、キーワード DBA を使用してルーチンを登録
できません。
DBA は、ルーチンの作成に必要な Resource アクセス権を他のユーザに与える必要が
あります。また DBA は Resource アクセス権を取り消すことにより、ユーザがさら
にルーチンを作成することを回避できます。
DBA およびルーチン所有者は、DROP FUNCTION 文または DROP PROCEDURE 文に
より登録をキャンセルできます。
ルーチンを実行する権限
Execute アクセス権によりユーザはルーチンを起動できるようになります。EXECUTE
文または CALL 文により、あるいは式の中で関数を使用することによりルーチンを起
動できます。次のユーザはデフォルトの Execute アクセス権を持ち、ルーチンを起動で
きます。
v デフォルトでは、DBA アクセス権を持つあらゆるユーザがデータベース内のあらゆ
るルーチンを実行できます。
v ルーチンが修飾のある CREATE DBA FUNCTION または CREATE DBA
PROCEDURE 文で登録される場合は、 DBA アクセス権を持つユーザだけがそのル
ーチンに対してデフォルトの Execute アクセス権を持ちます。
v データベースが ANSI 標準準拠でない場合は、ユーザ public (Connect データベース
アクセス権を持つユーザ) はキーワード DBA で登録されていないルーチンへの
Execute アクセス権を自動的に持ちます。
v ANSI 標準準拠のデータベースでは、プロシジャの所有者および DBA アクセス権を
持つユーザは追加のアクセス権を受け取らなくてもルーチンを実行できます。
Execute アクセス権の付与と取消し
ルーチンの、GRANT および REVOKE 要件は、以下のとおりです。
v DBA は、データベース内のあらゆるルーチンに Execute アクセス権を付与または取
り消すことができます。
v ルーチンの作成者は、その特定のルーチンの Execute アクセス権を付与または取り消
すことができます。作成者は AS grantor 節を GRANT EXECUTE ON 文に含めるこ
とにより、付与または取消しの能力を失います。
v 所有者 が GRANT EXECUTE ON 文の中にキーワード WITH GRANT を適用する
と、別のユーザは Execute アクセス権を付与できます。
380
IBM Informix SQL ガイド: チュートリアル
DBA またはルーチンの所有者は、次の条件において、Execute アクセス権を DBA でな
いユーザに対して明示的に付与する必要があります。
v ANSI 標準準拠データベース内のルーチン
v yes に設定された環境変数 NODEFDAC を持つデータベース
v DBA キーワードで作成されたルーチン
データベース サーバによりデフォルトでパブリックにアクセス権が付与された場合で
も、所有者はルーチンの Execute アクセス権を制限できます。このためには、REVOKE
EXECUTION ON PUBLIC 文を発行します。それでも DBA および所有者は、なおルー
チンを実行することが可能であり、該当する特定のユーザに Execute アクセス権を付与
できます。
COMMUTATOR 関数および NEGATOR 関数の Execute アクセス権 (IDS)
重要: COMMUTATOR 修飾子または NEGATOR 修飾子を使用して作成した SPL 関数
の Execute アクセス権を明示的に付与する必要がある場合は、被権限授与者が
COMMUNICATOR 修飾子または NEGATOR 修飾子のどちらかを使用する前にそ
の Execute アクセス権を明示的に付与することも必要です。COMMUTATOR 修
飾子または NEGATOR 修飾子は、SPL プロシジャでは指定できません。
次の例では、関数についてのアクセス権の制限と 1 つのユーザ グループに対するその
否定素子の両方を示しています。次のような否定素子関数のペアを作成すると仮定しま
す。
CREATE FUNCTION greater(y PERCENT, z PERCENT)
RETURNS BOOLEAN
NEGATOR= less(y PERCENT, z PERCENT)
. . .
CREATE FUNCTION less(y PERCENT, z PERCENT)
RETURNS BOOLEAN
NEGATOR= greater(y PERCENT, z PERCENT)
デフォルトでは、あらゆるユーザが関数と否定素子の両方を実行できます。次の文は、
accounting のみが、これらの関数を実行できるよう許可します。
REVOKE EXECUTE ON greater FROM PUBLIC
REVOKE EXECUTE ON less FROM PUBLIC
GRANT ROLE accounting TO mary, jim, ted
GRANT EXECUTE ON greater TO accounting
GRANT EXECUTE ON less TO accounting
ユーザは、他のユーザに Execute アクセス権を付与するための WITH GRANT オプシ
ョンの許可をともなう Execute アクセス権を受け取ることがあります。ユーザがルーチ
ンの Execute アクセス権を失った場合には、そのユーザから Execute アクセス権を付与
されたすべてのユーザからも Execute アクセス権が取り消されます。
第 11 章 SPL ルーチンの作成と使用
381
詳細については、「IBM Informix: SQL ガイド: 構文」の GRANT 文および REVOKE
文の説明を参照してください。
ルーチンに関連付けられたオブジェクトのアクセス権
データベース サーバはあらゆる被参照側オブジェクトの存在をチェックして、ルーチン
を起動しているユーザが被参照側オブジェクトにアクセスするのに必要なアクセス権を
持っているかどうかを検証します。例えば、ユーザが表の中のデータを更新するルーチ
ンを実行する場合は、ユーザはルーチンの中で参照される表または列の更新アクセス権
を持つ必要があります。
ルーチンにより参照されるオブジェクトには次のものがあります。
v 表と列
v ユーザ定義のデータ型
v ルーチンにより実行される他のルーチン
ルーチンの所有者が Execute アクセス権を付与する場合は、オブジェクトのアクセス権
には自動的に Execute アクセス権がともないます。GRANT EXECUTE ON 文は、キー
ワード WITH GRANT を含む GRANT 文から権限授与者が受け取るあらゆる表レベル
のアクセス権を被権限授与者に付与します。
ルーチンの所有者は、ルーチンの実行中に作成される修飾のないオブジェクトを所有し
ますが、ルーチンを実行するユーザは所有しません。例えば、ユーザ howie が、次の
SPL ルーチンにより、2 つの表を作成する SPL ルーチンを登録すると仮定します。
CREATE PROCEDURE promo()
. . .
CREATE TABLE newcatalog
(
catlog_num INTEGER
cat_advert VARCHAR(255, 65)
cat_picture BLOB
) ;
CREATE TABLE dawn.mailers
(
cust_num INTEGER
interested_in SET(catlog_num INTEGER)
);
END PROCEDURE;
ユーザ julia は、表 newcatalog を作成するルーチンを実行します。表の名前
newcatalog を修飾する所有者名がないため、ルーチンの所有者 (howie) が newcatalog
を所有します。対照的に、修飾のある名前 dawn.maillist は dawn を maillist の所有者
として識別します。
382
IBM Informix SQL ガイド: チュートリアル
ルーチンを実行するための DBA アクセス権
DBA がキーワード DBA を使用してルーチンを作成すると、データベース サーバは
DBA アクセス権を持つ他のユーザのみに、Execute アクセス権を自動的に付与します。
ただし DBA は、DBA ルーチンの Execute アクセス権を DBA アクセス権を持たない
ユーザに対して明示的に付与することもできます。
キーワード DBA で登録されたルーチンをユーザが実行する場合、ユーザはルーチンの
継続期間中は DBA のアクセス権を所有します。DBA アクセス権を持たないユーザが
DBA ルーチンを実行する場合は、データベース サーバが一時的な DBA アクセス権を
起動者に暗黙的に付与します。 DBA ルーチンを終了する前に、データベース サーバ
は一時的な DBA アクセス権を暗黙的に取り消します。
DBA ルーチンの実行中に作成されたオブジェクトは、ルーチンの文が所有者として他
のユーザを明示的に指定しない限り、ルーチンを実行するユーザが所有します。例え
ば、tony がキーワード DBA により、次のようにルーチン promo() を登録すると仮定
します。
CREATE DBA PROCEDURE promo()
. . .
CREATE TABLE catalog
. . .
CREATE TABLE libby.mailers
. . .
END PROCEDURE;
tony がルーチンを所有しているにもかかわらず、marty がルーチンを実行した場合は、
marty が表 catalog を所有します。ただし、ユーザ libby の名前が表の名前を修飾する
ため libby が表の所有者になって libby.mailers を所有します。
呼び出されたルーチンは DBA アクセス権を継承しません。DBA ルーチンが、キーワ
ード DBA なしで作成されたルーチンを実行する場合、DBA アクセス権は呼び出され
たルーチンには影響しません。
キーワード DBA なしで登録されたルーチンが DBA ルーチンを呼び出す場合は、呼出
す DBA ルーチンの Execute アクセス権を所有している必要があります。DBA ルーチ
ン内の文は、いかなる DBA ルーチン内でも同じように実行されます。
次の例は DBA ルーチンと DBA でないルーチンが相互に作用するとき何が起きるかを
示します。プロシジャ dbspc_cleanup() が別のプロシジャ clust_catalog() を実行すると
仮定します。また、プロシジャ clust_catalog() がインデックスを作成し、clust_catalog()
用の SPL ソース コードに次の文が含まれると仮定します。
CREATE CLUSTER INDEX c_clust_ix ON catalog (catalog_num);
DBA プロシジャ dbspace_cleanup() は、次の文で他のルーチンを呼び出します。
EXECUTE PROCEDURE clust_catalog(catalog)
第 11 章 SPL ルーチンの作成と使用
383
tony は dbspc_cleanup() を DBA プロシジャとして登録し、clust_catalog() は次の文に
示すようにキーワード DBA なしで登録されると仮定します。
CREATE DBA PROCEDURE dbspc_cleanup(loc CHAR)
CREATE PROCEDURE clust_catalog(catalog CHAR)
GRANT EXECUTION ON dbspc_cleanup(CHAR) to marty;
ユーザ marty は dbspc_cleanup() を実行すると仮定します。インデックス c_clust_ix
は、DBA でないルーチンによって作成されるため、両方のルーチンを所有する tony は
c_clust_ix も所有します。対照的に、次の登録文と付与文が示すように clust_catalog()
が DBA プロシジャである場合、marty はインデックス c_clust_ix を所有します。
CREATE PROCEDURE dbspc_cleanup(loc CHAR)
CREATE DBA PROCEDURE clust_catalog(catalog CHAR)
GRANT EXECUTION ON clust_catalog(CHAR) to marty;
dbspc_cleanup() は DBA プロシジャを呼び出すための DBA プロシジャである必要は
ないことに注意してください。
SPL ルーチンのエラー検出
DB–Access で SPL ルーチンを記述するのに CREATE PROCEDURE 文または
CREATE FUNCTION 文を使用する場合、メニューから「Run」を選択し、構文エラー
がルーチン本体で発生すると、文は失敗します。
DB–Access でルーチンを作成しているときにメニューから「Modify」オプションを選択
すると、カーソルは構文エラーを含む行に移動します。「Run」と「Modify」を再度選
択すると次の行をチェックできます。
コンパイル時の警告の表示
データベース サーバにより問題の可能性を検出されたにも関わらず SPL ルーチンの構
文が正しい場合は、警告が生成され、リスト ファイルに入ります。このファイルを調べ
るとルーチンを実行する前に可能性がある問題をチェックできます。
リスト ファイルのファイル名とパス名は、CREATE PROCEDURE 文または CREATE
FUNCTION 文の WITH LISTING IN 節で指定します。リスト ファイルのパス名の指
定方法の詳細については、318 ページの『DOCUMENT 節の指定』を参照してくださ
い。
ネットワーク上で作業している場合は、リスト ファイルはデータベースが常駐するシス
テム上に作成されます。ファイルの絶対パス名とファイル名を入力すると、指定した場
384
IBM Informix SQL ガイド: チュートリアル
所にファイルが作成されます。
UNIX のみ
リスト ファイルの相対パス名を入力した場合は、ファイルはデータベースが常駐するコ
ンピュータのホーム ディレクトリに作成されます (ホーム ディレクトリがない場合、
ファイルはルート ディレクトリに作成されます)。
UNIX のみ の終り
Windows のみ
リスト ファイルの相対パス名を入力したときに、データベースがローカル コンピュー
タ上にある場合は、デフォルトのディレクトリは現在の作業ディレクトリになります。
それ以外の場合は、%INFORMIXDIR%¥bin がデフォルトのディレクトリになります。
Windows のみ の終り
ルーチンを作成した後では、WITH LISTING IN 節で指定したファイルを表示して、含
まれている警告を見ることができます。
ルーチンのテキストの生成
SPL ルーチンは、作成後にシステム カタログ表 sysprocbody に格納されます。
sysprocbody システム カタログ表には、実行可能ルーチンとそのテキストが含まれま
す。
ルーチンのテキストを抽出するには、システム カタログ表 sysprocbody から列 data
を選択します。テキスト エントリの列 datakey はコード T を持ちます。
図 465 の SELECT 文は、SPL ルーチン read_address のテキストを読み込みます。
SELECT data FROM informix.sysprocbody
WHERE datakey = ’T’
-- find text lines
AND procid =
( SELECT procid
FROM informix.sysprocedures
WHERE informix.sysprocedures.procname =
’read_address’ )
図 465.
第 11 章 SPL ルーチンの作成と使用
385
SPL ルーチンのデバッグ
SPL ルーチンを正常に作成および実行した後に、論理エラーが発生することがありま
す。ルーチンに論理エラーがある場合は、TRACE 文を使用するとエラーの検出に役立
ちます。次の項目の値をトレースできます。
v 変数
v 引数
v 戻り値
v SQL エラー コード
v ISAM エラー コード
トレースした値のリストを生成するには、最初に SQL 文 SET DEBUG FILE を使用し
てトレースされた出力を含むファイルに名前を付けます。SPL ルーチンを作成する場合
は、TRACE 文を含めます。
次の方法で TRACE 出力のフォームを指定します。
文
アクション
TRACE ON
SQL 文を除くすべての文をトレースします。使用す
る前に変数の内容を出力します。ルーチン呼出しと
戻り値をトレースします。
TRACE PROCEDURE
ルーチン呼出しと戻り値のみをトレースします。
TRACE expression
リテラルまたは式を出力します。必要な場合は、フ
ァイルに送る前に式の値が計算されます。
図 466 では、 TRACE 文を使用して SPL 関数の実行を監視する方法を示します。
386
IBM Informix SQL ガイド: チュートリアル
CREATE FUNCTION read_many (lastname CHAR(15))
RETURNING CHAR(15), CHAR(15), CHAR(20), CHAR(15),
CHAR(2), CHAR(5);
DEFINE
DEFINE
DEFINE
DEFINE
DEFINE
p_lname,p_fname, p_city CHAR(15);
p_add CHAR(20);
p_state CHAR(2);
p_zip CHAR(5);
lcount, i INT;
LET lcount = 1;
TRACE ON;
-- Trace every expression from here on
TRACE ’Foreach starts’; -- Trace statement with a literal
FOREACH
SELECT fname, lname, address1, city, state, zipcode
INTO p_fname, p_lname, p_add, p_city, p_state, p_zip
FROM customer
WHERE lname = lastname
RETURN p_fname, p_lname, p_add, p_city, p_state, p_zip
WITH RESUME;
LET lcount = lcount + 1;
-- count of returned addresses
END FOREACH
TRACE ’Loop starts’;
-- Another literal
FOR i IN (1 TO 5)
BEGIN
RETURN i , i+1, i*i, i/i, i-1,i WITH RESUME;
END
END FOR;
END FUNCTION;
図 466.
TRACE ON 文により、トレースするルーチンを実行するたびに、SET DEBUG FILE 文
により指定したファイルにエントリが追加されます。デバッグ エントリを参照するに
は、任意のテキスト エディタで出力ファイルを表示します。
次のリストには、図 466 の関数が生成する出力のいくつかが含まれます。各トレース文
の次には、内容の説明があります。
文
アクション
TRACE ON
TRACE ON 文へエコーイングします。
TRACE Foreach starts
式、この場合、リテラル文字列 Foreach Start をト
レースします。
第 11 章 SPL ルーチンの作成と使用
387
start select cursor
FOREACH ループを処理するためにカーソルがオー
プンされていることを通知します。
select cursor iteration
選択したカーソルの各反復の起動を通知します。
expression: (+lcount, 1)
検出した式、(lcount+1) を評価して 2 を出力しま
す。
let lcount = 2
各 LET 文を値とともにエコーイングします。
例外処理
ON EXCEPTION 文を使用して、データベース サーバにより SPL ルーチンに戻される
あらゆる例外 (またはエラー)、またはルーチンにより生成されるあらゆる例外をトラッ
プできます。RAISE EXCEPTION 文を使用すると SPL ルーチン内に例外を生成できま
す。
SPL ルーチンでは、次の条件を処理する例外処理を使用することはできません。
v 正常終了 (戻り行あり)
v 正常終了 (戻り行なし)
エラー トラッピングと復旧
ON EXCEPTION 文は、あらゆるエラーをトラップするメカニズムを提供します。
エラーをトラップするには、文のグループを BEGIN 文と END 文でマークされた文ブ
ロックで囲み ON EXCEPTION IN 文を文ブロックの始めに追加します。ON
EXCEPTION 文に後続するブロックでエラーが発生する場合は、復旧アクションを実行
することができます。
図 467 に、文ブロック内の ON EXCEPTION 文を示します。
388
IBM Informix SQL ガイド: チュートリアル
BEGIN
DEFINE c INT;
ON EXCEPTION IN
(
-206, -- table does not exist
-217 -- column does not exist
) SET err_num
IF err_num = -206 THEN
CREATE TABLE t (c INT);
INSERT INTO t VALUES (10);
-- continue after the insert statement
ELSE
ALTER TABLE t ADD(d INT);
LET c = (SELECT d FROM t);
-- continue after the select statement.
END IF
END EXCEPTION WITH RESUME
INSERT INTO t VALUES (10);
-- fails if t does not exist
LET c = (SELECT d FROM t);
END
-- fails if d does not exist
図 467.
エラーが発生すると、SPL インタープリタは、エラーをトラップする最も内側の ON
EXCEPTION 宣言を検索します。エラー トラッピング後に行う最初のアクションはエラ
ーのリセットです。エラー アクション コードの実行が完了し、生成された ON
EXCEPTION 宣言にキーワード WITH RESUME が含まれていた場合は、エラーを生成
した文に後続する 文から自動的に実行が再開されます。ON EXCEPTION 宣言にキーワ
ード WITH RESUME が含まれていなかった場合には、実行は現在のブロックで完全に
終了します。
ON EXCEPTION 文の制御の有効範囲
ON EXCEPTION 文が有効な文ブロックは、 ON EXCEPTION 文、続く文ブロックの範
囲内で入れ子になっているすべての文ブロック、および ON EXCEPTION 文に後続する
すべての文ブロックに後続する文ブロックです。ON EXCEPTION 文を含む文ブロック
では有効ではありません。
図 468 の疑似コードは、ルーチンの範囲内で例外が有効になる場所を示します。つま
り、エラー 201 が、指定されたブロックの 1 つで発生した場合は、a201 というラベル
のアクションが発生します。
第 11 章 SPL ルーチンの作成と使用
389
CREATE PROCEDURE scope()
DEFINE i INT;
. . .
BEGIN
-- begin statement block A
. . .
ON EXCEPTION IN (201)
-- do action a201
END EXCEPTION
BEGIN
-- statement block aa
-- do action, a201 valid here
END
BEGIN
-- statement block bb
-- do action, a201 valid here
END
WHILE i < 10
-- do something, a201 is valid here
END WHILE
END
BEGIN
-- begin statement block B
-- do something
-- a201 is NOT valid here
END
END PROCEDURE;
図 468.
ユーザが生成する例外
図 469 に示すように、RAISE EXCEPTION 文を使用して独自のエラーを生成すること
ができます。
BEGIN
ON EXCEPTION SET esql, eisam
-- trap all errors
IF esql = -206 THEN
-- table not found
-- recover somehow
ELSE
RAISE exception esql, eisam; -- pass the error up
END IF
END EXCEPTION
-- do something
END
図 469.
390
IBM Informix SQL ガイド: チュートリアル
図 469 では、ON EXCEPTION 文が 2 つの変数 esql および eisam を使用してデータ
ベース サーバが戻すエラー番号を保持します。IF 節は、エラーが発生し、SQL エラー
番号が -206 である場合に実行されます。その他の SQL エラーが検出されると、この
BEGIN END ブロックから、前述の例の最後の BEGINEND ブロックに渡されます。
SQL エラーのシミュレート
図 470 に示すように、SQL エラーを生成してシミュレートすることができます。ユー
ザが pault である場合には、ユーザが実際には更新アクセス権を持っている場合であっ
ても SPL ルーチンは、ユーザがそのアクセス権を持っていないかのように動作しま
す。
BEGIN
IF user = ’pault’ THEN
RAISE EXCEPTION -273;
END IF
END
-- deny Paul update privilege
図 470.
入れ子コードを終了する RAISE EXCEPTION の使用
図 471 では、RAISE EXCEPTION 文を使用して深い入れ子ブロックを終了して外に出
る方法を示します。
第 11 章 SPL ルーチンの作成と使用
391
BEGIN
ON EXCEPTION IN (1)
END EXCEPTION WITH RESUME -- do nothing significant (cont)
BEGIN
FOR i IN (1 TO 1000)
FOREACH select ..INTO aa FROM t
IF aa < 0 THEN
RAISE EXCEPTION 1;
-- emergency exit
END IF
END FOREACH
END FOR
RETURN 1;
END
--do something;
-- emergency exit to
-- this statement.
TRACE ’Negative value returned’;
RETURN -10;
END
図 471.
最も内側の条件が TRUE (aa が負の場合) の場合には、例外が発生して実行はブロック
の END 文に後続するコードにジャンプします。この場合、例外は TRACE 文にジャン
プします。
BEGINEND ブロックが単一 文であることに注意してください。ブロック内部のどこか
でエラーが発生し、トラップがブロックの外にある場合は、実行が再開されたときブロ
ックの残りはスキップされ、次の文から実行が始まります。
このエラーに対してブロック内のどこかにトラップを設定しない場合には、エラー条件
は呼出しを含むあらゆるブロック、およびそのブロックを含むあらゆるブロックに戻さ
れます。エラーを処理するように設定された ON EXCEPTION 文が存在しない場合は、
SPL ルーチンの実行は停止し、SPL ルーチンを実行しているルーチンのエラーが作成さ
れます。
SPL ルーチンで処理される行数のチェック
SPL 内で DBINFO 関数を使用し、 SELECT、INSERT、UPDATE、DELETE、
EXECUTE PROCEDURE、および EXECUTE FUNCTION 文で処理された行数を検出で
きます。
図 472 では、オプション ’sqlca.sqlerrd2’ とともに DBINFO 関数を使用して、表から削
除される行数を判断する SPL 関数を示します。
392
IBM Informix SQL ガイド: チュートリアル
CREATE FUNCTION del_rows ( pnumb INT )
RETURNING INT;
DEFINE nrows INT;
DELETE FROM sec_tab WHERE part_num = pnumb;
LET nrows = DBINFO(’sqlca.sqlerrd2’);
RETURN nrows;
END FUNCTION;
図 472.
有効な結果を確保するために、SELECT 文と EXECUTE PROCEDURE 文、または
EXECUTE FUNCTION 文が完了した後で、このオプションを使用します。また、オプ
ション ’sqlca.sqlerrd2’ をカーソル内で使用する場合は、有効な結果を確保するためにカ
ーソルがクローズする前にすべての行を取り出す必要があります。
サマリ
SPL ルーチンは、データベースのパフォーマンスの向上、アプリケーションの簡略化、
およびデータ アクセスの制限または監視など、データベース処理を能率化する多くの可
能性を提供します。また、SPL ルーチンを使用してコレクション (COLLECTION) 型、
行 (ROW) 型、不透明 (OPAQUE) 型、およびディスティンクト (DISTINCT) 型などの
拡張データ型を扱うことができます。SPL 文の構文ダイアグラムは、「IBM Informix:
SQL ガイド: 構文」に記載されています。
第 11 章 SPL ルーチンの作成と使用
393
394
IBM Informix SQL ガイド: チュートリアル
第 12 章 トリガの作成と使用
トリガを使用するタイミング . . . . . . . . . . . . .
トリガの作成方法 . . . . . . . . . . . . . . . .
トリガ名の割当て . . . . . . . . . . . . . . .
トリガ イベントの指定 . . . . . . . . . . . . . .
トリガ アクションの定義 . . . . . . . . . . . . .
完全な構成の CREATE TRIGGER 文 . . . . . . . . .
トリガ アクションの使用方法 . . . . . . . . . . . .
BEFORE および AFTER トリガ アクションの使用方法 . . .
FOR EACH ROW トリガ アクションの使用方法 . . . . .
REFERENCING 節の使用方法 . . . . . . . . . .
WHEN 条件の使用方法 . . . . . . . . . . . . .
トリガ アクションとしての SPL ルーチンの使用方法 . . .
SPL ルーチンへのデータ引き渡し . . . . . . . . .
SPL の使用. . . . . . . . . . . . . . . . .
SPL ルーチンからのデータによる非トリガ列の更新 . . .
表階層のトリガ (IDS) . . . . . . . . . . . . . . .
選択トリガの使用 (IDS) . . . . . . . . . . . . . .
トリガ アクションを実行する SELECT 文 . . . . . . .
スタンドアロン SELECT 文 . . . . . . . . . . .
SELECT 文の選択リストにあるコレクション (COLLECTION)
ユーザ定義ルーチンに埋め込まれた SELECT 文 . . . .
ビュー . . . . . . . . . . . . . . . . . .
選択トリガの実行についての制限 . . . . . . . . . .
表階層の表に対する選択トリガ . . . . . . . . . . .
リエントラント トリガ . . . . . . . . . . . . . . .
ビューの INSTEAD OF トリガ (IDS) . . . . . . . . . .
INSTEAD OF トリガを使用してビュー上で更新 . . . . .
トリガ アクションのトレース . . . . . . . . . . . .
SPL ルーチン内の TRACE 文の例 . . . . . . . . . .
TRACE 出力の例 . . . . . . . . . . . . . . . .
エラー メッセージの生成 . . . . . . . . . . . . . .
固定エラー メッセージの適用 . . . . . . . . . . .
可変エラー メッセージの生成 . . . . . . . . . . .
© Copyright IBM Corp. 1996, 2004
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
型副問合せ .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
396
397
398
398
398
399
399
399
400
401
402
402
402
403
403
403
404
404
404
404
404
405
405
405
406
406
406
407
407
408
409
409
410
395
サマリ .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 411
本章について
この章では、CREATE TRIGGER 文の各コンポーネントの目的を説明し、トリガの使い
方をいくつか紹介します。また、SPL ルーチンをトリガ アクションとして使用する利
点についても説明します。
Dynamic Server
さらに、ビューで使用される INSTEAD OF トリガについても説明します。
Dynamic Server の終り
SQL トリガは、データベースに常駐する機構です。使用許可さえ受けていれば、どのよ
うなユーザでも使用することができます。SQL トリガは、特定の表に対して挿入、選
択、削除、更新などの特定の操作を行う場合に、データベース サーバが自動的に 1 つ
以上の追加操作を実行するように指定します。追加のアクションは、INSERT 文、
DELETE 文、UPDATE 文、EXECUTE PROCEDURE 文、または EXECUTE
FUNCTION 文です。
Dynamic Server
Dynamic Server はまた、C 言語または Java で作成されたユーザ定義ルーチンもトリガ
アクションとしてサポートします。
Dynamic Server の終り
C 言語の UDR を作成してトリガ イベントについてのメタデータ情報を取得する方法
については、「IBM Informix: DataBlade API Programmer’s Guide」を参照してくださ
い。
トリガを使用するタイミング
トリガはデータベース内に存在し、必要なアクセス権を持つユーザは誰でも使用できる
ため、トリガを使用して、複数のアプリケーションで使用可能な一連の SQL 文を書く
ことができます。トリガを使用すれば、複数のプログラムが同じデータベース操作を実
行する必要がある場合に、コードが冗長になりません。
トリガを使用して、以下に示すアクションを実行できます。また、このリスト以外のア
クションを実行することもできます。
v データベースでの動作監査記録の作成。例えば、監査表に対する確認情報を更新する
ことによって、表 orders に対する更新を追跡することができます。
396
IBM Informix SQL ガイド: チュートリアル
v ビジネス ルールの実装。例えばオーダーが顧客の信用限度を超える条件を決めて、
それに応じたメッセージを表示することができます。
v 表やデータベース内で使用できない補助データの導出。例えば表 items の列 quantity
が更新されると、それに応じて列 total_price を再計算できます。
v 参照整合性の確保。例えば、ある顧客を削除するときに、トリガを使用して表 orders
内の対応する行 (同じ顧客番号を持つ行) を削除することができます。
トリガの作成方法
トリガの作成には CREATE TRIGGER 文を使用します。CREATE TRIGGER 文は、
SQL 文を表内の促進的アクションと共用するデータ定義文です。促進的アクションが発
生すると、それによりデータベースに格納された関連する SQL 文がトリガされます。
図 473 は、促進的アクションまたはトリガ イベントのトリガ アクションとの関係を示
しています。
UPDATE
item_num
2
3
4
5
quantity
3
1
4
1
total_price
15.00
236.00
100.00
280.00
EXECUTE PROCEDURE
upd_items
図 473. トリガ イベントとトリガ アクション
CREATE TRIGGER 文は、以下のアクションを実行する節で構成されます。
v トリガ名の割当て
v トリガ イベント、つまり、表とトリガを開始するアクションの型の指定
v トリガされる SQL アクションの定義
オプションの節 REFERENCING 節は、400 ページの『FOR EACH ROW トリガ アク
ションの使用方法』で説明されています。
トリガを作成するには、DB–Access または SQL API のうち 1 つを使用します。この
章では、DB–Access の問合せ言語オプションを使用して入力した、CREATE TRIGGER
文について説明します。 SQL API では、文 (その文を組込みステートメントとして識
別する記号またはキーワードを含む) を先行させます。
第 12 章 トリガの作成と使用
397
トリガ名の割当て
トリガは、トリガ名によって識別されます。これはデータベース内で固有である必要が
あります。トリガ名は文中の文字列 CREATE TRIGGER に続きます。トリガ名の長さ
は最高 18 バイトで、先頭が文字、その後は文字と 0 から 9 までの数字と下線で構成
することができます。次の例の CREATE TRIGGER 文では、トリガに upqty という名
前を割り当てています。
CREATE TRIGGER upqty
-- assign trigger name
トリガ イベントの指定
トリガ イベント は、トリガを起動する文のタイプです。このタイプの文が表に対して
実行されると、データベース サーバは、トリガ アクションを構成する SQL 文を実行
します。トリガ イベントには、INSERT、SELECT、DELETE、または UPDATE 文が含
まれます。UPDATE または SELECT トリガ イベントを定義する場合は、表内の複数
の列を指定してトリガをアクティブにできます。列名を指定しない場合は、表のどの列
が更新または SELECT されてもトリガが起動されます。各表あたり 1 つの INSERT
および DELETE トリガのみ作成できますが、トリガする列が相互に排他的である限
り、複数の UPDATE または SELECT トリガを作成できます。
現行のデータベース内の表にのみ、トリガを作成できます。トリガはリモート表を参照
できません。
次の CREATE TRIGGER 文の例では、表 items の列 quantity の更新動作として、ト
リガ イベントが定義されています。
CREATE TRIGGER upqty
UPDATE OF quantity ON items
-- an UPDATE trigger event
文のこの部分は、トリガを作成する表を特定しています。トリガ イベントが挿入または
削除の場合、次の例に示すように、このタイプの文と表名のみが必要になります。
CREATE TRIGGER ins_qty
INSERT ON items
-- an INSERT trigger event
トリガ アクションの定義
トリガ アクション は、トリガ イベントが発生するときに実行される SQL 文です。ト
リガ アクションには、INSERT、DELETE、UPDATE、および EXECUTE PROCEDURE
文が含まれます。ただし、実行するアクションを指定するだけでなく、トリガ文を基準
にして実行するタイミング も指定する必要があります。このタイミングは次のいずれか
です。
v トリガ文の実行前
v トリガ文の実行後
v トリガ文の影響を受けるそれぞれの行ごと
398
IBM Informix SQL ガイド: チュートリアル
1 つのトリガで、このようなそれぞれのタイミングに対して、実行する処理を定義する
ことができます。
トリガ アクションを定義するには、発生するタイミングと、実行する SQL 文を指定し
ます。キーワード BEFORE、AFTER、または FOR EACH ROW を使用するアクション
を実行するタイミングを指定します。その後にトリガ アクションを置き、括弧で囲みま
す。次のトリガ アクション定義は、SPL ルーチン upd_items_p1 がトリガ文の前に実
行されることを指定します。
BEFORE(EXECUTE PROCEDURE upd_items_p1) -- a BEFORE action
完全な構成の CREATE TRIGGER 文
完全な CREATE TRIGGER 文を定義するには、トリガ名節、トリガ イベント節、およ
びトリガ アクション節を結合します。次の CREATE TRIGGER 文は、上記の例の文の
コンポーネントを結合したものです。このトリガは、表 items の列 quantity が更新さ
れると必ず、SPL ルーチン upd_items_p1 を実行します。
CREATE TRIGGER upqty
UPDATE OF quantity ON items
BEFORE(EXECUTE PROCEDURE upd_items_p1)
データベース サーバが CREATE TRIGGER 文を処理するときに、例えば、この例の
SPL ルーチン upd_items_p1 などのトリガ定義内のデータベース オブジェクトが存在
しない場合、データベース サーバはエラーを戻します。
トリガ アクションの使用方法
トリガを効果的に使用するには、トリガ文とそれによって引き起こされるトリガ アクシ
ョンの関係を理解する必要があります。トリガ アクションを発生させるタイミング、つ
まり BEFORE、AFTER、および FOR EACH ROW のいずれかを指定するときに、この
関係を定義してください。
BEFORE および AFTER トリガ アクションの使用方法
トリガ イベントの前または後に起こるトリガ アクションは、1 回のみ実行されます。
BEFORE トリガ アクションは、トリガ文 の前、つまり、トリガ イベントの発生前に
実行します。AFTER トリガ アクションは、トリガ文のアクションの完了後に実行され
ます。また、BEFORE トリガ アクションと AFTER トリガ アクションは、トリガ文に
よって行が処理されない場合も実行されます。
さまざまな使用方法がありますが、特に、トリガ文の影響を調べるために、BEFORE ト
リガ アクションと AFTER トリガ アクションを使用することができます。例えば、次
の例に示すように、表 items の列 quantity を更新する前に、SPL ルーチン
upd_items_p1 を呼び出して、表内のすべての品目に対するオーダーの合計数量を計算す
ることができます。このプロシジャは、old_qty と呼ばれる広域変数に合計数量を格納
します。
第 12 章 トリガの作成と使用
399
CREATE PROCEDURE upd_items_p1()
DEFINE GLOBAL old_qty INT DEFAULT 0;
LET old_qty = (SELECT SUM(quantity) FROM items);
END PROCEDURE;
トリガ更新の終了後、再び合計数量を計算してどのくらい変化したかを調べることがで
きます。次の SPL ルーチン upd_items_p2 は、quantityの合計を再計算し、その結果を
局所変数 new_qty に格納します。次に、new_qty と広域変数 old_qty を比較して、全
オーダーの合計数量が 50% 以上増加しているかどうかを調べます。増加している場
合、プロシジャは RAISE EXCEPTION 文を使用して、SQL エラーをシミュレートしま
す。
CREATE PROCEDURE upd_items_p2()
DEFINE GLOBAL old_qty INT DEFAULT 0;
DEFINE new_qty INT;
LET new_qty = (SELECT SUM(quantity) FROM items);
IF new_qty > old_qty * 1.50 THEN
RAISE EXCEPTION -746, 0, ’Not allowed - rule violation’;
END IF
END PROCEDURE;
次のトリガは、upd_items_p1 と upd_items_p2 を呼び出して、表 items の列 quantity
に異常な更新が行われないようにします。
CREATE TRIGGER up_items
UPDATE OF quantity ON items
BEFORE(EXECUTE PROCEDURE upd_items_p1())
AFTER(EXECUTE PROCEDURE upd_items_p2());
更新によって全品目に対するオーダーの合計数量が 50% 以上増加すると、
upd_items_p2 の RAISE EXCEPTION 文によってトリガが終了し、エラーになります。
トリガがデータベース サーバで失敗し、データベースにログ機能がある場合には、デー
タベース サーバは、トリガ文とトリガ アクションの両方によって加えられた変更をロ
ールバックします。トリガが失敗した場合について、詳しくは、「IBM Informix: SQL
ガイド: 構文」の CREATE TRIGGER 文を参照してください。
FOR EACH ROW トリガ アクションの使用方法
FOR EACH ROW トリガ アクションは、トリガ文が影響を与える各行に対して 1 回ず
つ実行されます。例えばトリガ文の構文が次のような場合、FOR EACH ROW トリガ
アクションは、manacled 列が値 ‘KAR’ を持つ items 表の各行に対して 1 回ずつ実行
されます。
UPDATE items SET quantity = quantity * 2
WHERE manu_code = ’KAR’
トリガ文によって行が処理されない場合には、 FOR EACH ROW トリガ アクションは
実行されません。
400
IBM Informix SQL ガイド: チュートリアル
トリガ文が SELECT 文の場合、つまりトリガが選択トリガの場合、トリガ アクション
は、抽出行に対するすべての処理が完了した後に実行されます。ただし、トリガ アクシ
ョンはただちに実行されるわけではありません。FOR EACH ROW アクションは、ユー
ザに戻す行の実現値ごとに実行されます。例えば、ORDER BY 節を含む SELECT 文で
は、すべての行は、ソートされ戻される前に WHERE 節に対し修飾されます。
REFERENCING 節の使用方法
FOR EACH ROW トリガ アクションを作成するときは、通常、トリガ文の実行前また
は後に列の値を参照するかどうかを、トリガ アクション文で指定する必要があります。
例えば、表 items の列 quantity に対する更新の記録を追跡すると仮定します。この処
理を実行するには、次のような表を作成し、動作を記録します。
CREATE TABLE log_record
(item_num
SMALLINT,
ord_num
INTEGER,
username
CHARACTER(8),
update_time
DATETIME YEAR TO MINUTE,
old_qty
SMALLINT,
new_qty
SMALLINT);
この表の列 old_qty と列 new_qty の値を指定するには、表 items 内の列 quantity の
元の値と新しい値、つまりトリガ文の実行前と実行後の値を参照できなければなりませ
ん。REFERENCING 節により、この処理が有効になります。
REFERENCING 節では、列名と結合できる 2 つのプレフィックスを作成することがで
きます。1 つは列の元の値の参照用、もう 1 つは列の新しい値の参照用です。これらの
プレフィックスは、関連名 と呼ばれます。これらの関連名は、要求に応じて、1 つある
いは、両方作成することもできます。キーワード OLD および NEW を使用して作成す
る関連名を示します。次の REFERENCING 節では、関連名として pre_upd と
post_upd を作成して、行の元の値と新しい値を参照しています。
REFERENCING OLD AS pre_upd NEW AS post_upd
次のトリガ アクションは、表 items の行で quantity が更新されたときに、log_record
に行を作成します。INSERT 文は列 item_num と列 order_num の元の値を参照し、さ
らに列 quantity の元の値と新しい値を参照します。
FOR EACH ROW(INSERT INTO log_record
VALUES (pre_upd.item_num, pre_upd.order_num, USER,
CURRENT, pre_upd.quantity, post_upd.quantity));
REFERENCING 節で定義される関連名は、トリガ文の影響を受けるすべての行に適用さ
れます。
重要: トリガ表内の列名を参照する場合に関連名を使用しないと、データベース サーバ
はトリガ表内に定義されたこの列を探索するために特別な動作は行いません。文
がトリガ アクションにかかわらず有効でない限り、関連名を FOR EACH ROW
第 12 章 トリガの作成と使用
401
トリガ アクションの SQL 文中の列名とともに、常に使用する必要があります。
詳しくは、「IBM Informix: SQL ガイド: 構文」の CREATE TRIGGER 文に関す
る説明を参照してください。
WHEN 条件の使用方法
オプションとして、トリガ アクションの前に WHEN 節を使用し、テストの結果に基づ
くアクションを実行することができます。WHEN 節は、キーワード WHEN とそれに続
く括弧内に示される条件文で構成されます。 CREATE TRIGGER 文では、WHEN 節は
キーワード BEFORE、AFTER、または FOR EACH ROW の後に続き、トリガ アクシ
ョン リストに先行します。
WHEN 条件が存在していて、その条件が TRUE の場合には、トリガ アクションは、指
定されたアクションの並びの順に実行されます。WHEN 条件が FALSE または unknown
を評価する場合、トリガ アクション リストのアクションは実行しません。トリガに
FOR EACH ROWの指定がある場合は、WHEN 条件は行ごとにも評価されます。
次のトリガの例では、トリガ アクションは WHEN 節の中の条件が TRUE である場合
のみ実行されます。つまり、更新後の単価が更新前の単価の 2 倍を超える場合に実行さ
れます。
CREATE TRIGGER up_price
UPDATE OF unit_price ON stock
REFERENCING OLD AS pre NEW AS post
FOR EACH ROW WHEN(post.unit_price > pre.unit_price * 2)
(INSERT INTO warn_tab
VALUES(pre.stock_num, pre.manu_code, pre.unit_price,
post.unit_price, CURRENT))
WHEN 条件について、詳しくは、「IBM Informix: SQL ガイド: 構文」の CREATE
TRIGGER 文を参照してください。
トリガ アクションとしての SPL ルーチンの使用方法
もっとも有効なトリガの機能は、SPL ルーチンをトリガ アクションとして呼び出せる
ことです。SPL ルーチンを呼び出す EXECUTE PROCEDURE 文は、トリガ表から SPL
ルーチンへのデータの受け渡しを可能にし、トリガ表を SPL ルーチンから戻されたデ
ータで更新します。 SPL はまた、変数の定義とそれらに対するデータの割り当て、比
較の作成も可能にします。さらに、プロシジャ ステートメントを使用したトリガ アク
ション内の複雑なタスクの実行も可能にします。
SPL ルーチンへのデータ引き渡し
データを EXECUTE PROCEDURE 文の引数リスト内の SPL ルーチンに引き渡すこと
ができます。以下のトリガ例の EXECUTE PROCEDURE 文は、値を表 items の列
quantity および total_price から SPL ルーチン calc_totpr に受け渡します。
402
IBM Informix SQL ガイド: チュートリアル
CREATE TRIGGER upd_totpr
UPDATE OF quantity ON items
REFERENCING OLD AS pre_upd NEW AS post_upd
FOR EACH ROW(EXECUTE PROCEDURE calc_totpr(pre_upd.quantity,
post_upd.quantity, pre_upd.total_price) INTO total_price)
SPL ルーチンにデータを渡すと、プロシジャが実行する操作の中でそのデータを使用す
ることができます。
SPL の使用
先行するトリガの EXECUTE PROCEDURE 文は、以下の例に示す SPL ルーチンを呼
び出します。このプロシジャは、表 items の quantity が更新されたときに列
total_price に加える変更を計算するために、SPL を使用します。プロシジャは、
quantity の新旧の値と、total_price の古い値を受け取ります。古い合計金額の値を古い
数量の値で割り、単価を求めます。次に単価に新しい数量を乗算して新しい合計金額を
求めます。
CREATE PROCEDURE calc_totpr(old_qty SMALLINT, new_qty SMALLINT,
total MONEY(8)) RETURNING MONEY(8);
DEFINE u_price LIKE items.total_price;
DEFINE n_total LIKE items.total_price;
LET u_price = total / old_qty;
LET n_total = new_qty * u_price;
RETURN n_total;
END PROCEDURE;
この例の SPL は、トリガ表から直接取得できないデータをトリガによって導出してい
ます。
SPL ルーチンからのデータによる非トリガ列の更新
トリガ アクション内で、EXECUTE PROCEDURE 文のINTO 節を使用して、トリガ表
の非トリガ列を更新することができます。以下の例の EXECUTE PROCEDURE 文は、
列 total_price を参照する INTO 節を含む、calc_totpr SPL プロシジャを呼び出しま
す。
FOR EACH ROW(EXECUTE PROCEDURE calc_totpr(pre_upd.quantity,
post_upd.quantity, pre_upd.total_price) INTO total_price);
total_price に更新された値は、SPL プロシジャの結論で RETURN 文により戻されま
す。トリガ文の影響を受ける各行に対して、列 total_price (合計金額) が更新されま
す。
表階層のトリガ (IDS)
上位表でトリガを定義すると、その表階層にあるすべての副表にもそのトリガが継承さ
れます。したがって、階層内の表に対して操作を実行するときには、階層内で、トリガ
が定義された表の副表になっているすべての表に対してトリガを実行できます。
第 12 章 トリガの作成と使用
403
選択トリガの使用 (IDS)
表または列に対して選択トリガを作成することにより、表内ヒット数の追跡のような、
特定のタイプの監査をアプリケーションごとに実行できます。選択トリガを作成する
と、ユーザが特定の表に問合せを行うたびに、監査記録を監査表に挿入することができ
ます。例えば、DBA は、Web DataBlade モジュールの Web トランザクション履歴を
提供するため、選択トリガを作成する可能性があります。
トリガ アクションを実行する SELECT 文
選択トリガを作成すると、特定の型の SELECT 文のみが、そのトリガに対して定義さ
れたアクションを実行できます。選択トリガは、次の型の SELECT 文に対してのみ実
行されます。
v スタンドアロン SELECT 文
v SELECT 文の選択リストにあるコレクション (COLLECTION) 型副問合せ
v ユーザ定義ルーチンに埋め込まれた SELECT 文
v ビュー
スタンドアロン SELECT 文
次のような選択トリガを表に定義すると仮定します。
CREATE TRIGGER hits_trig SELECT OF col_a ON tab_a
REFERENCING OLD AS hit
FOR EACH ROW (INSERT INTO hits_log
VALUES (hit.col_a, CURRENT, USER));
選択トリガが実行されるのは、スタンド アロン SELECT 文の選択リストにトリガ列が
表示された場合です。次の文は、データベース サーバが戻す行の実現値ごとに、トリガ
hits_trig に対してトリガ アクションを実行します。
SELECT col_a FROM tab_a
SELECT 文の選択リストにあるコレクション (COLLECTION) 型副問合せ
選択トリガが実行されるのは、別の SELECT 文の選択リストに現れたコレクション
(COLLECTION) 型副問合せにトリガ列が表示された場合です。次の文は、コレクション
(COLLECTION) 型副問合せが戻す行の実現値ごとに、トリガ hits_trig に対してトリガ
アクションを実行します。
SELECT MULTISET(SELECT col_a FROM tab_a) FROM ...
ユーザ定義ルーチンに埋め込まれた SELECT 文
ユーザ定義ルーチン (UDR) に埋め込まれた SELECT 文に対して定義された選択トリガ
は、次のような実現値のみでトリガ アクションを実行します。
v SELECT 文の選択リストに表示される UDR
v 実行プロシジャ ステートメントで呼び出される UDR
404
IBM Informix SQL ガイド: チュートリアル
文 SELECT col_a FROM tab_a を含むルーチン new_proc を作成すると仮定します。次
の各文は、埋め込まれた SELECT 文が戻す行の実現値ごとに、トリガ hits_trig に対し
てトリガ アクションを実行します。
SELECT new_proc() FROM tab_b
EXECUTE PROCEDURE new_proc
ビュー
選択トリガは、基本表にトリガ列への参照を含むビューに対してトリガ アクションを実
行します。ただし、ビューに対して選択トリガを定義することはできません。
次のようなビューを作成すると仮定します。
CREATE VIEW view_tab AS
SELECT * FROM tab_a
次の文は、ビューが戻す行の実現値ごとに、トリガ hits_trig に対してトリガ アクショ
ンを実行します。
SELECT * FROM view_tab
SELECT col_a FROM tab_a
選択トリガの実行についての制限
次のような場合、その文は選択トリガに対して何のアクションも起こしません。
v トリガ列が選択リストにない場合 (例えば、SELECT 文の WHERE 節に表示されて
いる列は選択トリガを実行しません)。
v SELECT 文がリモート表をインクルードする場合。
v SELECT 文が集計関数を含む場合。
v SELECT 文が UNION または UNION ALL 演算子をインクルードする場合。
v SELECT 文がキーワード DISTINCT または UNIQUE をインクルードする場合。
v SELECT 文を含む UDR 表現式が選択リストに存在しない場合。
v SELECT 文が INSERT INTO 文に表示される場合。
v SELECT 文がスクロール カーソルに表示される場合。
v トリガがカスケードされる選択トリガである場合。
カスケード選択トリガは、トリガ SELECT 文を自前で持つ SPL ルーチンをそのアク
ションに含むトリガです。ただし、カスケード選択トリガのアクションは実行され
ず、データベース サーバはエラーを戻しません。
表階層の表に対する選択トリガ
上位表に対して選択トリガを定義すると、その表階層にあるすべての副表もそのトリガ
を継承します。
第 12 章 トリガの作成と使用
405
継承されたトリガを上書きする方法、または無効にする方法については、403 ページの
『表階層のトリガ (IDS)』を参照してください。
リエントラント トリガ
リエントラント トリガ は、トリガ アクションがトリガ表を参照できるケースを指しま
す。言い換えると、トリガ イベントとトリガ アクションの両方が同じ表で動作できま
す。例えば、次のUPDATE文がトリガ イベントを表しているとします。
UPDATE tab1 SET (col_a, col_b) = (col_a + 1, col_b + 1)
列 col_c はトリガ イベントが更新した列ではないので、次のトリガ アクションは有効
です。
UPDATE tab1 SET (col_c) = (col_c + 3)
この前の例では、トリガ アクションが、トリガ イベントによって更新される列を参照
している UPDATE 文であってはならないので、col_a または col_b に対するトリガ ア
クションは無効です。
重要: 選択トリガはリエントラント トリガにはなり得ません。トリガ イベントが
SELECT 文である場合、同じ表でトリガ アクションを動作させることはできませ
ん。
トリガをリエントラント可能および不可能な状態を説明するルールのリストについて、
詳しくは、「IBM Informix: SQL ガイド: 構文」の CREATE TRIGGER 文を参照してく
ださい。
ビューの INSTEAD OF トリガ (IDS)
ビューは CREATE VIEW 文を使用して作成し、SELECT 文を使用して定義する仮想表
です。それぞれのビューは、問合せのビューを参照する度にビュー定義の SELECT 文
が戻す、一連の行と列で構成されます。ビューは仮想表であるため、ビュー内で行を挿
入、更新、または削除するには、INSTEAD OF トリガを使用する必要があります。
ビューで行を挿入する INSTEAD OF トリガの例を含む、CREATE VIEW 文および
INSTEAD OF トリガ構文ルールについて、詳しくは、「IBM Informix: SQL ガイド: 構
文」を参照してください。
INSTEAD OF トリガを使用してビュー上で更新
1 つ以上の表 (以下の例の表名 dept および emp など) を作成し、さらに dept および
emp からビュー (ビュー名 manager_info など) を作成後、INSTEAD OF トリガを使用
してそのビューを更新できます。
406
IBM Informix SQL ガイド: チュートリアル
以下の CREATE TRIGGER 文は、表 dept および emp 内の行を、manager_info ビュ
ーを使用して更新するために設計された、INSTEAD OF トリガである
manager_info_update を作成します。
CREATE TRIGGER manager_info_update
INSTEAD OF UPDATE ON manager_info
REFERENCING NEW AS n
FOR EACH ROW
(EXECUTE PROCEDURE updtab (n.empno, n.empname, n.deptno,));
CREATE PROCEDURE updtab (eno INT, ename CHAR(20), dno INT,)
DEFINE deptcode INT;
UPDATE dept SET manager_num = eno where deptno = dno;
SELECT deptno INTO deptcode FROM emp WHERE empno = eno;
IF dno !=deptcode THEN
UPDATE emp SET deptno = dno WHERE empno = eno;
END IF;
END PROCEDURE;
表、ビュー、トリガ、および SPL ルーチンを作成後、データベース サーバは、以下の
UPDATE 文をトリガ イベントとして扱います。
UPDATE manager_info
SET empno = 3666, empname = “Steve”
WHERE deptno = 01;
このトリガされる UPDATE 文は実行されませんが、このイベントは updtab() SPL を
呼び出して、代わりにトリガ アクションを実行させます。 SPL ルーチン内の
UPDATE 文は、manager_info ビューの emp および dept ベースの表両方に、値を更
新します。
トリガ アクションのトレース
トリガ アクションが意図した動作を行わない場合、SPL ルーチンに配置し、
SPLTRACE 文を使用してその操作を監視してください。トレースを開始する前にSET
DEBUG FILE TO 文を使用してトレース結果がファイルに出力されるようにします。
SPL ルーチン内の TRACE 文の例
以下の例は、SPL ルーチン items_pct に追加した TRACE 文を示しています。 SET
DEBUG FILE TO 文は、パス名で指定されるファイルにトレースが出力されるようにし
ます。TRACE ON 文は、文および変数のトレースをプロシジャ内で開始します。
CREATE PROCEDURE items_pct(mac CHAR(3))
DEFINE tp MONEY;
DEFINE mc_tot MONEY;
DEFINE pct DECIMAL;
SET DEBUG FILE TO ’pathname’;
TRACE ’begin trace’;
TRACE ON;
第 12 章 トリガの作成と使用
407
LET tp = (SELECT SUM(total_price) FROM items);
LET mc_tot = (SELECT SUM(total_price) FROM items
WHERE manu_code = mac);
LET pct = mc_tot / tp;
IF pct > .10 THEN
RAISE EXCEPTION -745;
END IF
TRACE OFF;
END PROCEDURE;
CREATE TRIGGER items_ins
INSERT ON items
REFERENCING NEW AS post_ins
FOR EACH ROW(EXECUTE PROCEDURE items_pct (post_ins.manu_code));
TRACE 出力の例
items_pct プロシジャからのトレース出力の例を次に示します。このプロシジャは、SET
DEBUG FILE TO 文の中で指定されたファイルに出力されています。この出力に示され
ているのは、プロシジャ変数の値、プロシジャ引数、戻り値、およびエラー コードで
す。
trace expression :begin trace
trace on
expression:
(select (sum total_price)
from items)
evaluates to $18280.77 ;
let tp = $18280.77
expression:
(select (sum total_price)
from items
where (= manu_code, mac))
evaluates to $3008.00 ;
let mc_tot = $3008.00
expression:(/ mc_tot, tp)
evaluates to 0.16
let pct = 0.16
expression:(> pct, 0.1)
evaluates to 1
expression:(- 745)
evaluates to -745
raise exception :-745, 0, ’’
exception : looking for handler
SQL error = -745 ISAM error = 0 error string =
exception : no appropriate handler
= ’’
TRACE 文を使用して SPL ルーチン内の論理エラーを診断する方法について、詳しく
は、 305 ページの『第 11 章 SPL ルーチンの作成と使用』を参照してください。
408
IBM Informix SQL ガイド: チュートリアル
エラー メッセージの生成
SQL 文が原因でトリガが失敗する場合、データベース サーバは、失敗の特定の原因に
適用する SQL エラー番号を戻します。
トリガ アクションが SPL ルーチンの場合は、2 つの予約エラー番号のうちの 1 つを
使用して、他のエラー条件を表すエラー メッセージを生成することができます。1 つは
エラー番号 -745 で、これには一般的な固定エラー メッセージが割り当てられていま
す。もう 1 つは -746 であり、最大 70 バイトからなるメッセージ テキストを指定す
ることができます。
固定エラー メッセージの適用
エラー番号 -745 を、SQL エラーでないすべてのトリガの失敗に適用できます。このエ
ラーには、次の固定メッセージがあります。
-745 トリガの実行に失敗しました。
このメッセージは、SPL の RAISE EXCEPTION 文を使用して適用できます。次の例で
は、new_qty が old_qty の 1.5 倍を超える場合にエラー -745 を生成します。
CREATE PROCEDURE upd_items_p2()
DEFINE GLOBAL old_qty INT DEFAULT 0;
DEFINE new_qty INT;
LET new_qty = (SELECT SUM(quantity) FROM items);
IF new_qty > old_qty * 1.50 THEN
RAISE EXCEPTION -745;
END IF
END PROCEDURE
DB–Access を使用している場合は、エラー -745 のメッセージ テキストは、図 474 に
示すように画面の一番下に表示されます。
第 12 章 トリガの作成と使用
409
Press CTRL-W for Help
SQL: New Run Modify Use-editor Output Choose Save
Modify the current SQL statements using the SQL editor.
Info
Drop
Exit
--------------------- stores8@myserver --------- Press CTRL-W for Help ---INSERT INTO items VALUES( 2, 1001, 2, ’HRO’, 1, 126.00);
745: Trigger execution has failed.
図 474. 固定メッセージが表示されるエラー -745
ご使用の SQL API の SQL 文を使用して、エラーを含むプロシジャをトリガする場
合、データベース サーバは、SQL エラー状態変数を -745 に設定し、プログラムに戻
します。このメッセージ テキストを表示するには、SQL エラー メッセージのテキスト
を抽出するために IBM Informix アプリケーション開発支援ツールが提供しているプロ
シジャに従います。
可変エラー メッセージの生成
エラー番号 -746 では、エラー メッセージのテキストを指定することができます。前述
の例のように、次の例も new_qty が old_qty に 1.50 を掛けた値より大きい場合にエ
ラーを生成します。ただし、この場合のエラー番号は -746 であり、Too many items
for Mfr. というメッセージ テキストが、RAISE EXCEPTION 文の 3 番目の引数とし
て出力されます。構文およびこの文の使用方法について、詳しくは 305 ページの『第
11 章 SPL ルーチンの作成と使用』の RAISE EXCEPTION 文を参照してください。
CREATE PROCEDURE upd_items_p2()
DEFINE GLOBAL old_qty INT DEFAULT 0;
DEFINE new_qty INT;
LET new_qty = (SELECT SUM(quantity) FROM items);
IF new_qty > old_qty * 1.50 THEN
RAISE EXCEPTION -746, 0, ’Too many items for Mfr.’;
END IF
END PROCEDURE;
DB–Access を使用してトリガ文を実行要求する場合や、new_qty が old_qty より大きい
場合には、図 475 に示す結果になります。
410
IBM Informix SQL ガイド: チュートリアル
Press CTRL-W for Help
SQL:
New Run Modify Use-editor Output Choose Save
Modify the current SQL statements using the SQL editor.
Info
Drop
Exit
-------------------- store7@myserver --------- Press CTRL-W for Help ----INSERT INTO items VALUES( 2, 1001, 2, ’HRO’, 1, 126.00);
746: Too many items for Mfr.
図 475. ユーザ指定のメッセージ テキストが表示されるエラー番号 -746
トリガを SQL API の SQL 文から呼び出す場合、データベース サーバは sqlcode を
-746 に設定し、SQL 通信領域 (SQLCA) の sqlerrm フィールド内のメッセージ テキ
ストを戻します。 SQLCA の使用方法について、詳しくは、ご使用の SQL API マニュ
アルを参照してください。
サマリ
トリガ導入の観点から、この章では次のトピックについて説明しました。
v CREATE TRIGGER 文の各コンポーネントの目的
v BEFORE トリガ アクションと AFTER トリガ アクションの作成方法と、それらの
トリガ アクションを使用したトリガ文の影響の調査方法
v FOR EACH ROW トリガ アクションの作成方法と、REFERENCING 節を使用した、
トリガ文の実行前後の列値の参照方法
v SPL ルーチンをトリガ アクションとして使用する利点
v トリガ アクションが期待どおりに動作しないときのトレース方法
v トリガ アクション内の 2 種類のエラー メッセージの生成方法
第 12 章 トリガの作成と使用
411
412
IBM Informix SQL ガイド: チュートリアル
付録. アクセシビリティ
このマニュアルの HTML バージョンの構文ダイアグラムは、小数点付き 10 進数構文
フォーマットに従っています。このフォーマットは、スクリーン リーダ (読上げソフト
ウェア) を使用している場合に限り利用できるフォーマットです。
小数点付き 10 進数構文ダイアグラム
小数点付き 10 進数フォーマットでは、構文要素はそれぞれ別の行に書き込まれます。2
つ以上の構文要素が、まとめて使用される (またはどちらも使用されない) 場合、単一
の複合構文要素と見なすことができるため、それらの要素が同じ行に表示される場合が
あります。
各行は小数点付き 10 進数値で開始されます。例えば、3、3.1 または 3.1.1 などで
す。これらの数字を正確に聞き取るために、必ずスクリーン リーダ (読上げソフトウェ
ア) が句読点を読み取るように設定してください。同じ小数点付き 10 進数値を持つす
べての構文要素 (例えば、数値 3.1 を含むすべての構文要素) は相互に排他的な選択肢
です。行 3.1 USERID および行 3.1 SYSTEMID を聞き取った場合、構文に USERID また
は SYSTEMID のいずれかを記述できますが、両方を組み込むことはできません。
小数点付き 10 進数の番号付けレベルにより、ネストのレベルが示されます。例えば、
小数点付き 10 進数値 3 の構文要素の後に、小数点付き 10 進数値 3.1 の構文要素が
続く場合、3.1 と番号付けされている構文要素はすべて、3 と番号付けされている構文
要素に従属します。
構文要素についての情報を追加するために、小数点付き 10 進数値の横に特定の単語お
よび記号が付加されます。場合により、これらの単語および記号が要素の先頭で使用さ
れることがあります。識別を容易にするため、該当する単語または記号が構文要素の一
部である場合には、その単語または記号の前に円記号 (¥) を付加します。* 記号を小数
点付き 10 進数値の横に付加して、その構文要素が反復することを示すことができま
す。例えば、小数点付き 10 進数値 3 の構文要素 *FILE は、読取り時に 3 ¥* FILE と
示されます。フォーマット 3* FILE は、構文要素 FILE が反復することを示します。フ
ォーマット 3* ¥* FILE は、構文要素 * FILE が反復することを示します。
構文要素文字列の分離に使用されるコンマなどの文字は、構文では分離する項目の直前
に表示されます。これらの文字は、各項目と同じ行に表示される場合と、関連項目と同
じ小数点付き 10 進数値を持つ別の行に表示される場合があります。行には構文要素に
ついての情報を提供する別の記号も表示される場合があります。例えば、5.1*、5.1
LASTRUN、5.1 DELETE などの行は、LASTRUN および DELETE 構文要素を複数使用する場
© Copyright IBM Corp. 1996, 2004
413
合に、これらの要素をコンマで分離する必要があることを意味します。分離文字を指定
しない場合、各構文要素の分離には空白が使用されるものと想定します。
構文要素の前に % 記号がある場合、別の場所で定義されている参照を示します。% 記号
に続く文字列はリテラルではなく、構文フラグメントの名前です。例えば、行 2.1 %OP1
は、別の構文フラグメント OP1 を参照する必要があることを意味します。
小数点付き 10 進数値の横に次の単語および記号が付加されます。
414
?
オプションの構文要素を指定します。後ろに ? 記号が続く小数点付き 10 進数
値は、対応する小数点付き 10 進数値の構文要素すべて、およびそれに従属す
る構文要素がオプションであることを示します。ある小数点付き 10 進数値に
構文要素が 1 つのみ含まれる場合、? 記号はその構文要素と同じ行に表示され
ます (例えば、5? NOTIFY)。ある小数点付き 10 進数値に構文要素が複数含ま
れる場合、? 記号は行に単独で表示され、以下オプションの構文要素が続きま
す。例えば、5 ?、5 NOTIFY、5 UPDATE などの行を聞き取った場合、構文要素
NOTIFY と UPDATE がオプションであることが分かります。つまり、それらをい
ずれも選択しないか、1 つのみ選択します。? 記号は、レールロード構文ダイ
アグラムでのバイパス線に相当します。
!
デフォルトの構文要素を指定します。小数点付き 10 進数値とそれに続く ! 記
号および構文要素は、同じ小数点付き 10 進数値を共用するすべての構文要素
に対し、構文要素がデフォルト オプションであることを示します。同じ小数点
付き 10 進数値を共用する構文要素のうちの 1 つのみで ! 記号を指定できま
す。例えば、2? FILE、2.1! (KEEP)、2.1 (DELETE) などの行を聞き取った場合
は、(KEEP) が FILE キーワードに対するデフォルト オプションであることが
分かります。この例では、オプションを指定せずに FILE キーワードを組み込
んだ場合、デフォルト オプション KEEP が適用されます。デフォルト オプシ
ョンは 1 レベル上の小数点付き 10 進数値にも適用します。この例では、FILE
キーワードが省略されるとデフォルトの FILE(KEEP) が使用されます。しか
し、2? FILE、2.1、2.1.1! (KEEP)、および 2.1.1 (DELETE) などの行を聞き取
った場合は、デフォルト オプション KEEP は 1 レベル上の小数点付き 10 進
数値 2.1 (関連キーワードなし) のみに適用し、2? FILE には適用しません。
キーワード FILE が省略されると、いずれも使用されません。
*
ゼロ回以上の反復が可能な構文要素を指定します。後ろに * 記号が続く小数点
付き 10 進数値は、この構文要素をゼロ回以上使用できることを示します。つ
まり、これはオプションであり、かつ反復可能です。例えば、行 5.1*
data-area を聞き取った場合、複数の data-area を記述するか、または 1 つも
記述しないことが可能であると分かります。 3*、3 HOST、3 STATE などの行を
聞き取った場合は、HOST、STATE 両方を記述するか、またはいずれも記述しな
いことが可能であると分かります。
IBM Informix SQL ガイド: チュートリアル
注:
1. 小数点付き 10 進数値の横にアスタリスク (*) があり、その小数点付き 10
進数値が指定された項目が 1 つのみである場合は、その同じ項目を複数回
反復できます。
2. 小数点付き 10 進数値の横にアスタリスクがあり、その小数点付き 10 進数
値がいくつかの項目で指定されている場合は、そのリストから複数の項目を
使用できますが、各項目を複数回使用することはできません。前の例では、
HOST STATE と記述することはできますが、HOST HOST とは記述できませ
ん。
3. * 記号は、レールロード構文ダイアグラムでのループバック線に相当しま
す。
+
1 回以上組み込む必要がある構文要素を指定します。後ろに + 記号が続く小
数点付き 10 進数値は、この構文要素を 1 回以上組み込む必要があることを示
します。例えば、行 6.1+ data-area を聞き取った場合、少なくとも 1 つの
data-area を記述する必要があります。 2+、2 HOST、2 STATE などの行を聞き
取った場合、HOST または STATE、もしくはその両方を記述する必要があると分
かります。 * 記号の場合と同様、その小数点付き 10 進数値が指定された唯一
の項目である場合に限り、特定の項目を反復できます。+ 記号は、* 記号と同
様に、レールロード構文ダイアグラムでのループバック線に相当します。
付録. アクセシビリティ
415
416
IBM Informix SQL ガイド: チュートリアル
特記事項
本書に記載の製品、サービス、または機能が日本においては提供されていない場合があ
ります。日本で利用可能な製品、サービス、および機能については、日本 IBM の営業
担当員にお尋ねください。本書で IBM 製品、プログラム、またはサービスに言及して
いても、その IBM 製品、プログラム、またはサービスのみが使用可能であることを意
味するものではありません。これらに代えて、IBM の知的所有権を侵害することのな
い、機能的に同等の製品、プログラム、またはサービスを使用することができます。た
だし、IBM 以外の製品とプログラムの操作またはサービスの評価および検証は、お客様
の責任で行っていただきます。
IBM は、本書に記載されている内容に関して特許権 (特許出願中のものを含む) を保有
している場合があります。本書の提供は、お客様にこれらの特許権について実施権を許
諾することを意味するものではありません。実施権についてのお問い合わせは、書面に
て下記宛先にお送りください。
〒106-0032
東京都港区六本木 3-2-31
IBM World Trade Asia Corporation
Licensing
以下の保証は、国または地域の法律に沿わない場合は、適用されません。IBM およびそ
の直接または間接の子会社は、本書を特定物として現存するままの状態で提供し、商品
性の保証、特定目的適合性の保証および法律上の瑕疵担保責任を含むすべての明示もし
くは黙示の保証責任を負わないものとします。国または地域によっては、法律の強行規
定により、保証責任の制限が禁じられる場合、強行規定の制限を受けるものとします。
この情報には、技術的に不適切な記述や誤植を含む場合があります。本書は定期的に見
直され、必要な変更は本書の次版に組み込まれます。IBM は予告なしに、随時、この文
書に記載されている製品またはプログラムに対して、改良または変更を行うことがあり
ます。
本書において IBM 以外の Web サイトに言及している場合がありますが、便宜のため
記載しただけであり、決してそれらの Web サイトを推奨するものではありません。そ
れらの Web サイトにある資料は、この IBM 製品の資料の一部ではありません。それ
らの Web サイトは、お客様の責任でご使用ください。
IBM は、お客様が提供するいかなる情報も、お客様に対してなんら義務も負うことのな
い、自ら適切と信ずる方法で、使用もしくは配布することができるものとします。
© Copyright IBM Corp. 1996, 2004
417
本プログラムのライセンス保持者で、(i) 独自に作成したプログラムとその他のプログラ
ム (本プログラムを含む) との間での情報交換、および (ii) 交換された情報の相互利用
を可能にすることを目的として、本プログラムに関する情報を必要とする方は、下記に
連絡してください。
IBM Corporation
J46A/G4
555 Bailey Avenue
San Jose, CA 95141-1003
U.S.A.
本プログラムに関する上記の情報は、適切な使用条件の下で使用することができます
が、有償の場合もあります。
本書で説明されているライセンス・プログラムまたはその他のライセンス資料は、IBM
所定のプログラム契約の契約条項、IBM プログラムのご使用条件、またはそれと同等の
条項に基づいて、IBM より提供されます。
この文書に含まれるいかなるパフォーマンス・データも、管理環境下で決定されたもの
です。そのため、他の操作環境で得られた結果は、異なる可能性があります。一部の測
定が、開発レベルのシステムで行われた可能性がありますが、その測定値が、一般に利
用可能なシステムのものと同じである保証はありません。さらに、一部の測定値が、推
定値である可能性があります。実際の結果は、異なる可能性があります。お客様は、お
客様の特定の環境に適したデータを確かめる必要があります。
IBM 以外の製品に関する情報は、その製品の供給者、出版物、もしくはその他の公に利
用可能なソースから入手したものです。IBM は、それらの製品のテストは行っておりま
せん。したがって、他社製品に関する実行性、互換性、またはその他の要求については
確証できません。IBM 以外の製品の性能に関する質問は、それらの製品の供給者にお願
いします。
IBM の将来の方向または意向に関する記述については、予告なしに変更または撤回され
る場合があり、単に目標を示しているものです。
表示されている IBM の価格は IBM が小売り価格として提示しているもので、現行価
格であり、通知なしに変更されるものです。卸価格は、異なる場合があります。
本書には、日常の業務処理で用いられるデータや報告書の例が含まれています。より具
体性を与えるために、それらの例には、個人、企業、ブランド、あるいは製品などの名
前が含まれている場合があります。これらの名称はすべて架空のものであり、名称や住
所が類似する企業が実在しているとしても、それは偶然にすぎません。
著作権使用許諾:
本書には、様々なオペレーティング・プラットフォームでのプログラミング手法を例示
するサンプル・アプリケーション・プログラムがソース言語で掲載されています。お客
418
IBM Informix SQL ガイド: チュートリアル
様は、サンプル・プログラムが書かれているオペレーティング・プラットフォームのア
プリケーション・プログラミング・インターフェースに準拠したアプリケーション・プ
ログラムの開発、使用、販売、配布を目的として、いかなる形式においても、IBM に対
価を支払うことなくこれを複製し、改変し、配布することができます。このサンプル・
プログラムは、あらゆる条件下における完全なテストを経ていません。従って IBM
は、これらのサンプル・プログラムについて信頼性、利便性もしくは機能性があること
をほのめかしたり、保証することはできません。お客様は、IBM のアプリケーション・
プログラミング・インターフェースに準拠したアプリケーション・プログラムの開発、
使用、販売、配布を目的として、いかなる形式においても、IBM に対価を支払うことな
くこれを複製し、改変し、配布することができます。
それぞれの複製物、サンプル・プログラムのいかなる部分、またはすべての派生的創作
物にも、次のように、著作権表示を入れていただく必要があります。
© (お客様の会社名) (西暦年). このコードの一部は、IBM Corp. のサンプル・プログ
ラムから取られています。© Copyright IBM Corp. (年を入れる).All rights reserved.
この情報をソフトコピーでご覧になっている場合は、写真やカラーの図表は表示されな
い場合があります。
特記事項
419
商標
AIX; DB2; DB2 Universal Database; Distributed Relational Database Architecture;
NUMA-Q; OS/2、OS/390、および OS/400; IBM Informix®; C-ISAM®; Foundation.2000™;
IBM Informix ® 4GL; IBM Informix®DataBlade®Module; Client SDK™; Cloudscape™;
Cloudsync™; IBM Informix®Connect; IBM Informix®Driver for JDBC; Dynamic Connect™;
IBM Informix®Dynamic Scalable Architecture™(DSA); IBM Informix®Dynamic Server™;
IBM Informix®Enterprise Gateway Manager (Enterprise Gateway Manager); IBM
Informix®Extended Parallel Server™; i.Financial Services™; J/Foundation™; MaxConnect™;
Object Translator™; Red Brick™; IBM Informix® SE; IBM Informix® SQL;
InformiXML™; RedBack®; SystemBuilder™; U2™; UniData®; UniVerse®; wintegrate® は、
IBM Corporation の商標です。
Java およびすべての Java 関連の商標およびロゴは、Sun Microsystems, Inc. の米国およ
びその他の国における商標または登録商標です。
Windows、Windows NT および Excel は、Microsoft Corporation の米国およびその他の
国における商標です。
UNIX は、The Open Group の米国およびその他の国における登録商標です。
本書で言及しているその他の会社名、製品名およびサービス名はそれぞれ各社の商標ま
たは登録商標です。
420
IBM Informix SQL ガイド: チュートリアル
索引
日本語, 数字, 英字, 特殊文字の順に配列されてい
ます。なお, 濁音と半濁音は清音と同等に扱われ
ています。
アーカイブ
説明 225
xxi
埋込み SQL
データベース サーバ メソッド
トランザクション ログ 225
225
アクセシビリティ xxiv
構文ダイアグラム、スクリーン リーダ (読上げソフ
トウェア) による読取り 413
小数点付き 10 進数フォーマットの構文ダイアグラ
ム 413
データ修正の必要
開始の例 218
説明 217
名前の割当て 219
例 215
意味整合性 210
インストール ガイド
[ア行]
アクセス モード、説明
アクセス権
概要 6
違反表 (続き)
299
© Copyright IBM Corp. 1996, 2004
237
カーソルのオープン時の検出 251
カーソルを使用した挿入 271
コード 241
更新中
221
処理 248
DELETE の後 266
ISAM エラー コード
241
エラー メッセージ xxiii
可変、生成 410
適用する固定 409
207
データベース レベル 207
データベースでの 207
表示 208
表レベル 207
アクティブ セット
カーソルの 253
定義 38, 245
アスタリスク、SELECT 内のワイルドカード文字
アスタリスク表記、SELECT 文 89
アプリケーション
エラー処理 248
排他レベル 290
UPDATE カーソル 296
一時表
およびカーソルのアクティブ セット 254
例 199
列名の割当て 146
意図ロック 298
違反の検出 214
違反表
アクセス権の例 219
開始 218
使用可能な言語
定義 236
エラー
25
トリガ失敗への 409
トリガでの生成 409
プログラム内のトリガ テキストの検索 410, 411
エラー メッセージ ファイル 244
エラー検査
エラーのシミュレート 391
SPL ルーチン 388, 392
エンティティ保全性 210
大文字小文字変換
INITCAP 関数を使用 120
LOWER 関数を使用 118
UPPER 関数を使用 119
オブジェクト モード
説明 214
停止 215
フィルタ 215
有効 214
オブジェクト リレーショナル データベース、説明 11
オンライン ノート xxi, xxii
オンライン ヘルプ xxiv
421
オンライン マニュアル
各国語文字 (NCHAR) 型、問合せ
xxiv
[カ行]
カーソル
オープン
クローズ
更新
251, 253
302
xv
21
LIKE
302
48
WHERE 節内
関係モデル
結合 23
プログラム操作のシーケンス 250
FETCH での値の抽出 251
カーソル安定性排他レベル (Informix) 293
射影
253
38
21
選択 21
関数
式への適用
カーソルの選択
オープン 251
使用 250
106
時刻 106
集計 100
スマート ラージ オブジェクト
階層
表および行 94
外部キー 211
日付関連
外部結合構文
ANSI 150
Informix 149
外部データベース 231
外部表 226
拡張性、説明 11
確定読込み排他レベル (ANSI) 292
確定読込み排他レベル (Informix) 292
カスケード削除
関連したロック 212
子表 213
参照整合性 212
制約事項 213
定義 212
ロギング 213, 224
型付き表
から選択 85
行の挿入 192
定義 84
型なし 325
各国語可変長文字 (NVARCHAR) 型、問合せ
48
MATCHES
NULL 45
OR 43
270
定義 250
トランザクションの終わり
のアクティブ セット 253
422
409
環境変数
関係演算
BETWEEN 42
EXISTS 159
IN 159
順 252, 254
スクロール 252
宣言 250
カーソルのオープン
画面、例
関係演算子
275, 290
挿入のため
20
可変長文字 (VARCHAR) 型、LENGTH 関数の使用
126
20
IBM Informix SQL ガイド: チュートリアル
116
106
変換 112
文字列操作 118
DATE 112
DBINFO 129
DECODE 130
INITCAP 120
LOWER 118
LPAD 124
NVL 131
REPLACE 120
RPAD 124
SELECT 文内 100
SPL ルーチンでの名前の混同
SUBSTR 123
SUBSTRING 121
TO_CHAR 113
TO_DATE 114
UPPER 119
関数、データ暗号化 134
キーワード
構文ダイアグラム内 xix
331
キーワード (続き)
キーワード LIKE
副問合せ内 159
WHERE 節内 38
説明 48
WHERE 節での使用
キーワード ALL
副問合せ
GLS の使用
160
副問合せの開始 159
キーワード ANY、SELECT 文内 161
52
WHERE 節での使用
キーワード MULTISET
キーワード BETWEEN
38
コレクション (COLLECTION) 型の副問合せ
行範囲の指定に使用 42
WHERE 節での使用 38
キーワード DISTINCT
168
キーワード NOT EXISTS 180
キーワード NOT IN 180
キーワード ORDER BY
COUNT 関数で使用 102
GROUP BY との関係 139
SELECT での使用 31
キーワード ESCAPE、WHERE 節での使用
38
キーワード MATCHES
および GLS 36
キーワード DESC
行のソート 26
昇順
53
27, 35
27
キーワード EXCLUSIVE
DATABASE 文の 284
キーワード EXISTS 179
番号で列を選択
表示ラベル 64
複数の列 28
SELECT 文内 164
WHERE 節内 159
キーワード FOR UPDATE
FOR UPDATE の制約事項 270
GROUP BY との関係 140
INSERT の制約事項 199
特定の列 276
ANSI 標準準拠データベースで必要とされない
276
34
キーワード REFERENCES、SPL 関数内 325
キーワード SCROLL、DECLARE 内での使用 253
ORDER BY との競合 270
キーワード FROM、別名 76
キーワード SOME、副問合せの開始 159
キーワード TABLE、ロック モードの 286
キーワード GROUP BY
説明 138
列番号 141
キーワード HAVING 142
キーワード IN
積の構成 179
WHERE 節での使用 38
キーワード INTO
格納場所の選択 252
単一行の抽出 245
複数行の抽出 250
FETCH 文 252
INSERT の制約事項 198
PREPARE 文で処理された文の制約事項 258
SQLWARN でシグナル通知されるミスマッチ 243
キーワード INTO TEMP、説明 79
キーワード IS NOT NULL 45
キーワード IS NULL 45
キーワード ITEM、コレクション (COLLECTION) 型の
副問合せ 168
キーワード UNION、集合演算で 171
キーワード UNIQUE、SELECT 文内 31
キーワード UPDATE 276
キーワード WHERE
値の範囲 42
NULL データのテスト 45
キーワード WITH HOLD、HOLD カーソルの宣言
規格準拠
業界標準 xxviii
規則
構文記法 xvi
構文ダイアグラム xvi
コマンド行 xviii
サンプル コード xx
表記 xiv
表記上 xv
行
関係モデル 10
更新 200
除去 185
処理された行数の検出 129
索引
303
423
行 (続き)
結合 (続き)
挿入
定義
定義 23, 66
等価結合 69
190
10, 20
戻される行数
ロック
左外部
55
複合
286
SPL ルーチン内で処理された行数
行 ID、内部行番号の検索に使用 65
150
66
複数表結合 74
右外部 152
392
行 (ROW) 型
ANSI 外部結合構文
150
からのデータ選択 84
からの列選択 86
更新 203
Informix 外部結合構文 149
UPDATE 文内 206
コード、サンプル、の規則 xx
ピリオド表記 87
フィールド、定義 86
フィールド射影 87
コード例の表記規則 xx
広域言語サポート (GLS) xii
およびキーワード MATCHES
DELETE 文内
およびキーワード ORDER BY
188
SELECT でのアスタリスク表記の使用
SELECT でのフィールド射影 88
行 (ROW) 型データの列を選択 86
行 (ROW) 型変数、宣言
行 (ROW) 型列
定義 86
89
326
NULL 値 203
業界標準、準拠 xxviii
共有クラス ライブラリ
共有ロック 283
36
36
説明 332
宣言 332
交換子関数
定義 316
交差結合 69
12
局所変数、説明 323
切捨て、SQLWARN でシグナル通知される 243
金額 (MONEY) 型
INSERT 文内 191
組込み変数 324
クラス ライブラリ、共有 12
繰返し可能読込み排他レベル 295
警告、SPL ルーチンでのコンパイル時 384
計数関数
説明 115
結合
入れ子になった単純 153
外部 149
結合性 74
交差 69
削除結合 189
作成 68
自然 72
条件 66
セルフ結合 145
単純 66
424
ソート順 36
デフォルト ロケール
広域変数
52
IBM Informix SQL ガイド: チュートリアル
更新ロック、保存
構成パラメータ
296
ISOLATION_LOCKS 293
構文セグメント xviii
構文ダイアグラム
キーワード xix
スクリーン リーダ (読上げソフトウェア)での読取り
413
の規則 xvi
変数 xx
コマンド行の表記規則
サンプル ダイアグラム xviii
読み方 xviii
固有名、SPL ルーチンの 312
コレクション (COLLECTION) 型
アクセス 84, 90
更新 204
説明 90
単純 90
要素、IN での検索 92
要素のカウント 116
CARDINALITY 関数の使用 116
DELETE 文内 188
コレクション (COLLECTION) 型 (続き)
時刻関数
SPL ルーチン内 320
コレクション (COLLECTION) 型値、列への挿入
コレクション (COLLECTION) 型導出表
コレクションの要素へのアクセス
WEEKDAY
170
145, 214
システム カタログ
363
アクセス権 208
問合せ 208
sysprocbody 385
説明 167
コレクション (COLLECTION) 型変数
入れ子 90, 91
systabauth 208
システム記述子領域
システム要件
ソフトウェア
データベース
91
定義、制約事項 326
コレクション、INSERT 文の使用
サーバ、データベース、他のサーバとの通信
再帰的関係の例 255
細分性、ロック 283
差集合演算 180
260
xii
xii
自然結合 72
射影、説明 11
195
[サ行]
234
射影、定義 22
集計関数
および GROUP BY 節
139
式 100
シグナル通知するされる NULL 値
243
説明 100, 112
標準偏差 105
サブスクリプト付け
SPL 変数 330
WHERE 節内 54
サブ文字列 35, 330
作用素、存在 164
算術演算子、式 58
算術式 58
参照整合性、定義 211
参照制約、定義 212
シーケンス
定義 10
視覚障害
構文ダイアグラムの読取り
時間隔 (INTERVAL) 型
関係式 39
式
説明 58
の表示ラベル 61
日付関連 106
CASE 63
SPL ルーチン内 336
107
100
109
YEAR 110
自己参照型問合せ
コレクション (COLLECTION) 型の副問合せ
キーワード ITEM 168
キーワード ITEM の使用 168
選択
説明 106
DAY および CURRENT
SELECT での使用
169
制約事項 171
説明 167, 358
SPL での使用
195
413
副問合せ 161
AVG 102
COUNT 101
ESQL 内 246
MAX 103
MIN 103
NULL 値の検索 249
RANGE 104
SPL ルーチン内 336
STDEV 105
SUM 103
VARIANCE 105
集合演算
差 180
使用 171
積 178
和集合 171
修正された問題と既知の問題についてのファイル
主キー、定義 210
主キー制約、定義 212
順カーソル、定義 252
索引
xxii
425
循環型問合せ
上位表 97
から削除
セルフ結合
214
186
から選択
96
表階層内
94
選択、説明 11, 21
選択トリガ、説明 404
選択リスト
別名の使用 97
への挿入 195
照合順序と GLS
関数
36
小数点付き 10 進数フォーマットの構文ダイアグラム
413
シリアル (SERIAL) 型
開始値の挿入 191
最後に挿入されたシリアル値の検索
SQLERRD で生成される値 241
129
身体障害、視覚
構文ダイアグラムの読取り
診断表
アクセス権の例 220
413
開始の例 218
説明 217
シンプル ラージ オブジェクト、SPL 変数 325
スクリーン リーダ (読上げソフトウェア)
構文ダイアグラムの読取り 413
スクロール カーソル
アクティブ セット
254
定義 252
ストアド プロシジャ言語
参照: SPL
ストアド ルーチン、一般的なプログラミング 14
すべてのマニュアルのマニュアル セット xxv
スマート ラージ オブジェクト
インポートおよびエクスポート 116, 197
コピーする関数 116
SPL 変数 325
SQL 関数の使用
INSERT 文内 197
SELECT 文内 116
UPDATE 文内 206
整合性がある削除 267
静的 SQL 238
制約、エンティティ保全性 210
積
集合演算 178
定義 179
積集合演算 179
セッション ID、DBINFO 関数が戻す 129
426
145
説明 145
INTO TEMP を使用した列名の割当て
IBM Informix SQL ガイド: チュートリアル
100, 129
サブ文字列の指定
式 58
すべての列を選択
特定の列を選択
表示ラベル 61
ラベル 176
35
25
30
ソート
入れ子 28
ロケールの影響 36
GLS の効果 36
ORDER BY を使用 27
相関副問合せ
カスケード削除の制約事項
定義
214
157
増進可能なロック
ソフトウェア要件
283, 290
xii
[タ行]
多重順序付け、SELECT 28
単一行 SELECT 文 38, 245
単純読込み排他レベル (Informix) 292
チェック制約、定義 211
中括弧 ({ }) コメント区切り 319
重複値、検索 65
データ モデル、説明 2
データ レプリケーション 227
データ暗号化関数 134
データ型
コレクション、アクセス 84, 90
自動変換 246
変換 191, 246
データ整合性 209
障害 221
データ定義文 261
データの終り
カーソルのオープン時 251
SELECT のみのシグナル 274
SQLCODE 251
146
データの終り (続き)
デフォルト値 (続き)
SQLCODE のシグナル
データのロード 226
241, 248
データベース
オブジェクト リレーショナル、説明
外部
管理
11
監査
166
自己参照型の
複合
6
制御 6
定義 9
内容の変更
211
214
循環型 214
データ モデルとして記述
231
8
サーバ
列内
問合せ
等価結合 69
動的 SQL
説明 238, 257
5
ファイルとの比較
並行使用 6
リモート 231
4
171
PREPARE 文で処理された文の解放
動的ルーチン名指定
のルール 379
3
リレーショナル、説明
8
ロック 284
ANSI 標準準拠 14
データベース オブジェクト
違反の検出 214
インデックス 214
オブジェクト モード
214
制約 214
トリガ 214
データベース オブジェクト モード
例 215
データベース サーバ
アーカイブ 225
バージョン番号の識別 130
文のキャッシュ 304
ホスト コンピュータ名の識別 129
ロック表 284
SQLWARN でのシグナル通知 243
定数データの行の挿入 272
ディスティンクト (DISTINCT) 型変数 328
デカルト積
結合の基本 68
説明 67
テキスト (TEXT) 型
関係式 39
制約事項
GROUP BY の 140
LENGTH 関数の使用 126
デッドロック検出 301
デフォルト ロケール xii
デフォルト値
使用 249
SPL 関数用
260
377
SPL ルーチン用 377
ドキュメント ノート xxii
特殊文字、プロテクト 53
トランザクション
終わり 302
説明 222
の終りに解除されるロック 289
の終りへのロック保持 290
ロギング 222
DELETE の例 267
SQLWARN でのシグナルの使用
トランザクション ログ
説明 222
ログの内容 225
XPS 223
トリガ
作成 397
使用時 396
選択
実行の制約事項 405
説明 404
表階層における定義 405
定義 396
名前の割当て 398
表階層内 403
リエントラント 406
INSTEAD OF 406
トリガ アクション
エラー メッセージの生成 409
使用 399
定義 398
243
索引
427
トリガ アクション (続き)
トリガ文を基準にする
トレース 407
文
パブリックに付与されたアクセス権に影響力を持つ環境
変数 NODEFDAC 381
バリアント SPL 関数 316
398
比較条件、説明 38
非確定読込み排他レベル (ANSI)
396
BEFORE および AFTER
399
左外部結合
FOR EACH ROW 400
REFERENCING 節 401
SELECT 文
日付 (DATE) 型
関係式 39
関数からの戻り
文字列への変換
404
SPL ルーチンを使用する
WHEN 条件 402
トリガ イベント
292
150
402
106
113
ORDER BY シーケンスで
27
等しい (=) 関係演算子 40, 69
等しくない (!=) 関係演算子 40
定義 398
例 398
ビュー
から削除 406
定義 10
で更新 406
[ナ行]
名前付き行型、VALUES 節内 193
名前なし行型、VALUES 節内 194
二重ハイフン (--) コメント標識
日時 (DATETIME) 型
319
関係式 39
関数からの戻り 106
形式の表示 111
文字列への変換
113
ORDER BY シーケンスで 27
日時 (DATETIME) 型値、形式 111
[ハ行]
バージョン番号、DBINFO 関数が戻す 130
排他レベル
カーソル安定性 (Informix) 293
繰返し可能読込み 295
説明 291
単純読込み 292
非確定読込み 292
ANSI 292, 295
Informix 292
排他ロック 283
バイト (BYTE) 型
関係式 39
GROUP BY の制約事項 140
LENGTH 関数の使用 126
パフォーマンス
ストアド ルーチンによる増加 308
並行性の効果 280
428
の INSTEAD OF トリガ
への挿入 406
IBM Informix SQL ガイド: チュートリアル
406
表
階層
94
関係モデル 9
現行データベースにない
説明 9
47
操作 10
データのロード
外部表の使用 226
onload ユーティリティの使用 226
ロギング 223
ログなし 223
ロック 284
表階層
のトリガ 403
UPDATE 文 204
標識変数、定義 247
標準偏差、集計関数 105
表示ラベル 315
ORDER BY 節 64
SELECT で 60
ピリオド表記 87
ブール (BOOLEAN) 式 46
ファイル、データベースとの比較 2
フィールド、定義 86
フィールド射影 87
フィルタ モード 215
複合問合せ 171
複数表結合
変数
74
複数表の SELECT 文
副問合せ
一価
66
161
キーワード ALL
160
キーワード ANY 161
選択リスト内 159
相関
157, 162, 214
DELETE 文内 189
SELECT 文内 157
UPDATE 文内 200
キーワードと同じ名前をもつ 330
SPL ルーチンでの定義および使用 323
SPL ルーチンでの範囲
324
変数、構文ダイアグラム内
xx
ホスト変数 240
区切り記号 239
シグナル通知される切捨て
説明 238
へのデータの取出し
DELETE 文内 266
243
251
SET 節を使用 201
WHERE 節内 159
不透明 (OPAQUE) 型変数 328
INSERT 文内 270
INTO キーワード セット
NULL 標識 247
太文字
PREPARE 文で処理された文の制約事項
xv
部品展開 255
プログラム変数
SPL 238
245
258
UPDATE 文内 275
WHERE 節内 246
本書の規則 xiv
文キャッシュ、SQL 303
文ブロック 336
ページ ロック 286
[マ行]
ペーパー マニュアル
並行性
マシン ノート xxii
マニュアル、タイプ xxi
xxiv
アクセス モード 299
アクティブ セット 255
カーソル安定性排他レベル (Informix) 293
説明 227, 280
データベース ロック 284
デッドロック 301
排他レベル 291
表ロック 284
複数のプログラム 281
ロックの継続期間 289
ロックの種類 283
ロック範囲 283
ANSI 排他レベル 292
Informix 排他レベル 292
別名
一時表での列名の割当て 146
使用
上位表で 97
問合せのショートカットとして 76
セルフ結合 145
表名の 76
ヘルプ xxiv
変換関数、説明 112
オンライン マニュアル xxiv
ペーパー マニュアル xxiv
マシン ノート xxii
マルチスレッド アプリケーション、定義 237
右外部結合 152
文字 (CHAR) 型
関係式 39
サブ文字列 35
シグナル通知される切捨て 243
日時 (DATETIME) 型値への変換 114
日付 (DATE) 型値への変換 112
文字の表記規則 xv
文字列
日時 (DATETIME) 型値への変換 114
日付 (DATE) 型値への変換 112
戻りの型、SPL 関数内 314
[ヤ行]
ユーザ、対象の xii
ユーティリティ プログラム
onload 226
onunload 226
索引
429
要件、ソフトウェア
ロック (続き)
xii
より小または等しい 41
より大または等しい (>=) 関係演算子
ロックの種類 283
行とキーのロック
41
共有
[ラ行]
ラベル 61, 176
リエントラント トリガ、説明
リモート データベース
リリース ノート xxii
関係モデル
選択の順序付け
定義 20
ラベル 176
列の定義域
290
25
ロック モード、TABLE
論理演算子
AND 46
NOT 46
OR 46
= (等しい)
210
透過性 228
ロール
定義 6
デフォルト 7
ログ スライス、説明 223
ログなし表 223
ロケール xii
ロック
意図ロック 298
および並行性 227
キーワード WAIT 300
行とキーのロック 286
更新ロック 296
異なるロック タイプの動作 297
時間制限 300
整合性 280
説明 282
デッドロック 301
トランザクションの終わり 302
ロック モードの設定 299
ロックされる行数 293
ロックの継続期間 289
IBM Informix SQL ガイド: チュートリアル
290
286
47
論理ログ
およびバックアップ
説明
284
286, 287
UPDATE カーソル
86
列番号、使用 34
レプリケーション
データの 227
430
289
ページ ロック
ロック範囲 283
DELETE で 266
391
10
行 (ROW) 型、定義
降順 27
説明 10
288
スマート ラージ オブジェクト
増進可能 283
データベース ロック
排他 283
表ロック 284
231
リレーショナル データベース、説明 8
ループ、RAISE EXCEPTION を使用した終了
列
コアース インデックス ロック
増進可能なロック
406
286
283
225
222
[ワ行]
ワイルドカード、単一文字の使用
ワイルドカード文字
アスタリスク 25
プロテクト 53
和集合演算 171
48
[数字]
10 進数 (DECIMAL) 型、SQLWARN でシグナル通知さ
れる 243
10.0 の機能 xiv
10.0 の機能、概要 xiv
A
ALTER INDEX 文、ロック表
AND 論理演算子 46
ANSI
排他レベル 295
285
ANSI (続き)
SQL バージョン
ANSI 標準
CREATE PROCEDURE 文 (続き)
CREATE PROCEDURE FROM 内
WITH LISTING IN 節 384
13
Informix 構文の拡張
CREATE TABLE 文
14
ANSI 標準準拠データベース
階層
で必要とされない FOR UPDATE 276
SQLWARN でのシグナル通知 243
AVG 関数、集計関数として
321
102
94
カスケード削除
型付き表 84
213
行 (ROW) 型列
85
コレクション (COLLECTION) 型 91
主キー 212
スマート ラージ オブジェクト列 117
B
BEGIN WORK 文
マルチセット (MULTISET) 型列
ロック モードの設定 287
LOCK MODE 節 286
224
C
ON DELETE CASCADE 節
CALL 文、SPL 関数内 375
CARDINALITY 関数 116
CASE 式
使用 63
説明 63
UPDATE 文内 205
CLOSE DATABASE 文、データベース ロックへの効果
284
COMMIT WORK 文
カーソルのクローズ 302
ロック解除 289, 302
SQLCODE の設定 267
COUNT 関数
および GROUP BY 140
削除する行のカウント 187
集計関数として 101
副問合せでの使用 189
DISTINCT を使用 102
CREATE DATABASE 文
共有ロックの設定 284
の後の SQLWARN 243
CREATE FUNCTION FROM 文、埋込み言語で 321
CREATE FUNCTION 文
使用 309
CREATE FUNCTION FROM 文内 321
WITH LISTING IN 節 384
CREATE FUNCTION、RETURN 節 314
CREATE INDEX 文、ロック表 285
CREATE PROCEDURE FROM 文、埋込み言語で 321
CREATE PROCEDURE 文
使用 309
CREATE TRIGGER 文
CURRENT 関数
使用 107
列の値の比較
168
185
399
106
D
DATABASE 文
の後の SQLWARN
243
ロック 284
DataBlade モジュール
12
DATE 関数、変換関数として 112
DAY 関数 107
DBDATE 環境変数 191
DBINFO 関数、SELECT 文内 129
DBSERVERALIAS、TCP/IP 接続 234
DBSERVERNAME 関数、SELECT 文内 128
DBSERVERNAME、TCP/IP 接続 234
dbspace、DBINFO 関数が戻す名前 129
DB-Access
を使用したデータベースの作成 261
DECLARE CURSOR 文 270
DECLARE 文
キーワード SCROLL 253
説明 250
FOR INSERT 節 270
FOR UPDATE 275
WITH HOLD 節 303
DECODE 関数 130
DECRYPT_BINARY 関数 135
DECRYPT_CHAR 関数 135
索引
431
DEF_TABLES_LOCKMODE 構成パラメータ
288
ESQL (続き)
DELETE 文
埋込み 238, 266
カーソルの使用
プリプロセッサ 237
ホスト変数 238, 240
ホスト変数を区切る
268
239
行 (ROW) 型 188
DELETE 文
行数 241
行のカウント
SQL 通信領域 (SQLCA)
SQLCODE 240
266
コレクション (COLLECTION) 型 188
作成 189
使用 266
上位表に対して
説明
SQLERRD フィールド
キーワード DBA、影響
185
選択された行 187
重複行 273
特定の行 187
ロック モード 297
WHERE 節の制約事項
261
383
ルーチンが参照するオブジェクト
EXTEND 関数
式での使用 111
F
189
318
DROP INDEX 文、ロック表 285
Dynamic Server、オブジェクト リレーショナル データ
ベース 11
E
ENCRYPT_AES 関数 134
ENCRYPT_TDES 関数 134
en_us.8859-1 ロケール xii
ESQL
エラー処理 248
カーソルからの行の取出し
カーソルの使用 249, 257
概要 236, 264, 265
スクロール カーソル 252
静的埋込み 238
単一行の選択 245
での INSERT 270
での UPDATE 275
動的埋込み 238, 257
標識変数 247
382
日付 (DATE) 型、日時 (DATETIME) 型、および時
間隔 (INTERVAL) 型 106
267
XPS での結合の使用 189
DOCUMENT 節、SPL ルーチンでの使用
432
241
EXECUTE PROCEDURE 文
SPL で 373
Execute アクセス権
185, 186
267
とのトランザクション
表のすべての行 185
副問合せの使用 189
240
EXECUTE FUNCTION 文
SPL で 373
EXECUTE IMMEDIATE 文、説明
188
処理 259
すべての行の削除
整合性がある削除
266
251
IBM Informix SQL ガイド: チュートリアル
FETCH 文 252
キーワード ABSOLUTE
253
順 252
順カーソル 254
説明 251
FIRST 節
使用 56
説明 55
ユニオン問合せ内 178
ORDER BY 節との併用 57
FLUSH 文
挿入された行のカウント 271
バッファへの行の書込み 271
ロールバック 272
FOREACH 文 337
FREE 文、PREPARE 文で処理された文の解放
G
GET DIAGNOSTICS 文 245
GETHINT 関数 135
GLS
参照: 広域言語サポート
260
GRANT 文、埋込み SQL で 261, 263
INSTEAD OF トリガ
GROUP BY 節
説明 138
INTO 節
GROUP BY 節と HAVING 節の使用
406
252
ISAM エラー コード 241
ISO 8859-1 コード セット xii, 36
138
ISOLATION_LOCKS 構成パラメータ
H
L
HAVING 節、説明 138
HEX 関数、式での使用 129
HOLD カーソル、定義
293
LENGTH 関数 100
可変長文字 (VARCHAR) 型
302
126
式での使用 125
テキスト (TEXT) 型またはバイト (BYTE) 型文字列
I
IF 文、SPL 内 340
IFX_DEF_TABLE_LOCKMODE 環境変数
126
LET 文 333
287
IN 関係演算子 159
Informix Dynamic Server マニュアル セット
INFORMIXDIR/bin ディレクトリ xiii
INITCAP 関数、文字列操作関数として
INSERT カーソル
使用
120
272
定義 270
INSERT 文
埋込み 270
およびデータの終わり 274
行 (ROW) 型で 193
行数 241
コレクション (COLLECTION) 型列 195
コレクション内の NULL 値 196
シリアル値 191
スマート ラージ オブジェクト 197
説明 190
選択された列 191
挿入
コレクション 195
上位表へ 195
複数行 198
挿入された行のカウント 271
名前付き行型 193
名前なし行型 194
の定数データ 272
ロック モード 297
SELECT の制約事項 198
SELECT 文 198
SELECT 文で 198
VALUES 節 190
xxv
LIKE 節
SPL 関数内 328
LOCK TABLE 文、明示的に表をロック
284
LOWER 関数、文字列操作関数として 118
LPAD 関数、文字列操作関数として 124
M
MATCHES 関係演算子
ロケールの影響 52
WHERE 節内 48
MAX 関数、集計関数として
103
MDY 関数、時刻関数として 106
MIN 関数、集計関数として 103
MODE ANSI キーワード、トランザクションの指定
224
MONTH 関数
使用、時刻関数
MONTH 108
MONTH 関数、時刻関数として 106
N
NOT 論理演算子 46
NULL 値
テスト 45
論理演算子 46
ESQL 内での検出 247
NVL 関数 131
索引
433
SELECT 文 (続き)
O
ON DELETE CASCADE オプション
ON EXCEPTION 文
エラーのトラッピング
制御範囲
212
関数
388
ユーザが生成するエラー
100, 129
100
キーワード ALL 160
キーワード ANY 161
391
onload ユーティリティ 226
onunload ユーティリティ 226
OPEN 文
249, 250
149
関数の使用
389
キーワード DISTINCT
31
キーワード EXISTS 164
基本的な概念 20
行 (ROW) 型の選択 84
251
OR 関係演算子
OR 論理演算子
カーソル
外部結合
43
46
結合 68
結合された表
高度 138
P
79
コレクション (COLLECTION) 型導出表
PREPARE 文
説明 258
複数の SQL 文 259
SQLERRD のエラー戻り
PROCEDURE 型変数
PUT 文
状態コード 271
241
サブ文字列の選択 35
自然結合 72
集計関数 100, 112
329
挿入された行のカウント
集合演算
使用
271
データの挿入 270
の定数データ 272
戻されたデータのバッファへの送信
結合
射影
271
R
RAISE EXCEPTION 文 388
RANGE 関数、集計関数として 104
REPLACE 関数、文字列操作関数として 120
REVOKE 文、埋込み SQL で 261, 263
ROLLBACK WORK 文
カーソルのクローズ 302
ロック解除 289, 302
SQLCODE の設定 267
RPAD 関数、文字列操作関数として 124
S
SELECT の降順 27
SELECT の昇順 27
SELECT 文
アクティブ セット
埋込み 245, 248
434
169
コレクション (COLLECTION) 型の副問合せ
コレクションの式 167
コレクションへのアクセス 84, 90
38, 245
IBM Informix SQL ガイド: チュートリアル
171
23
22
選択 21
スタンドアロン 404
スマート ラージ オブジェクト関数
説明 19
セルフ結合 145
選択式 58
選択リスト 22, 25
単一行 38, 245
単一表 24, 129
単純 18
データの終わり戻りコード 274
トリガ アクションの実行 404
の日付関数 106
排他レベル 290
表示ラベル 61
フォーム 19
複合問合せ 171
複数表 66
副問合せ 157
別名 76
ESQL を使用した INTO 節 245
116
168
SELECT 文 (続き)
FIRST 節 55
GROUP BY 節
HAVING 節
SPL ルーチン (続き)
構文エラー 384
コメント 319
139
固有名
142
INTO TEMP 節
312
コレクション (COLLECTION) 型
79
ORDER BY 節 26
UNION 演算子 171
コンパイラ メッセージ
削除 321
UPDATE 文内
作成
200, 201
SET COLLATION 52
SET ISOLATION 文
および SET TRANSACTION
使用 291
SET LOCK MODE 文、説明
SET TRANSACTION 文
および SET ISOLATION
309
システム カタログ エントリ
実行 373
使用 308
291
データの引き渡し
定義 307
デバッグ 386
299
動的ルーチン名指定
291
385
402
377
使用 291
SET キーワード、UPDATE 文内 200
SET 節、UPDATE 文 202
トリガ アクションとして 402
のテキスト 385
非トリガ列を更新する 403
SITENAME 関数、SELECT 文内 128
SPL
カーソルの使用 337
ピリオド表記 348
へのコメントの追加
変数の範囲 324
トリガ アクションのトレース
パラメータ リスト 312
318
戻りの型 314
ループの終了 344
407
プログラム変数 238
文ブロック 336
変数への値の代入 333, 336
FOREACH ループ 337
LET 文 333
RETURN 節 314
SQL との関係 307, 308
WITH LISTING IN 節 318
SPL 関数
コレクション (COLLECTION) 型データ問合せ
定義 307
動的ルーチン名指定 377
バリアントと非バリアント 316
ラージ オブジェクト変数 325
CALL 文 375
WITH 節 316
SPL ルーチン
アクセス権 379
値の戻り 344
埋込み言語で 321
エラー検出 384
概要 307
行 (ROW) 型データ 348
349
384
例 320
例外 388, 392
358
CONTINUE 文 344
EXECUTE PROCEDURE 403
EXIT 文 344
FOR ループ 342
IF..ELIF..ELSE 構造 340
SELECT 文内 132
SPL 関数での名前の混同 331
SQL 式 336
SYSPROCPLAN 309
TRACE 文 407
WHILE ループ 342
XPS で 308
SQL
アプリケーション プログラム インターフェイス
(API) 237
アプリケーション言語 237
エラー処理 248
カーソル 249
静的埋込み 238
説明 12
対話型使用 14
索引
435
SQL (続き)
superstores_demo データベース
動的文 238
ヒストリー 13
標準化
SPL ルーチン
13
ANSI 標準に準拠した文
14
xx
267
TRACE 文
出力 408
SPL ルーチンのデバッグ 386
TRUNCATE TABLE 文 186
TRUNCATE TABLE を使用した削除
251
186
272
カーソルのオープン後 251
シグナル通知されるデータの終わり
説明 240
U
248
DELETE 文で設定 266
PUT 文で設定 271
SELECT のみのデータの終わり
SQLERRD 配列
UNION 演算子、表示ラベル
UPDATE カーソル 296
UPDATE カーソル、定義
UPDATE 文
274
行のカウント 274
削除された行のカウント 266
説明 241
挿入された行のカウント 271
命名構文 240
SQLERRM 文字列 244
SQLSTATE 値 245
SQLSTATE 変数
カーソルを使用して 251
ANSI 標準準拠でないデータベースで 248
SQLSTATE、問題のある値 248
SQLWARN 配列
説明 242
命名構文 240
PREPARE 文で 259
START VIOLATIONS TABLE 218
STDEV 関数、集計関数として 105
stores_demo データベース xiii
SUBSTR 関数、文字列操作関数として 123
SUBSTRING 関数、文字列操作関数として 121
SUM 関数、集計関数として 103
436
T
TO_CHAR 関数、変換関数として 113
TO_DATE 関数、変換関数として 114
トランザクションの終わりに変更
SQL 文キャッシュ 303
SQLCODE
負の値 248
SQLCODE フィールド
および FLUSH 操作
309
TOC (目次) ノート xxii
TODAY 関数、定数式内 127, 191
SQL 通信領域 (SQLCA)
行の挿入 271
説明 240
データの終わり
385
13
Informix SQL と ANSI SQL 13
Informix 構文と ANSI 標準の相違
SQL コード
xiii
sysprocbody、システム カタログ表
SYSPROCPLAN
IBM Informix SQL ガイド: チュートリアル
176
275
一様値を使用 201
埋込み 275
およびデータの終わり 274
行 (ROW) 型で 203
行数 241
結合を使用した列の更新 206
コレクション (COLLECTION) 型 204
上位表で 204
障害 221
処理 259
スマート ラージ オブジェクト 206
説明 200
副問合せの制約事項 201
ロック モード 297
SET 節 202
WHERE 節 200
UPPER 関数、文字列操作関数として 119
USER 関数、式内 126
V
VALUES 節
可能な値
190
[特殊文字]
VALUES 節 (続き)
制約事項 191
選択された列 191
INSERT 文内
NULL 値
!=、等しくない、関係演算子
=、等しい、関係演算子
?、疑問符
190
194
VARIANCE 関数、集計関数として
105
40
40, 69
PREPARE 文の位置指定子として
>=、より大か等しい、関係演算子
258
41
W
WEEKDAY 関数
時刻関数として
106, 110
使用 109
WHERE CURRENT OF clause
UPDATE 文内 275
WHERE CURRENT OF 節
DELETE 文内 268
WHERE 節
関係演算子 39
キーワード NOT を使用 42
キーワード OR を使用 43
説明 38
等号関係演算子
内のホスト変数
の日付関数
40
246
110
比較条件 38
ブール (BOOLEAN) 式 46
副問合せ 159
不等号関係演算子 40
文字範囲の選択 54
より小関係演算子 41
ワイルドカード比較 48
DELETE 文内 185
UPDATE 文内 200
WHERE 節でのワイルドカード比較 48
WHERE 節内のキーワード NOT BETWEEN 42
WITH LISTING IN 節、SPL ルーチンでの使用 318
WITH 節、SPL 関数内 316
Y
YEAR 関数
時刻関数として
使用 110
106
索引
437
438
IBM Informix SQL ガイド: チュートリアル
򔻐򗗠򙳰
Printed in Japan
GB88-8673-00
Fly UP