...

Informix Guide to SQL: Tutorial

by user

on
Category: Documents
66

views

Report

Comments

Transcript

Informix Guide to SQL: Tutorial
Informix Guide to SQL:
®
Tutorial
Informix Dynamic Server, Version 7.3
Informix Dynamic Server with Advanced Decision Support and Extended Parallel Options, Version 8.2
Informix Dynamic Server, Developer Edition, Version 7.3
Informix Dynamic Server, Workgroup Edition, Version 7.3
September 1998
Part No. 000-4366-8
Informix のソフトウェアおよびユーザ・マニュアルは「現状のまま」提供され、商品性の黙示的な保証およ
び特定の目的への適合性の黙示的な保証など、明示的か黙示的かを問わず、いかなる種類の保証も提供され
ません。Informix のソフトウェアおよびユーザマニュアルの品質と性能についてのリスクは、すべて、お客
様の負担です。Informix のソフトウェアおよびユーザ・マニュアルに欠陥があった場合には、すべての必要
なサービス、修理または修正のための費用は、すべて、(Informix または Informix の正規取扱店ではなく)
お客様の負担となります。いかなる場合においても、Informix は Informix または Informix の正規代理店そう
した損害の可能性を知らされていた場合であっても、Informix のソフトウェアまたはユーザ・マニュアルの
使用または使用不能から生じた、利益の喪失、節約の喪失あるいは他の偶発的または結果的な損害など、い
かなる損害についても責任を負わず、また第三者からのいかなる請求についても責任を負いません。加え
て、Informix は、厳格責任あるいは Informix の過失に基づく請求で Informix のソフトウェアまたはユーザ・
マニュアルの使用または使用不能から生じた一切の請求についても責任を負いません。管轄地によっては、
黙示的な保証の排除を認めていない管轄地もあり、その場合には上記の排除の全部または一部が適用されな
いこともあります。この保証は、お客様に特定の法的な権利を付与するものですが、管轄地によって異な
る、その他の権利がお客様に認められることもあります。
すべての権利は Informix に保留されます。本書についての著作権で保護される本書のいかなる部分も、グ
ラフィック、電子的方法、あるいは、コピー機、記録装置、テープ、情報記憶媒体、検索システムなどの機
械的方法など、形態あるいは方法を問わず、発行元の許可を得ないで、複製または使用することはできませ
ん。
発行者: INFORMIX Press
Informix Software, Inc.
4100 Bohannon Drive
Menlo Park, CA 94025-1032
Answers OnLine、INFORMIX、Informix、Illustra、C-ISAH、DataBlade、Dynamic Server、Gateway および
NewEra は Informix Software, Inc. の登録商標です。
その他の名前やマークはすべて、それぞれの所有者の登録商標または商標である可能性があります。
本書記載の製品またはサービスには Informix 以外の会社が提供しているものがあります。これらの製品や
サービスについては、適切な会社の商標またはサービスマークが表示してありますので、これらの製品や
サービスについてご質問がある場合には、該当する会社に直接ご連絡ください。
権利制限
Informix のソフトウェアおよび付随する資料は、制限された権利のもとに提供されます。政府による使用、
複製、または開示については、DFARS 252.227-7013 の Rights in Technical Data and Computer Software Clause
( 技術データおよびコンピュータ・ソフトウェアについての権利)に関するサブパラグラフ (c)(1)(ii) または
48CFR52.227-19 の Commercial Computer Software-Restricted Rights( 商用コンピュータ・ソフトウェア - 制限さ
れた権利)に関するサブパラグラフ (c)(1) および (2) の適用がある部分(および政府契約に規定されたその
他の適用のライセンス規定)に限定された制限が適用されます。
Copyright © 1981-1998 by Informix Software, Inc.
ii
Informix Guide to SQL: Tutorial
目次
目次
序
このマニュアルについて . . . . .
対象ユーザ . . . . . . .
ソフトウェアの要件 . . . . .
使用するロケール . . . . .
デモンストレーションデータベース
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
序3
序3
序4
序4
序5
序5
序6
序6
新機能 . . . . . . . .
バージョン 7.3 での新機能 .
バージョン 8.2 での新機能 .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. .
. .
. .
表記上のきまり . . .
文字の表記 . . .
アイコンの表記 . .
サンプルコードの表記
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
追加のマニュアル . . . . . . . . . . . .
オンライン マニュアル . . . . . . . . .
ペーパーマニュアル . . . . . . . . . .
エラーメッセージファイル . . . . . . . .
ドキュメントノート、リリースノート、マシンノート
参考文献 . . . . . . . . . . . . .
業界標準への準拠 . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
序7
序8
序9
序 11
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
序 12
序 12
序 13
序 13
序 13
序 15
序 15
. . .
. . .
. . .
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
セクション I 基本 SQL の使用
第1章
データベースのコンセプト
データモデルによる説明
データの格納 . .
データへの問合せ
データの変更 . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1-4
1-6
1-6
1-9
複数のユーザによる同時利用とセキュリティ .
データベースの利用制御 . . . . . .
集中管理 . . . . . . . . . . .
. . .
. . .
. . .
. . .
. . .
. . .
1-9
1-9
1-10
重要なデータベース用語 .
リレーショナル モデル.
表. . . . . . .
列. . . . . . .
行. . . . . . .
表に対する操作 . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
構造化問合せ言語 (SQL) . . . .
標準 SQL 文 . . . . . .
Informix SQL と ANSI 標準 SQL
ANSI 標準準拠のデータベース
GLS データベース . . . .
第2章
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1-11
1-11
1-12
1-13
1-13
1-13
. .
.
. .
.
.
.
.
.
.
.
.
.
.
.
.
. . . . .
. . . .
. . . . .
. . . .
. . . .
.
.
.
.
.
.
.
.
.
.
. .
.
. .
.
.
1-15
1-15
1-16
1-17
1-17
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
.
1-17
1-18
1-18
1-18
1-19
.
.
.
.
.
まとめ .
. . .
. . .
. . .
. . .
1-19
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2-4
2-5
2-10
2-11
一つの表に対する SELECT 文 . . . . . . .
すべての列と行の選択 . . . . . . . .
特定の列の抽出 . . . . . . . . . .
WHERE 節の使用方法 . . . . . . . .
比較条件の作成 . . . . . . . . . .
特定の行を選択するための FIRST 節の使用. .
式と導出値 . . . . . . . . . . .
SELECT 文での関数の使用 . . . . . .
SELECT 文でのストアドプロシジャの使用 . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
2-11
2-12
2-18
2-28
2-29
2-46
2-49
2-57
2-87
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2-89
2-89
2-91
2-97
. . .
2-102
. . .
.
.
.
. . . .
. . . .
. . . .
. . . . . .
. . . . .
.
.
.
.
.
.
データベース ソフトウェア
アプリケーション . .
データベース サーバ .
対話型 SQL . . . . .
一般的なプログラミング
. . .
.
.
.
.
.
.
.
.
.
.
.
. .
. .
. .
. . .
. .
簡単な SELECT 文の作成
SELECT 文の基本的な事項 .
基本概念 . . . . .
SELECT 文の形式 . .
特殊なデータ型 . . .
複数表 SELECT 文 .
デカルト積の作成
結合の作成 . .
簡単な問合せ方法
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
.
.
.
.
現行データベース以外のデータベースからの表の検索 . .
iv
Informix Guide to SQL: Tutorial
まとめ . . .
第3章
第4章
. . .
. . .
. . .
. . .
. . .
. 2-103
GROUP BY 節と HAVING 節の使用方法 . .
GROUP BY 節の使用方法 . . . . .
HAVING 節の使用方法 . . . . . .
. . .
. . .
. . .
. . .
. . .
. . .
.
.
.
3-4
3-4
3-8
高度な結合の作成 . . .
セルフ結合. . . .
外部結合 . . . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
.
.
.
3-10
3-11
3-20
SELECT 文中の副問合せ文 . . .
キーワード ALL の使用方法 . .
キーワード ANY の使用方法 .
値を一つだけ返す副問合せ文 .
相関副問合せ文 . . . . .
キーワード EXISTS の使用方法 .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3-30
3-31
3-32
3-33
3-35
3-36
集合演算 . .
和の集合演算
積の集合演算
差の集合演算
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3-39
3-40
3-48
3-50
まとめ . . .
. . .
. . .
. . .
. . .
. . .
.
3-52
データを更新する文 . .
. . .
. . .
. . .
. . .
.
4-3
.
.
.
.
.
高度な SELECT 文の作成
.
.
.
.
.
.
.
.
. . .
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
データの更新
行の削除 . . . . . . . . . . .
表のすべての行の削除 . . . . . .
削除対象の行数がわかっている場合の削除
削除対象の行数が不明の場合の削除 . .
複雑な削除条件 . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4-4
4-4
4-5
4-5
4-6
行の挿入 . . . . . . . . . . . .
単一行の挿入 . . . . . . . . . .
複数の行の挿入と式の使用方法. . . . .
INSERT 文に SELECT 文を使用する場合の制約
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4-7
4-7
4-10
4-11
行の更新 . . . . . . .
更新対象の行の選択 . . .
一様値を使用する更新 . .
更新の制限. . . . . .
選択値を使用する更新 . .
CASE 式を使用する列の更新
結合を使用する列の更新. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4-12
4-13
4-14
4-15
4-15
4-16
4-17
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
目次
v
第5章
データベースでのアクセス権 . . .
データベースレベルのアクセス権
表レベルのアクセス権 . . . .
表アクセス権の表示 . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4-17
4-18
4-18
4-19
データの整合性 . . . . . . .
実体整合性 . . . . . . .
意味整合性 . . . . . . .
参照整合性 . . . . . . .
オブジェクトモードと違反の検出
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4-20
4-21
4-21
4-22
4-26
中断された更新 . . . . .
トランザクション . . .
トランザクションログ機能
トランザクションの指定 .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4-28
4-30
4-30
4-32
Informix データベースサーバを使用したバックアップとログ . . .
4-33
並列度とロック .
. . .
4-34
データレプリケーション . . . . . . . . . . . . .
Informix データベースサーバによるデータレプリケーション .
4-35
4-36
まとめ .
4-37
. . .
. . .
. . .
.
.
.
.
. . .
. . .
. . .
. . .
. . .
. . .
. . .
SQL を使用したプログラミング
プログラム中の SQL . . . . .
SQL API 中の SQL . . . .
アプリケーション言語の SQL
静的 SQL 文 . . . . . .
動的 SQL 文 . . . . . .
プログラム変数とホスト変数 .
. .
. .
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . .
. . . . .
. . . . .
. . . .
. . . .
. . . .
.
.
.
.
.
.
.
.
.
.
.
.
. .
. .
. .
.
.
.
5-4
5-4
5-5
5-5
5-5
5-6
データベースサーバの呼出し
SQL 通信領域 . . .
SQLCODE フィールド .
SQLERRD 配列 . . .
SQLWARN 配列. . .
SQLERRM 文字配列 .
SQLSTATE 値 . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5-8
5-8
5-9
5-10
5-11
5-13
5-13
単一行の抽出 . . . .
データ型変換 . .
NULL データの処理
エラーの処理 . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5-14
5-15
5-16
5-17
. . .
. . .
5-20
5-20
.
.
.
.
複数行の抽出 . . . . .
カーソルの宣言 . . .
vi
.
.
.
.
Informix Guide to SQL: Tutorial
. . .
. . .
. . .
. . .
. . .
. . .
カーソルのオープン . . .
行の取出し. . . . . .
カーソルによる取出し . .
カーソルのアクティブセット
カーソルの使用方法 : 部品爆発
第6章
第7章
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
動的 SQL. . . . . . . . . . . . . . . . . .
文の PREPARE 文による処理 . . . . . . .
PREPARE 文で処理された SQL 文の実行 . . . .
動的なホスト変数. . . . . . . . . . .
PREPARE 文で処理された文が所有する記憶域の解放
実行の高速化 . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
. . .
. .
. .
. .
. .
. .
プログラム中のデータ定義文
5-21
5-22
5-23
5-24
5-27
5-29
5-30
5-31
5-32
5-33
5-33
. .
. . .
. . .
. . .
.
5-34
GRANT 文と REVOKE 文の埋込み .
. . .
. . .
. . .
.
5-34
まとめ . . .
. . .
. . .
. . .
.
5-37
. . .
. . .
SQL プログラムによるデータの更新
DELETE 文の使用方法 . . . .
直接的な削除 . . . . . .
カーソルを使用した削除. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
.
.
.
6-3
6-4
6-7
INSERT カーソルの使用方法 . . .
INSERT カーソルの使用方法 .
定数だけで構成される行の挿入.
挿入の例 . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6-9
6-9
6-12
6-12
UPDATE 文の使用方法 . . . .
UPDATE カーソルの使用方法 .
表の仕上げ. . . . . . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
.
.
.
6-15
6-15
6-17
まとめ . . .
. . .
. . .
. . .
.
6-18
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
マルチユーザ環境のためのプログラミング
並列度と性能 .
. . .
. . .
. . .
. . .
. . .
.
7-3
ロックと整合性
. . .
. . .
. . .
. . .
. . .
.
7-3
ロックと性能 .
. . .
. . .
. . .
. . .
. . .
.
7-4
並列度に関する問題 . .
. . .
. . .
. . .
. . .
.
7-4
ロックの動作 . . .
ロックの種類 . .
ロック範囲. . .
ロックの継続期間.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7-6
7-7
7-7
7-11
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
目次
vii
データ修正中のロック .
. . .
. . .
. . .
. . .
排他レベルの設定 . . . . . . . . . . . . .
SET TRANSACTION 文の SET ISOLATION 文との比較 .
不確定読込み (ANSI) と単純読込み (INFORMIX) . . . .
確定読込み (ANSI) と確定読込み (INFORMIX) . . . . .
排他レベルのカーソル安定性 (INFORMIX) . . . . . .
繰返し読込み (ANSI)、直列化可能 (ANSI)、および繰返し
読込み (INFORMIX) 排他レベル . . . . .
.
.
.
.
.
.
.
. .
. .
. .
7-11
7-12
7-12
7-14
7-14
7-15
. .
7-17
アクセスモードによるデータ変更の制御 . . .
. . .
. . .
7-18
ロックモードの設定 . . . . .
ロックの解除を待つ . . .
ロックの解除を待たない . .
一定時間ロックの解除を待つ .
デッドロックの処理 . . .
外部デッドロックの処理 . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7-19
7-19
7-19
7-20
7-20
7-21
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
単純な並列度 . .
. . .
. . .
. . .
. . .
. . .
7-21
HOLD カーソル .
. . .
. . .
. . .
. . .
. . .
7-21
まとめ .
. . .
. . .
. . .
. . .
. . .
7-23
ストアド プロシジャと SPL の紹介 . . . .
ストアド プロシジャの機能 . . . . .
SQL とストアド プロシジャの関係 . . .
. . .
. . .
. . .
. . .
. . .
. . .
8-3
8-4
8-4
Dynamic Server with AD and XP Options のストアド プロシジャ動作 .
8-5
. . .
セクション II 高度な SQL の使用
第8章
viii
ストアド プロシジャの作成と使用
ストアド プロシジャの作成と使用 . . . .
プロシジャの作成 . . . . . . . .
プログラム内のプロシジャの作成 . . .
プロシジャのコメント作成とドキュメント化
コンパイル時エラーの診断 . . . . .
コンパイル時警告の確認 . . . . . .
テキストまたはドキュメントの生成 . . .
プロシジャの実行 . . . . . . . .
ストアド プロシジャの動的実行 . . . .
プロシジャのデバッグ . . . . . . .
.
.
.
.
.
.
.
.
.
.
ストアド プロシジャに対するアクセス権 . .
作成に必要なアクセス権 . . . . . .
. . .
. . .
Informix Guide to SQL: Tutorial
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8-6
8-6
8-7
8-8
8-8
8-10
8-11
8-12
8-14
8-14
. . .
. . .
8-17
8-18
実行に必要なアクセス権. . .
アクセス権の取消し . . . .
変数と式 . .
SPL 変数 .
SPL 式 . .
. . .
. . .
. . .
プログラムの流れの制御
分岐 . . . . .
ループ . . . .
関数の処理. . .
.
.
.
.
. . .
. . .
. . .
. . .
. . .
. . .
.
.
8-18
8-20
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
.
.
.
8-20
8-20
8-25
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8-26
8-26
8-27
8-28
. . .
. . .
. . .
. . .
.
.
8-29
8-30
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8-32
8-32
8-33
8-34
.
.
.
.
.
.
.
.
プロシジャとの情報の受渡し . .
結果の返戻. . . . . . .
第9章
. . .
. . .
.
.
.
.
. . .
. . .
例外処理 . . . . . . . . .
エラーのトラップと回復. . . .
ON EXCEPTION 文の制御の有効範囲
ユーザ生成の例外. . . . . .
まとめ . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
. . .
. . .
.
8-36
. . .
. . .
. . .
.
9-3
.
.
.
.
.
.
.
.
.
.
トリガの作成と使用
トリガを使用するタイミング
. .
トリガの作成方法 . . . . . . .
トリガ名の割当て. . . . . .
トリガイベントの指定 . . . .
トリガアクションの定義. . . .
完全な構成の CREATE TRIGGER 文
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
9-4
9-5
9-5
9-6
9-7
トリガアクションの使用方法 . . . . . . . . . .
BEFORE および AFTER トリガアクションの使用方法 . .
FOR EACHROW トリガアクションの使用方法 . . . .
ストアドプロシジャのトリガアクションとしての使用方法.
.
.
.
.
.
.
.
.
9-7
9-7
9-9
9-11
Dynamic Server 用の再入可能トリガ .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
. . .
. . .
.
9-13
トリガアクションのトレース . . . . .
ストアド プロシジャ内の TRACE 文の例 .
TRACE 出力の例 . . . . . . . .
. . .
. . .
. . .
. . .
. . .
. . .
.
.
.
9-13
9-14
9-14
エラーメッセージの生成 . . . .
固定エラーメッセージの適用 .
可変エラーメッセージの生成 .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
.
.
.
9-15
9-15
9-17
まとめ . . .
. . .
. . .
. . .
.
9-18
. . .
. . .
索引
目次
ix
序
序
このマニュアルについて . . . .
対象ユーザ . . . . . . .
ソフトウェアの要件 . . . .
使用するロケール . . . . .
デモンストレーションデータベース
新機能 . . . . . . . .
バージョン 7.3 での新機能 .
バージョン 8.2 での新機能 .
.
.
.
.
.
. . .
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
序3
序3
序4
序4
序5
. . .
. . .
. . .
. .
. .
. .
序5
序6
序6
表記上のきまり . . . . . . . . . . . . .
文字の表記 . . . . . . . . . . . . .
アイコンの表記 . . . . . . . . . . . .
コメントアイコン . . . . . . . . . .
機能、製品、およびプラットフォームのアイコン.
準拠アイコン . . . . . . . . . . .
サンプルコードの表記 . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
序7
序8
序9
序9
序 10
序 11
序 11
追加のマニュアル . . . . . . . . . . . .
オンライン マニュアル . . . . . . . . . .
ペーパーマニュアル . . . . . . . . . .
エラーメッセージファイル . . . . . . . .
ドキュメントノート、リリースノート、マシンノート
参考文献 . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
序 12
序 12
序 13
序 13
序 13
序 15
. .
序 15
業界標準への準拠
. .
. .
. . .
. . .
. . .
. . .
序 2 Informix Guide to SQL: Tutorial
この「序」では、
『Informix Guide to SQL: Tutorial』マニュアルで提供する情報の概
要とそこで使用されている表記の規約について説明します。
このマニュアルについて
このマニュアルでは、構造化問合せ言語 (SQL) の基本的および高度な使用法のほ
か、データベース内のデータのアクセスや操作方法が記述されています。データ操
作言語 (DML) 文や、DML 文で使用するトリガとプロシジャについて説明します。
このマニュアルは、Informix 版の構造化問合せ言語 (SQL) について説明する一連の
マニュアルのうちの 1 冊です。基本的な SQL と高度な SQL の使用法について説明
します。
『Informix Guide to SQL: Syntax』は、SQL のすべての構文とストアド プロシ
ジャ言語 (SPL) について説明しています。
『Informix Guide to SQL: Reference』は、言
語文以外の SQL 機能の参照情報を示しています。
『Informix Guide to Database Design
and Implementation』は、SQL を使用してデータベースの実装と管理を行う方法を示
しています。
対象ユーザ
このマニュアルは次のユーザを対象にしています。
■
データベース アプリケーション プログラマ
■
データベース ユーザ
■
データベース管理者
序 3
ソフトウェアの要件
このマニュアルでは、次の知識を持っていることを想定しています。
■
コンピュータ、オペレーティング システム、およびオペレーティング シ
ステムのユーティリティの操作知識
■
リレーショナル データベースの使用経験またはデータベースの概念につい
ての知識
■
コンピュータ プログラミングの経験
リレーショナル データベース、SQL、またはオペレーティング システムについてあ
まり知識のない場合は、ご使用のデータベース サーバの『Getting Started』に示され
ている参考文献を参照してください。
ソフトウェアの要件
このマニュアルでは、下記の データベースサーバの一つを使用することを前提にし
ています。
■
Informix Dynamic Server バージョン 7.3
■
Informix Dynamic Server with Advanced Decision Support and Extended Parallel
Options バージョン 8.2
■
Informix Dynamic Server Developer Edition バージョン 7.3
■
Informix Dynamic Server Workgroup Edition バージョン 7.3
使用するロケール
Informix 製品では多くの言語、文化、コード セットをサポートしています。文化の
違いに基づくすべての情報は、GLS ( 広域言語サポート ) ロケールという単一環境
にまとめられています。
このマニュアルでは、ユーザがデフォルト ロケールの en_us.8859-1 を使用すると想
定しています。このロケールは、日付、時間、通貨の形式として U.S. English 形式
をサポートします。また、このロケールは、ASCII コード セットと多くの 8 ビット
文字 (é、è、ñ など ) を含む ISO 8859-1 コード セットもサポートします。
データまたは SQL 識別子でデフォルト以外の文字を使用する場合や、文字データに
ついてデフォルト以外の照合規則に従う場合は、デフォルト以外の適切なロケール
を指定する必要があります。
序
4 Informix Guide to SQL: Tutorial
デモンストレーションデータベース
デフォルト以外のロケールや追加の構文など、GLS ロケールの関連事項の指定方法
については、
『Informix Guide to GLS Functionality』を参照してください。
デモンストレーションデータベース
Informix データベースサーバ製品付属の DB-Access ユーティリティには、デモンス
トレーションデータベース stores7 が入っています。これは、架空のスポーツ用品
卸売店に関する情報が収められたデータベースです。サンプルのコマンドファイル
も含まれています。DB-Access に付属の SQL スクリプトを使用すれば、sales_demo
という 2 番目のデータベースを導出することができます。このデータベースは、
データウェアハウスアプリケーションのディメンショナル スキーマを示します。こ
れらのデータベースを構築するためのサンプル コマンド ファイルも含まれていま
す。
Informix のマニュアル内のほとんどの例は、デモンストレーションデータベース
stores7 に基づいています。『Informix Guide to SQL: Reference』に、データベース
stores7 についての詳しい説明と内容の一覧があります。
デモンストレーション データベースをインストールするためのスクリプトが、
UNIX プラットフォームではディレクトリ $INFORMIXDIR/bin に、Windows NT プ
ラットフォームではディレクトリ %INFORMIXDIR%¥bin にあります。stores7 デモ
ンストレーション データベースの構築方法についての詳細は、
『DB-Access User
Manual』を参照してください。sales_demo データベースの構築方法についての詳細
は、
『Informix Guide to Database Design and Implementation』を参照してください。
新機能
次の節では、このマニュアルと関係のあるデータベース サーバの新機能について説
明します。新しい機能の完全なリストは、データベース サーバのリリース ノート
を参照してください。
序 5
バージョン 7.3 での新機能
バージョン 7.3 での新機能
Informix Dynamic Server バージョン 7.3 の新機能は、大きく次の 5 つにまとめること
ができます。
■
信頼性、高可用性、および保守性
■
性能
■
Windows NT 固有の機能
■
アプリケーションの移行
■
管理容易性
いくつかの追加機能は接続、レプリケーション、光サブシステムに影響を与えま
す。
このマニュアルでは次の新機能について説明します。
■
性能 : SELECT 文に対する格納機能で、最初の n 行を選択できます。
■
アプリケーションの移行 :
❑
大文字と小文字を区別する検索のための新機能 (UPPER、LOWER、
INITCAP)
❑
文字列操作のための新機能 (REPLACE、SUBSTR、LPAD、RPAD)
❑
新しい CASE 式
❑
新しい NVL 関数と DECODE 関数
❑
新しい日付変換関数 (TO_CHAR および TO_DATE)
❑
DBINFO 関数用の新しいオプション
❑
CREATE VIEW 文と EXECUTE PROCEDURE 文に対する拡張機能
バージョン 8.2 での新機能
このマニュアルでは、Dynamic Server with AD and XP Options バージョン 8.2 の次の
新機能について説明します。
序
■
広域言語サポート (GLS)
■
新しい集計関数 : STDEV、RANGE、および VARIANCE
6 Informix Guide to SQL: Tutorial
表記上のきまり
■
ALTER TABLE 文と CREATE TABLE 文の LOCK MODE 節の新しい TABLE
ロック モード
■
排他レベルのカーソル安定性のために 1 つ以上の行をロックする指定のサ
ポート
このマニュアルでは、Dynamic Server with AD and XP Options バージョン 8.1 で導入
された次の機能も説明します。
■
特定の問合せ構造化言語 (SQL) 文内の CASE 式
■
複数のコンピュータ間で使用する新しい結合方法
■
ログなし表
■
高性能のロードとアンロードのための外部表
表記上のきまり
ここでは、このマニュアルで使用されている表記上のきまりを説明します。この表
記上のきまりを覚えておくと、このマニュアルや他の Informix マニュアルの内容を
理解しやすくなります。
以下のような表記上のきまりがあります。
■
文字の表記
■
アイコンの表記
■
サンプルコードの表記
序 7
文字の表記
文字の表記
このマニュアルでは、画面表示、コマンド構文などに標準的な表記を使用していま
す。以下のような表記方法を使用しています。
表記方法
意味
KEYWORD
キーワードはセリフフォントの大文字で示します。
computer
ソフトウェアが表示する情報とユーザが入力する情報は、サ
ンセリフフォントで示します。
♦
この記号は、表または項内で機能、製品、プラットフォーム、
または規格特有の情報を示します。
➞
この記号はメニュー項目を示します。たとえば、
「Tools➞Options を選択します」とあったら、Tools メニューの
Options 項目を選択します。
ヒント : テキストを「入力」するように指示されている場合は、キーボードで必要
な情報をタイプした後に Return キーを押してください。テキストを「タイプ」する
ように指示されている場合は、Return キーを押す必要はありません。
序
8 Informix Guide to SQL: Tutorial
アイコンの表記
アイコンの表記
このマニュアルには、いろいろなアイコンを伴ったテキストがあります。ここで
は、これらのアイコンについて説明します。
コメントアイコン
コメントアイコンは、警告、重要、およびヒントを示します。この情報は常に太
字で印刷されています。
アイコン
説明
警告アイコンは、重要な指示、注意、情報を示します。
重要アイコンは、説明されている機能や操作に関する、
重要な情報を示します。
ヒントアイコンは、説明されている機能に関する、追加
情報や省略方法を示します。
序 9
アイコンの表記
機能、製品、およびプラットフォームのアイコン
機能、製品、プラットフォームのアイコンは、機能、製品、またはプラットフォー
ムに特有な情報を示します。
アイコン
AD/XP
E/C
GLS
IDS
UNIX
W/D
WIN NT
説明
Informix Dynamic Server with Advanced Decision Support and
Extended Parallel Options に特有な情報を示します。
INFORMIX-ESQL/C 製品に特有な情報を示します。
Informix 広域言語サポート (GLS) 機能に関連する情報を示
します。
Dynamic Server とその Workgroup Edition や Developer
Edition に特有な情報を示します。ただし、Informix
Dynamic Server だけに適用される (Informix Dynamic
Server、Workgroup Edition と Developer Edition は含まれな
い ) 場合もあります。
UNIX プラットフォームに特有な情報を示します。
Informix Dynamic Server、Workgroup Edition と Developer
Edition に特有な情報を示します。
Windows NT 環境に特有な情報を示します。
これらのアイコンは表の 1 行、1 つ以上のパラグラフ、またはセクション全体に適
用できます。アイコンがセクション タイトルの次に表示されている場合、示された
機能、製品、またはプラットフォームの情報の適用範囲は次のタイトル ( 同じレベ
ルまたはそれ以上のレベル ) までです。 ♦ 記号は、表またはセクションの複数パラ
グラフ内で、機能、製品、またはプラットフォームに特有な情報の終わりを示しま
す。
序
10
Informix Guide to SQL: Tutorial
サンプルコードの表記
準拠アイコン
準拠アイコンは、規格に準拠するための指針を説明した段落を示します。
アイコン
説明
ANSI
ANSI 標準準拠データベースに特有な情報を示します。
+
ANSI SQL-92 エントリレベル標準 SQL に対する Informix
X/O
の拡張機能を示します。
X/Open に準拠した機能を示します。
これらのアイコンは表の 1 行、1 つ以上のパラグラフ、またはセクション全体に適
用されます。アイコンがセクション タイトルの次に表示されている場合、準拠情報
の適用範囲は次のタイトル ( 同じレベルまたはそれ以上のレベル ) までです。 ♦ 記
号は、表またはセクションの複数のパラグラフ内で、準拠情報の終わりを示しま
す。
サンプルコードの表記
このマニュアルには、SQL コードの例が多数示されています。特に明記されている
場合を除き、それらのコードはいずれかの Informix アプリケーション開発ツールに
特有のものではありません。例の中に SQL 文だけが記述してある場合には、セミコ
ロンで区切られていません。つまり、次の例のようなコードになっています。
たとえば、次の例のようなコードになっています。
CONNECT TO stores7
...
DELETE FROM customer
WHERE customer_num = 121
...
COMMIT WORK
DISCONNECT CURRENT
序
11
追加のマニュアル
この SQL コードを特定の製品で使用するには、その製品の構文ルールに合わせる必
要があります。たとえば、DB-Access の問合せ言語オプションを使用する場合には、
複数の文はセミコロンで区切らなければなりません。SQL API を使用する場合に
は、各文の前に EXEC SQL を付け、後ろにはセミコロン ( または他の適切な区切り
文字 ) を付ける必要があります。
ヒント : コード例中のドットは、完全なアプリケーションではさらにコードが追加
されますが、ここでの概念の説明には必要ないため、省略してあることを示してい
ます。
特定のアプリケーション開発支援ツールまたは SQL の API での SQL 文の使用につ
いての詳細は、ご使用の製品のマニュアルを参照してください。
追加のマニュアル
さらに詳しい情報が必要な場合は、次の種類のマニュアルを参照するとよいでしょ
う。
■
オンライン マニュアル
■
ペーパー マニュアル
■
エラー メッセージ ファイル
■
ドキュメント ノート、リリース ノート、マシン ノート
■
参考文献
オンライン マニュアル
Informix 製品には、ペーパーマニュアルを電子化した Informix マニュアルの
Answers OnLine CD が付属しています。このマニュアルはインストールすることも、
CD から直接読み取ることもできます。オンライン マニュアルのインストール、読
取り、印刷についての詳細は、マニュアル Answers OnLine に添付されたインストー
ル説明書を参照してください。
序
12
Informix Guide to SQL: Tutorial
ペーパーマニュアル
ペーパーマニュアル
Informix Dynamic Server マニュアル セットでは、Informix Dynamic Server、その SQL
の実装、およびその関連するアプリケーション プログラミング インターフェイス
について説明しています。さらに、Informix Dynamic Server キットには、各キット
の各種コンポーネントをサポートする各マニュアルが含まれています。
Informix Dynamic Server マニュアル セットの各マニュアルと Informix Dynamic Server
キットのマニュアルの概要については、
『Getting Started with Informix Dynamic
Server』を参照してください。
エラーメッセージファイル
Informix ソフトウェア製品には、すべての Informix エラー メッセージとその対処方
法を示したテキスト ファイルが付属しています。これらのエラー メッセージにつ
いての詳細は、Answers OnLine の『Informix Error Messages』を参照してください。
UNIX
UNIX でエラー メッセージを読むには次のコマンドを使用します。
コマンド
説明
finderr
オンラインでエラー メッセージを表示します。
rofferr
印刷用にエラー メッセージの整形処理を行います。
♦
WIN NT
Windows NT でエラー メッセージを読んだりエラーに対処するには、Informix Find
Error ユーティリティを使用します。このユーティリティを表示するには、タスク
バーから[スタート]➞[プログラム]➞[Informix]を選択します。 ♦
ドキュメントノート、リリースノート、マシンノート
ペーパー マニュアルの他に、このマニュアルの内容を補足するオンライン ファイ
ルがあります。これらのオンライン ファイルについて次の各セクションで説明しま
す。データベース サーバを使用する前に、これらのファイルに目を通してくださ
い。アイコンと性能の問題について重要な情報が示されています。
序
13
ドキュメントノート、リリースノート、マシンノート
UNIX
UNIX プラットフォームでは、ディレクトリ $INFORMIXDIR/release/en_us/0333 に次
のオンライン ファイルがあります。
オンライン
ファイル
目的
SQLTDOC_x.y
このマニュアルのドキュメント ノートでは、このマニュアル
に示されていない機能や、マニュアルの発行後に変更された
機能について説明しています。ファイル名の x.y をデータベー
ス サーバのバージョン番号に置き換えると、このマニュアル
のドキュメント ノート ファイルの名前になります。
SERVERS_x.y
リリース ノート ファイルでは、以前のバージョンの Informix
製品と異なる機能と、これらの機能が現在の製品に与える影
響について説明します。このファイルには、報告されている
問題とその対処法も示されています。ファイル名の x.y をデー
タベース サーバのバージョン番号に置き換えると、リリース
ノート ファイルの名前になります。
IDS_x.y
マシン ノート ファイルでは、ユーザのコンピュータで
Informix 製品を使用したり構成するのに必要な特別な処置につ
いて説明します。マシン ノートには、説明されている製品の
名前がついています。ファイル名の x.y をデータベース サーバ
のバージョン番号に置き換えると、マシン ノート ファイルの
名前になります。
♦
WIN NT
次の項目は Informix フォルダに表示されます。このフォルダを表示するには、タス
ク バーで[スタート]➞[プログラム]➞[Informix]を選択します。
項目
説明
ドキュメント ノート
この項目には、マニュアルの訂正事項、マニュアルで
説明されていない機能やマニュアルの発行後に変更さ
れた機能について情報が示されています。
リリース ノート
この項目は、以前のバージョンの Informix 製品と異な
る機能と、これらの機能が現在の製品に与える影響に
ついて説明します。このファイルには、報告されてい
る問題とその対処法も示されています。
マシン ノートは Windows NT プラットフォームには適用されません。 ♦
序
14
Informix Guide to SQL: Tutorial
参考文献
参考文献
次の資料では、このマニュアルで示されているトピックについてさらに詳しく説明
されています。データベース サーバとオペレーティング システム プラットフォー
ムの基礎について知りたいときは、
『Getting Started』に記載されている参考文献を
参照してください。
■
『A Guide to the SQL Standard』C.J.Date および H.Darwen 著 (Addison-Wesley
Publishing、1993 年 )
■
『Understaiding the New SQL: A Complete Guide』J.Melton および A.Simon 著
(Morgan Kaufmann Publishers、1993 年 )
■
『Using SQL』J.Groff および P.Weinberg 著 (Osborne McGraw-Hill、1990 年 )
業界標準への準拠
ANSI( 米国規格協会 ) は SQL に関する業界標準を定めています。Informix の SQL
ベースの製品は、SQL-92 エントリレベル (ANSI X3.135-1992) に完全準拠しており、
この SQL-92 は ISO 9075:1992 と全く同じものです。また、Informix データベース
サーバの多数の機能も、SQL-92 の暫定レベルおよび X/Open SQL CAE ( 共通アプリ
ケーション環境 ) 標準に準拠しています。
序
15
セクション I
基本 SQL の使用
第1章
データベースのコンセプト
データモデルによる説明 . . . . . . . . . . . . . . . .
データの格納 . . . . . . . . . . . . . . . . . .
データへの問合せ . . . . . . . . . . . . . . . . .
データの変更 . . . . . . . . . . . . . . . . . .
1-4
1-6
1-6
1-9
複数のユーザによる同時利用とセキュリティ . . . . . . . . . .
データベースの利用制御 . . . . . . . . . . . . . . .
集中管理 . . . . . . . . . . . . . . . . . . . .
1-9
1-9
1-10
重要なデータベース用語 .
リレーショナル モデル .
表 . . . . . . .
列 . . . . . . .
行 . . . . . . .
表に対する操作 . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
構造化問合せ言語 (SQL) . . . .
標準 SQL 文 . . . . . .
Informix SQL と ANSI 標準 SQL
ANSI 標準準拠のデータベース
GLS データベース . . . .
.
.
.
.
.
.
.
.
.
.
. .
. .
. . .
. .
. .
. . .
. . .
. . .
. . .
. . .
.
.
.
.
.
データベース ソフトウェア.
アプリケーション . .
データベース サーバ .
対話型 SQL . . . . .
一般的なプログラミング
まとめ . . .
. . .
.
.
.
.
.
.
. .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1-11
1-11
1-12
1-13
1-13
1-13
. .
.
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
.
. .
.
.
1-15
1-15
1-16
1-17
1-17
. . . . . .
. . . . . .
. . . . . .
. . . . . . . .
. . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1-17
1-18
1-18
1-18
1-19
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. .
.
. .
1-19
1-2
Informix Guide to SQL: Tutorial
本書は、データベースと Informix ソフトウェアを使ってデータベースを処理する方
法が書かれたものです。このマニュアルを読むときは、データベースの基本的な性
質に留意していてください。
■
データベースの構成要素にはデータだけではなく、
データのプラン ( または
モデル ) も含まれます。
■
データベースは、多くのユーザが同時に使用する共通資源です。
データベースを実際に操作するときは SELECT 文を使用します (SELECT 文につい
ては、第 2 章「簡単な SELECT 文の作成」を参照してください )。データベースに
ついて多少の知識があり、すぐに使用したいときは、第 2 章に進んでください。
この章では、次の項目に重点を置いて、データベースの基本概念と、マニュアル全
体で使用される用語について説明します。
■
データ モデルによって生じたデータベースとファイルの違い
■
多くのユーザが共通資源としてデータベースを使用する場合の問題点
■
データベースの構成要素を表す用語
■
データベースの作成と修正、データベースに対する問合せのための言語
■
データベースを管理するソフトウェアの主要部分と各部分の働き
データベースのコンセプト
1-3
データモデルによる説明
データモデルによる説明
データベースに収集される情報とファイルに収集される情報の基本的な違いは、
データの編成方法にあります。フラットファイルは物理的に編成されます。つま
り、ある項目は他の項目の前か後といった関係しかありません。しかし、データ
ベースの内容はデータモデルにしたがって編成されます。データモデルはプランま
たは地図のようなもので、データの単位を定義して、それぞれの単位と他の単位と
の関係を指定します。
たとえば、数字はファイルにもデータベースにも入れることができます。ファイル
での数字は、ファイル内のある場所に置かれる単なる数字にすぎません。これに対
して、データベースでの数字は、データモデルによって割り当てられた特定の役割
を持っています。その数字が、顧客が注文した品目の一つとして販売される製品の
価格である場合もあります。このような価格、製品、品目、注文、顧客などのコン
ポーネントも、それぞれデータモデルによって指定された役割を持っています。図
1-1 のデータモデルの説明を参照してください。
1-4
Informix Guide to SQL: Tutorial
データモデルによる説明
図 1-1
データモデル使用の利点
1015 06/27/94 1 case baseball gloves $450.0
1014 06/25/94 1 case football
$960.00
1013 06/22/94 1 each tennis racquet $19.80
1012 06/18/94 1 case volleyball
1011 06/18/94 5 each tennis racquet
1010 06/17/94 1 case tennis ball
$ 840.0
$99.00
$36.00
注文
注文
1003
05/22/94
注文
1001
05/20/94
項目
tennis
racquet
$19.80
項目
2
volleyball
nets
顧客
Anthony
Higgins
注文
1011
06/18/94
注文
1013
06/22/94
項目
1case
tennis
ball
データモデルはデータベースを作成するときに設計します。個々のデータは、この
モデルで設計した計画にしたがって挿入されます。データモデルの代わりにスキー
マということばが使われることもあります。
データベースのコンセプト
1-5
データの格納
データの格納
データベースには、データベースの編成方法も格納されます。これも、データベー
スがファイルと異なる点です。
ファイルは複雑な内部構造を持っていますが、その構造の定義はファイル内ではな
く、ファイルを作成したり使用したりするプログラムの内部に格納されます。たと
えば、ワープロが使用する文書ファイルは、文書のフォーマットを記述している非
常に詳細な構造を持つことがあります。しかし、この構造はファイルではなくプロ
グラム内で定義されているため、文書ファイルを作成したワープロのみがファイル
の内容を解読することができます。
データモデルの場合はその記述先となるデータベースに格納されます。したがって
データベース内に構造が定義されているので、データベースを使用するすべてのプ
ログラムでの利用が可能です。データモデルはデータの項目名だけでなくデータ型
も定義するため、プログラムはデータベースに合わせて処理を変化させることがで
きます。たとえば、あるデータベースで価格項目が 8 桁の 10 進数であり、小数部
が 2 桁であるとします。プログラムは、このデータ型の数字に適した記憶域を割り
当てることができます。プログラムがデータベースとどのように連係しながら動作
するかについては、第 5 章「SQL を使用したプログラミング」と第 6 章「SQL プ
ログラムによるデータの更新」を参照してください。
データへの問合せ
データベースとファイルでは検索方法も異なります。ファイル内のデータは、順番
に検索して、各行または各レコード内の特定の物理位置にある特定の値を探すこと
ができます。つまり、
「1 番目のフィールドに 1013 の数値を持つレコードはどれか」
という問合せをすることになります。図 1-2 に、このタイプの探索を示します。
1-6
Informix Guide to SQL: Tutorial
データへの問合せ
図 1-2
ファイルの順次探索
1011 06/18/94 5 each tennis racquet $99.00
1013
06/22/94
1 each
tennis
racquet $19.80
1014
06/25/94
1 case
footballs
960.00
06/22/94 1 case tennis ball
$36.00
06/22/94 1 case tennis ball
$48.00
1012 06/18/94
1 case volleyball
$840.00
06/23/94
1011 06/18/94 5 each tennis racquet
1010 06/17/94 1 case tennis ball
$99.00
$36.00
注文
これに対して、データベースに問い合わせる場合は、モデルで定義した用語を使用
します。たとえば、データベースに対して「Shimara Corporation の製品に対する
New Jersey の顧客による注文で、出荷日が第 3 四半期のものはどれか」という問合
せをすることができます。図 1-3 にこのタイプの探索を示します。
データベースのコンセプト
1-7
データへの問合せ
図 1-3
データベースの問合せ
注文
1016
06/29/94
manufacturer
Shimara
注文
1019
07/16/94
州
New Jersey
注文
1023
07/24/94
顧客
Cathy
O’Brian
顧客
Bob
Shorter
Run: Next Restart Exit
Display the next page of query results
--------stores8-----------Press CTRL-W for Help------
1019 Bob Shorter SHM swim cap
07/16/94
言い換えれば、ファイルに格納されているデータを検索する場合は、ファイルの物
理的なレイアウトを表す用語で問い合わせなければならないということです。デー
タベースへの問合せを行うときは、コンピュータの記憶域に関する詳細は無視して
データベースで定義された現実の世界を反映する言葉を使用して、問合せを行うこ
とができます。
このマニュアルの第 2 章「簡単な SELECT 文の作成」と第 3 章「高度な SELECT 文
の作成」で、問合せに使用する言語について説明します。
データモデルの作成方法と実装方法については『Informix Guide to Database Design
and Implementation』を参照してください。
1-8
Informix Guide to SQL: Tutorial
データの変更
データの変更
データモデルを使用すると、データベースに格納されているデータを更新する際に
ある程度ミスを防げます。たとえば、
「Presta または Schraeder という manufacturer
のすべての stock item を検索して、その price を 13 パーセント上げる」というよう
な表現で、データベースに問い合わせることができます。このように、データの意
味を反映する用語を使用して変更内容を記述します。ファイルのレコードやフィー
ルドを示す意味のない文字や数字を使用する必要がないため、目的の操作に集中で
き、誤りを減らすことができます。
格納されているデータの変更に使用する文についての詳細は、第 4 章「データの更
新」を参照してください。
複数のユーザによる同時利用とセキュリティ
データベースは多くのユーザにとっての共通資源にすることができます。一つの
データベースに対して、複数のユーザが同時に問合せや変更ができます。その場合
は問合せと変更が衝突せず順次処理されるよう、データベースサーバ ( すべての
データベースの内容を管理するプログラム ) が調整します。
ユーザが並行してデータベースを利用できると、大きな利点が得られますが、同時
にセキュリティとプライバシーという新たな問題が発生します。データベースに
よっては個人的なものがあります。個人専用のデータベースとして設定する場合で
す。また、限られたグループのユーザのみが共有すべき機密資料が含まれている
データベースもあります。さらに、一般のアクセスが提供されているデータベース
もあります。
データベースの利用制御
Informix データベースソフトウェアには、データベースの利用を制御する機能が組
み込まれています。次のように機能するように、データベースを設計することがで
きます。
■
個人専用のデータベースにする。
■
データベースの全内容を、ユーザ全員か特定のユーザのみに公開する。
■
一部のユーザが参照できるデータの選択を制限する ( つまり、ユーザグルー
プごとに全く異なるデータを表示する )。
データベースのコンセプト
1-9
集中管理
■
特定のユーザに、特定のデータの表示はできるが変更はできない権限を与
える。
■
特定のユーザに、新しいデータの追加はできるが古いデータの変更はでき
ない権限を与える。
■
特定のユーザに、既存のデータのすべて、あるいは特定の部分のみを変更
できる権限を与える。
■
追加または変更できるデータを、データモデルに準拠したデータのみに制
限する。
データベースへのアクセス権の付与と制限の方法については、
『Informix Guide to
Database Design and Implementation』を参照してください。
集中管理
多くのユーザが使用するデータベースは、非常に貴重であり、重要な事業資産とし
て保護する必要があります。格納された貴重なデータをコンパイルし、多くのユー
ザが同時にアクセスできるようにする場合、性能を維持しながらデータを保護する
という点で大きな問題が出てきます。データベースサーバを使用すれば、これらの
タスクを集中化できます。
データベースは、損害が起こらないよう保護しなければなりません。損害をもたら
す危険はたくさんあります。ソフトウェアやハードウェアの故障や、火災、洪水な
どの自然災害が起こることもあります。重要なデータベースを失うと、莫大な被害
が生じる可能性があります。失われたデータを作成し直すには、大変な費用や手間
がかかりますが、被害はこれだけにとどまりません。データベースユーザは生産的
な時間を失ってしまいます。仕事が中断されるため、取引や信用にも影響が出てし
まうことがあります。データベースを定期的にバックアップすることで、このよう
な災害による影響を少なくすることができます。
多くのユーザが使用する大規模なデータベースの場合は、保守と調整が必要です。
担当者がシステム資源の利用状況やデータベースの発展過程を図表で監視し、障害
が発生しやすい部分を予測し、データベースの拡張を計画することが必要です。
ユーザからアプリケーションプログラムの問題が報告されたら、担当者は問題を診
断して解決しなければなりません。迅速な応答が重要な場合、担当者はシステムの
性能を分析して、応答が遅れる原因を突き止めなけれはなりません。
1-10
Informix Guide to SQL: Tutorial
重要なデータベース用語
重要なデータベース用語
次の章に進む前に二組の用語を理解しておく必要があります。一組の用語はデータ
ベースとデータ モデルに関連するもので、もう一組の用語はデータベースを管理す
るコンピュータ プログラムに関連するものです。この節では、データベースとデー
タ モデルを説明する用語を定義します。データベースを管理するプログラムに関連
する用語については、1-17 ページの「データベース ソフトウェア」を参照してくだ
さい。
リレーショナル モデル
Informix データベースはリレーショナル データベースです。リレーショナル データ
ベースの場合、技術的には、Informix データベースが編成されるデータ モデルは、
E. F. Codd が考案した関係演算に基づいています。実質的には、すべてのデータは、
行と列からなる表に格納されています。
リレーショナル モデルは、現実の世界を反映するようにデータを編成する 1 つの方
法で、次に示す単純な対応関係を使用します。
関係
説明
表 = 実体
各表は、1 つの対象または 1 種類の事柄についてデー
タベースが持っているすべてのデータを表します。
列 = 属性
各列は、表が記述する対象が持つ 1 つの機能、特性、
または事実を表します。
行 = 実現値
各行は、表が記述する対象が持つ 1 つの実現値を表
します。
実体と属性を選択する場合にはいくつかの規則が適用されますが、それらの規則が
重要な意味を持つのは新しいデータベースを設計するときだけです ( データベース
設計についての詳細は、
『Informix Guide to Database Design and Implementation』を参
照してください )。既存のデータベースではデータ モデルは既に設定されています。
既存のデータベースを使用する場合、表と列の名前、および表と列が現実の世界で
何に対応しているかを理解しておけば十分です。
データベースのコンセプト
1-11
表
表
データベースは、情報の集まりです。この情報は分類されて一つまたは複数の表に
格納されます。表は複数のデータが並んだもので、データは行と列の形で編成され
ます。すべての 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
表は、一つの実体、つまりデータベースが記述する一つの型についてデータベース
管理者 (DBA) が知っているすべての情報を表します。この例の表 stock は、あるス
ポーツ用品店が取り扱っている商品について DBA が知っているすべての情報を表
しています。この他に、デモンストレーションデータベースには、customer や
orders といった実体を表す表があります。
データベースは表の集まりと考えることができます。データベースを作成すること
は、互いに関連する複数の表を作成することになります。表に対して問合せたり変
更したりする権限は、表単位で制御することができるので、ユーザによって参照ま
たは変更できる表が異なることもあります。
1-12
Informix Guide to SQL: Tutorial
列
列
表の各列は 1 つの属性を表します。属性とは、表の対象について真である 1 つの特
性、機能、または事実です。表 stock には、対象である各商品の項目について、
stock numbers ( 取扱品目番号 )、manufacturer codes ( メーカ コード )、descriptions ( 品
目内容 )、prices ( 単価 )、および units of measure ( 最小販売単位 ) といった事実を表
す列があります。
行
表を構成するそれぞれの行は、表の対象の一つの実現値、つまりその実体の特定の
例を表します。表 stock の各行は、そのスポーツ用品店が販売している商品の一つ
の品目を表しています。
表に対する操作
データベースは表の集まりなので、データベースの操作は表に対する操作というこ
とになります。リレーショナルモデルには 3 つの基本的な操作、すなわち、選択、
射影、結合があります。図 1-4 は選択と射影の操作を示しています (3 つの操作は、
第 2 章「簡単な SELECT 文の作成」と第 3 章「高度な SELECT 文の作成」で、例を
伴って詳細に定義されています )。
データベースのコンセプト
1-13
表に対する操作
図 1-4
選択と射影の説明
表 stock
stock_num
manu_code
description
unit_price
unit
unit_descr
...
1
1
1
2
3
4
4
5
...
313
...
HRO
HSK
SMT
HRO
HSK
HSK
HRO
NRG
...
ANZ
...
baseball gloves
baseball gloves
baseball gloves
baseball
baseball bat
football
football
tennis racquet
...
swim cap
...
250.0
800.0
450.0
126.0
240.0
960.0
480.0
28.0
...
60.0
...
case
case
case
case
case
case
case
each
...
case
...
10 gloves/case
10 gloves/case
10 gloves/case
24/case
12/case
24/case
24/case
each
...
12/box
I
O
P
R
O
J
E
C
T
選択
N
表からデータを選択する場合、ある行は選択し、ある行は無視します。たとえば、
データベース管理システムに要求して、表 stock に対して「manufacturer code が
HSK で unit price が 200.00 から 300.00 の範囲の行をすべて選択する」という問合せ
を行うことができます。
表から射影する場合も、ある列を選択し、ある列は無視します。たとえば、データ
ベース管理システムに要求して、表 stock に対して「stock_num、unit_descr、
unit_price の各列を射影する」という問合せを行うことができます。
各表には一つの実体に関する情報のみが格納されるので、複数の実体について情報
が必要な場合はそれらの表を結合しなければなりません。表はさまざまな方法で結
合することができます ( 結合操作については、第 3 章「高度な SELECT 文の作成」
で説明しています )。
1-14
Informix Guide to SQL: Tutorial
構造化問合せ言語 (SQL)
構造化問合せ言語 (SQL)
ほとんどのコンピュータソフトウェアでは、
「New Jersey の顧客が行った発注のうち
出荷日が第 3 四半期にあたっているものはどれか」というような、日常用語でデー
タベース問合せを行える段階には達していません。したがって、ユーザはソフト
ウェアが簡単に解析できる制限的な構文で質問を記述する必要があります。次のよ
うな用語を使用して、デモンストレーションデータベースへの同じ質問を行うこと
ができます。
SELECT * FROM customer, orders
WHERE customer.customer_num = orders.customer_num
AND customer.state = 'NJ'
AND orders.ship_date
BETWEEN DATE('7/1/96') AND DATE('9/30/96')
この質問は、構造化問合せ言語 (SQL) の例を示しています。この言語はデータベー
スに対してあらゆる操作を指示するための言語です。SQL は文で構成され、各文は
特定の機能を指定する 1 語か 2 語のキーワードで始まります。SQL の Informix 実装
では、ALLOCATE DESCRIPTOR から WHENEVER に至るまで、多数の SQL 文があ
ります。
すべての SQL 文についての詳細は、
『Informix Guide to SQL: Syntax』を参照してく
ださい。データベースのセットアップや調整では、SQL 文はほとんど使用されませ
ん。通常は、3 つか 4 つの文を使用して、データベースの問合せや更新を行います。
必ずといってよいほど頻繁に使用する文の一つが、SELECT 文です。SELECT 文は、
データベースからデータを抽出するのに使用できる唯一の文です。また最も複雑な
文でもあります。このマニュアルでは、第 2 章と第 3 章を SELECT 文の説明に当て
ています。
標準 SQL 文
SQL と関係モデルは、1970 年代の初期から中頃にかけて IBM 社によって考案され
ました。実用的なリレーショナルデータベースが実現可能であることと、その操作
用言語として SQL を使用できることが IBM 社によって実証されると、他のベンダ
が同種の製品を IBM コンピュータ以外のマシン用として提供し始めました。
データベースのコンセプト
1-15
Informix SQL と ANSI 標準 SQL
製品化されたそれぞれの SQL は、性能の向上や競争力、特定のハードウェアやソ
フトウェアの特徴の活用などが背景にあったため、各社とも異なった製品を提供
し、SQL の IBM バージョンとも異なっていました。そこでこのような相違点を最
小限にするため、1980 年代初期に標準化委員会が設立されました。
ANSI( 米国規格協会 ) の X3H2 委員会は、1986 年に SQL1 規格を制定しました。こ
の規格は、SQL の中核となる機能群と SELECT 文などの文の構文を定義していま
す。
Informix SQL と ANSI 標準 SQL
Informix 製品がサポートしている SQL のバージョンは、標準 SQL と互換性があり
ます (SQL の IBM バージョンとも互換性があります )。また、標準 SQL に対する拡
張機能も用意されています。つまり、文によっては特別のオプションや機能を追加
して制約を緩やかにしている場合もあります。ただし、相違点のほとんどは、日常
的には使用頻度の低い文に関係しています。たとえば、通常のユーザが使用する場
合は SQL の 90 パーセントは SELECT 文ということになりますが、SELECT 文では
標準との相違点がほとんどありません。
ただし、拡張機能には相違点があり、矛盾が生じています。多くの Informix 製品利
用者は、Informix 製品の SQL をプログラムおよびストアドプロシジャに埋め込んで
いるので、言語を変更しないことを要求しています。一方、別の Informix 利用者は、
ANSI 規格に完全に準拠する形でデータベースを使用できるように要求しています。
規格に準拠するようにその言語が変更されることを、Informix 製品に期待しているの
です。
Informix はこのような利害の対立を解決するため、次のような機能を提供します。
■
ANSI標準の拡張版付きSQLのInformixバージョンをデフォルトで提供する。
■
SQL の使用状況をチェックして、Informix 拡張機能を使用したときは警告フ
ラグを立てるように、InformixSQL 言語プロセッサに要求できる。
『Informix Guide to SQL: Syntax』では、Informix と ANSI 標準の SQL 間で相違点があ
る場合には、両方のバージョンについて説明しています。しかし、ユーザはほとん
ど一つのバージョンのみを使用するので、必要のないバージョンは無視してくださ
い。
1-16
Informix Guide to SQL: Tutorial
ANSI 標準準拠のデータベース
ANSI 標準準拠のデータベース
ANSI 標準準拠のデータベースを作成する場合は、キーワード MODE ANSI を使用
してください。そのようなデータベース内では、ANSI 標準の一定の特性が適用さ
れます。たとえば、データを更新する動作はすべて自動的にトランザクション内で
実行されるので、変更は完全に行われるか、それとも全く行われないかが保証され
ます。ANSI 標準準拠のデータベースの動作の違いについては、『Informix Guide to
SQL: Syntax』を参照してください。ANSI 標準準拠のデータベースの詳細は、
『Informix Guide to Database Design and Implementation』を参照してください。
GLS
GLS データベース
Informix データベースサーバ製品は、GLS( 広域言語サポート ) 機能を装備していま
す。GLS により、合衆国英語の ASCII 文字に加えて他のロケールも使用することが
でき、SQL データ中の非 ASCII 文字および識別子も使用できます。GLS 機能を使
用すれば、特定のロケールの習慣に対応できます。ロケールファイルには、さまざ
まな金額フォーマット、日付フォーマット、照合順序などについての文化に固有の
情報が含まれています。GLS の詳細情報については、『Informix Guide to GLS
Functionality』を参照してください。
データベース ソフトウェア
データベースへのアクセスは、洗練されたソフトウェアの 2 つの層を通じて行いま
す。上位層 ( すなわちアプリケーション ) はコマンドまたは問合せをデータベース
サーバに送ります。アプリケーションは下位層 ( すなわちデータベース サーバ ) に
通知し、情報を受け取ります。SQL を使用するときは両方の層に指示します。
データベースのデータを使用するプログラムはどれも同じように動作します。どの
場合でも、アプリケーションとデータベース サーバを使用します。アプリケーショ
ンはユーザと対話し、データの準備と形式設定をして、SQL 文を設定します。デー
タベース サーバはデータベースを管理し、SQL 文を解釈します。すべてのアプリ
ケーションはデータベース サーバへの要求を作成し、データベース サーバだけが
ディスク上のデータベース ファイルを操作します。
データベースのコンセプト
1-17
アプリケーション
アプリケーション
データベース アプリケーション ( または単にアプリケーション ) は、データベース
サーバと通信することによってデータベースを使用するプログラムです。最も単純
な動作では、アプリケーションは SQL 文をデータベース サーバに送り、データ
ベース サーバは複数行のデータをアプリケーションに送り返します。次に、アプリ
ケーションはこの行をユーザに表示します。
または、ユーザがアプリケーションに新しいデータをデータベースに追加するよう
指示します。行を挿入するための SQL 文に新しいデータを含んでおり、実行する
ために SQL 文をデータベース サーバに渡します。
アプリケーションにはいくつかのタイプがあります。SQL を使用してデータベース
に対話的にアクセスするアプリケーションや、用途別に対応した形式で格納された
データを提供するアプリケーションがあります。
データベース サーバ
データベース サーバは、データベースのデータをディスクに格納するときにその内
容を管理するプログラムです。データベース サーバは、表、行、および列がコン
ピュータの物理記憶装置内で実際にどのように編成されているかを管理していま
す。データベース サーバは、すべての SQL コマンドの解釈と実行も行います。
対話型 SQL
このマニュアルに示された例を実行したり、SQL およびデータベース設計を自分で
試したりするためには、SQL 文を対話式に実行するプログラムが必要です。このよ
うなプログラムには、DB-Access やリレーショナルオブジェクトマネージャがあり
ます。これらのプログラムは、SQL 文を構成する手助けをし、次に、実行するため
に SQL 文をデータベース サーバに引き渡し、結果を表示します。
AD/XP
1-18
Dynamic Server with AD and XP Options は リレーショナルオブジェクトマネージャプ
ログラムをサポートしません。 ♦
Informix Guide to SQL: Tutorial
一般的なプログラミング
一般的なプログラミング
SQL 文を取り込んでデータベース サーバとの間でデータを交換するプログラムを作
成できます。すなわち、データベースからデータを検索し、選択した形式にフォー
マットできます。任意のソースから任意のフォーマットでデータを取り出し、準備
して、データベースに挿入するプログラムを作成することもできます。
データベース データおよびオブジェクトを操作するストアド プロシジャというプ
ログラムを作成することもできます。作成したストアド プロシジャはデータベース
の表に直接格納されます。ストアド プロシジャは、DB-Access、ROM、または
INFORMIX-ESQL/C などの SQL アプリケーション プログラミング インターフェイ
ス (SQL API) から実行できます。
第 5 章「SQL を使用したプログラミング」と第 6 章「SQL プログラムによるデータ
の更新」には、プログラムで SQL を使用する方法の概要が記載されています。
まとめ
データベースは関連する情報の集まりですが、他のデータ格納方法とは基本的に異
なります。データベースにはデータだけでなく、それぞれのデータ項目を定義し、
その意味を他の項目と実際に指定するデータモデルも格納されます。
複数のユーザが同時にデータベースにアクセスして変更を加えることができます。
ユーザによって参照できるデータベースの内容は異なり、これらの内容へのアクセ
スはいくつかの方法で制限することができます。
リレーショナルデータベースは表で構成され、表は列と行で構成されます。リレー
ショナルモデルは、表上での選択、射影、結合の 3 つの基本操作をサポートしま
す。
データベースのコンセプト
1-19
まとめ
データベースの操作と問合せには SQL を使用します。SQL には IBM 規格と ANSI
標準があります。ANSI が定義した言語に、Informix が補足した拡張機能を利用する
ことができます。Informix ツールを使用して、厳密な ANSI 標準準拠を維持すること
もできます。
2 層のソフトウェアによってデータベース操作を実行します。下位層は、SQL 文を
実行したりディスク上やメモリ内のデータを管理するデータベース サーバです。上
位層は、Informix、他のベンダ、またはユーザが作成するアプリケーションです。
1-20
Informix Guide to SQL: Tutorial
第2章
簡単な SELECT 文の作成
SELECT 文の基本的な事項
基本概念 . . . .
アクセス権 . .
関係演算. . .
選択と射影 . .
結合 . . . .
SELECT 文の形式 .
特殊なデータ型 . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2-4
2-5
2-5
2-5
2-6
2-8
2-10
2-11
一つの表に対する SELECT 文 . . . . . .
すべての列と行の選択 . . . . . . .
アスタリスクの使用方法 . . . . .
列の並べ替え . . . . . . . .
行のソート . . . . . . . . .
特定の列の抽出 . . . . . . . . .
ORDER BY と NLS( 各国語サポート ) . .
部分文字列の選択 . . . . . . .
WHERE 節の使用方法 . . . . . . .
比較条件の作成 . . . . . . . . .
変数テキスト検索の使用方法. . . .
正確な文字列比較の使用方法. . . .
1 字長のワイルドカードの使用方法 . .
MATCHES と英語以外のデータ . . .
特殊文字の比較. . . . . . . .
特定の行を選択するための FIRST 節の使用 .
ORDER BY 節のない FIRST 節 . . .
ORDER BY 節のある FIRST 節 . . .
ユニオン問合せの FIRST 節 . . . .
式と導出値 . . . . . . . . . .
算術式 . . . . . . . . . .
CASE 式 . . . . . . . . . .
導出列を基にしたソート . . . . .
SELECT 文での関数の使用. . . . . .
集計関数. . . . . . . . . .
時刻関数. . . . . . . . . .
日付変換関数 . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2-11
2-12
2-12
2-13
2-13
2-18
2-25
2-27
2-28
2-29
2-37
2-38
2-39
2-42
2-44
2-46
2-46
2-47
2-48
2-49
2-49
2-54
2-56
2-57
2-57
2-63
2-68
.
文字列操作関数 . . . . . . . . . . . . . . . . .
その他の関数. . . . . . . . . . . . . . . . . .
SELECT 文でのストアドプロシジャの使用 . . . . . . . . . . . .
複数表 SELECT 文 . .
デカルト積の作成
結合の作成 . .
等結合. . .
自然結合 . .
複数表の結合.
簡単な問合せ方法
別名の使用 .
INTO TEMP 節
2-2
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2-71
2-79
2-87
. 2-89
. 2-89
. 2-91
. 2-91
. 2-94
. 2-96
. 2-97
. 2-97
. 2-101
現行データベース以外のデータベースからの表の検索 . . .
. . .
. . 2-102
まとめ . . .
. . .
. . 2-103
. .
. . .
Informix Guide to SQL: Tutorial
. . .
. . .
. . .
SELECT 文は、もっとも重要でもっとも複雑な SQL 文です。SELECT 文は、SQL
の INSERT 文、UPDATE 文、および DELETE 文と一緒に使用してデータを操作す
ることができます。SELECT 文は次の方法で使用できます。
■
単独で使用して、データベースからデータを抽出する。
■
INSERT 文に組み込んで、データベースに新しい行を追加する。
■
UPDATE 文に組み込んで、データベースの情報を更新する。
SELECT 文はデータベース内の情報を問い合わせる主要な方法です。SELECT 文は
プログラム、レポート、スクリーンフォーム、スプレッドシートなどからデータを
抽出する際に重要な働きをします。
この章では、SELECT 文を使用してリレーショナルデータベースに問合せを行い、
データを抽出するさまざまな方法を紹介して説明します。一つまたは複数の表から
列または行を選択してその情報を得る方法、SELECT 文に式や関数をインクルード
する方法、リレーショナルデータベース内の表間のさまざまな結合条件を設定する
方法について説明します。
また、リレーショナルデータベースからデータを抽出する基本的な方法を説明しま
す。副問合せ、外部接続、共用体などの SELECT 文の複雑な使用方法については、
第 3 章「高度な SELECT 文の作成」で説明されています。SELECT 文の構文および
使用方法については、
『Informix Guide to SQL: Syntax』で説明されています。
この章に示す大半の例では、デモンストレーションデータベースの表を使用しま
す。このデータベースは、Informix SQL API や他のデータベースユーティリティの
ソフトウェアと一緒にインストールされます。簡略化のために、各 SELECT 文では
抽出されるデータの一部のみを例示します。デモンストレーションデータベースの
構造と内容については、
『Informix Guide to SQL: Reference』を参照してください。
SQL では大文字と小文字を区別しませんが、例の中では強調するためにキーワード
を大文字で表記しています。
簡単な SELECT 文の作成
2-3
SELECT 文の基本的な事項
SELECT 文の基本的な事項
SELECT 文は、リレーショナルデータベースのデータを選択して表示する機能を持
つ複数の節から構成されています。それらの節は、一つまたは複数の表やビューか
ら一つまたは複数の条件を指定して列や行を抽出し、データの順番を揃えたり、集
計をとって一時表に格納することもできます。
ここでは、SELECT 文を構成する 5 つの節の使用方法を説明します。5 つの節は次
の順序で SELECT 文にインクルードしなければなりません。
1.
SELECT 節
2.
FROM 節
3.
WHERE 節
4.
ORDER BY 節
5.
INTO TEMP 節
必ず使用しなければならないのは、SELECT 節と FROM 節のみです。この二つの
節は、抽出の対象となる表と列を指定するので、データベースに対するすべての
問合せの基本となります。他の節は、次に示す目的に応じて使用します。
■
WHERE 節を追加して、特定の行を指定したり、結合条件を設定する。
■
ORDER BY 節を追加して、問合せ結果のデータを特定の順番で並べ替え
る。
■
INTO TEMP 節を追加して、後で別の問合せで利用できるように問合せ結果
を一時表に保存する。
SELECT 文の GROUP BY 節および HAVING 節の二つの節では、複雑なデータの抽
出を実行します。これらの節については、第 3 章「高度な SELECT 文の作成」で説
明されています。INTO 節は、INFORMIX-NewEra と SQL API で SELECT 文から
データを抽出するためのプログラムまたはホスト変数を指定します。SELECT 文を
使用する際の完全な構文およびルールについては、
『Informix Guide to SQL: Syntax』
で説明されています。
2-4
Informix Guide to SQL: Tutorial
基本概念
基本概念
SELECT 文は、データベース内のデータの更新は行いません。この点が INSERT
文、UPDATE 文、DELETE 文と異なるところです。単にデータの問合せを行いま
す。データの変更は、一度に一人のユーザしか行うことができませんが、データの
問合せまたは選択は、複数のユーザが同時に行うことができます。データを変更す
る文については、第 4 章「データの更新」で説明されています。INSERT 文、
『Informix Guide to SQL: Syntax』で説明されてい
UPDATE 文、DELETE 文の構文は、
ます。
リレーショナルデータベースでは一つの列が 1 データ要素となり、表の各行に共通
して存在する特定のタイプの情報を表します。行とは、単一の実体に関する情報の
集まりで、各項目がデータベースの表の各列に相当します。
SELECT 文を使用して、データベースの表、システムカタログ表、ビューなどの行
や列を選択することができます。システムカタログ表はデータベースに関する情報
を収めた特殊な表です。ビューはカスタマイズされたデータセットを格納するため
に作成された仮想表です。システムカタログ表は『Informix Guide to SQL: Reference』
で説明されています。ビューについては、
『Informix Guide to Database Design and
Implementation』で説明されています。
アクセス権
データの問合せを行う前に、データベースの接続アクセス権と表の選択アクセス権
を所有している必要があります。通常、これらの権限はすべてのユーザに与えられ
ています。データベースのアクセス権については、
『Informix Guide to Database
、および『Informix Guide to SQL: Syntax』の GRANT 文と
Design and Implementation』
REVOKE 文で説明されています。
関係演算
関係演算は、一つまたは複数の表や関係を操作してその結果を新しい表として作成
するものです。関係演算には選択、射影、結合の 3 種類があります。ここでは選
択、射影、および簡単な結合の例を示します。
簡単な SELECT 文の作成
2-5
基本概念
選択と射影
リレーショナルデータベースでいう選択とは、一つの表から特定の条件に合致した
行を抽出することです。選択を行う SELECT 文は、表の中で条件に合致したいくつ
かの行とそれぞれの行のすべての列を返します。選択は、問合せ 2- 1 で示すよう
に、SELECT 文の WHERE 節で実行されます。
問合せ 2- 1
SELECT * FROM customer
WHERE state = 'NJ'
この問合せを行うと、問合せ結果 2- 1 に示すような結果になります。表 customer の
中の指定条件に合致したいくつかの行について、その行に属するすべての列が抽出
されます。選択された列のデータは、DB-Access またはリレーショナルオブジェク
トマネージャの画面の 1 行と一致していないため、横方向ではなく縦方向に表示さ
れます。
問合せ結果 2- 1
customer_num 119
fname
Bob
lname
Shorter
company The Triathletes Club
address1 2405 Kings Highway
address2
city
Cherry Hill
state
NJ
zipcode 08002
phone
609-663-6079
customer_num 122
fname
Cathy
lname
O‘ Brian
company The Sporting Life
address1 543d Nassau
address2
city
Princeton
state
NJ
zipcode 08540
phone
609-342-0054
リレーショナルデータベースでいう射影とは、一意の行を持つ単一の表から仮想的
にいくつかの列を抽出することです。射影を行う SELECT 文は、表の中のすべての
行について、指定したいくつかの列を返します。
2-6
Informix Guide to SQL: Tutorial
基本概念
射影は、問合せ 2- 2 で示すように、SELECT 文の SELECT 節の選択対象の並びで実
行されます。
問合せ 2- 2
SELECT UNIQUE city, state, zipcode
FROM customer
問合せ結果 2- 2 には、表 customer と同じ数の行が含まれますが、表内の列のサブ
セットしか射影しません。
問合せ結果 2- 2
city
state
zipcode
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
簡単な SELECT 文の作成
2-7
基本概念
通常使用する SELECT 文のほとんどは、選択と射影の両方を同時に行います。こ
のような問合せは、問合せ 2- 3 に示すように、表の一部の行について一部の列を返
します。
問合せ 2- 3
SELECT UNIQUE city, state, zipcode
FROM customer
WHERE state = 'NJ'
問合せ結果 2- 3 には、表 customer の一部の行について一部の列が示されています。
city
state
zipcode
Cherry Hill
Princeton
NJ
NJ
08002
08540
問合せ結果 2- 3
結合
この例の問合せでは、図 2-1 で示すように、表 items と表 stock のサブセットを使用
して結合の概念を説明しています。
2-8
Informix Guide to SQL: Tutorial
基本概念
図 2-1
二つの表の結合
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
HRO
HSK
HRO
4
HSK
5
NRG
野球グローブ
野球グローブ
野球用ボール
フットボール用
ボール
テニスラケット
item_num
order_num
stock_num
description
1
1001
1
1
1002
4
3
1
1003
1005
5
5
野球グローブ
フットボール用
ボール
テニスラケット
テニスラケット
問合せ 2- 4 では、表 customer と表 state を結合します。
問合せ 2- 4
SELECT UNIQUE city, state, zipcode, sname
FROM customer, state
WHERE customer.state = state.code
簡単な SELECT 文の作成
2-9
SELECT 文の形式
問合せ結果 2- 4 は、表 customer と表 state の両方で指定した行および列から構成さ
れています。
問合せ結果 2- 4
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
SELECT 文の形式
構文は Informix 製品すべてに共通していますが、SELECT 文の形式と、結果として
生じる出力の位置とフォーマットはアプリケーションによって異なります。この章
と第 3 章「高度な SELECT 文の作成」に示されている例は、DB-Access の対話型問
合せ言語オプションまたはリレーショナルオブジェクトマネージャ を使用したとき
に表示される SELECT 文とその出力を示しています。SELECT 文は、
INFORMIX-ESQL/C といった言語で組み込むこともできます (SELECT 文が実行可能
コードとして処理される場合 )。
2-10
Informix Guide to SQL: Tutorial
特殊なデータ型
特殊なデータ型
DB-Access の場合、可変長文字 (VARCHAR) 型データ、テキスト (TEXT) 型データ
またはバイト (BYTE) 型データを含む SELECT 文を使用すると、次のように異なっ
た問合せ結果が表示されます。
■
可変長文字 (VARCHAR) 型の列に対する問合せでは、文字 (CHARACTER) 型
の値の場合と同様に、可変長文字型の値全体が表示されます。
■
テキスト (TEXT) 型の列に対する問合せでは、列のテキスト内容が表示され
ます。このテキストは、スクロールして確認することができます。
■
バイト (BYTE) 型の列に対する問合せでは、実際の値は表示されず、かわり
に <BYTE value> と表示されます。
可変長文字 (VARCHAR) 型、テキスト (TEXT) 型、バイト (BYTE) 型に特有の事項
については、必要に応じてこの章で説明します。
GLS
文字(CHAR)型列ではなく、各国語文字(NCHAR)型列の問合せを行うSELECT文を使
用するか、可変長文字 (VARCHAR) 型列ではなく、各国語可変長文字
(NVARCHAR) 型列の問合せを行うことができます。
『Informix Guide to GLS Functionality』を参照してください。
GLS の詳細については、
GLS と他のデータ型の追加情報については、『Informix Guide to Database Design and
Implementation』と『Informix Guide to SQL: Reference』を参照してください。 ♦
一つの表に対する SELECT 文
データベース内の一つの表に対する問合せにもさまざまな方法があります。
SELECT 文の記述を変えることによって、次のような操作を行うことができます。
■
すべての列、または特定の列のみを抽出する。
■
すべての行、または特定の行のみを抽出する。
■
抽出したデータに対して計算のみの処理を行う。
■
抽出したデータを目的に応じて並べ替える。
簡単な SELECT 文の作成
2-11
すべての列と行の選択
すべての列と行の選択
もっとも基本的な SELECT 文は、SELECT 節と FROM 節の二つのみから構成され
ます。
アスタリスクの使用方法
問合せ 2- 5a に示す SELECT 文では、選択対象の並びに表 manufact のすべての列が
指定されています。選択対象の並びとは、表から取り出したい列の名前や式を並べ
たものです。
問合せ 2- 5a
SELECT manu_code, manu_name, lead_time
FROM manufact
問合せ 2-5b に示す SELECT 文では、ワイルドカード文字のアスタリスク (*) を使用
して選択対象の並びを簡潔に記述しています。このアスタリスクは表のすべての列
の名前を表します。表のすべての列を定義されている順番のまま SELECT 文に指定
する場合に、アスタリスクを使用することができます。
問合せ 2-5b
SELECT * FROM manufact
問合せ 2- 5a と問合せ 2-5b に示す二つの問合せから得られる結果は同じです。表
manufact のすべての行と列について表示されます。問合せ結果 2- 5 は、DB-Access
またはリレーショナルオブジェクトマネージャの画面に表示される状態を示してい
ます。 manu_code manu_name
SMT
ANZ
NRG
HSK
HRO
SHM
KAR
NKL
PRC
2-12
Smith
Anza
Norge
Husky
Hero
Shimara
Karsten
Nikolus
ProCycle
lead_time
3
5
7
5
4
30
21
8
9
Informix Guide to SQL: Tutorial
問合せ結果 2- 5
すべての列と行の選択
列の並べ替え
問合せ 2- 6 の SELECT 文は、選択対象の並びの順番を変えて、問合せ結果で表示さ
れる列の順番を変える方法を示しています。
問合せ 2- 6
SELECT manu_name, manu_code, lead_time
FROM manufact
問合せ結果 2- 6 には、直前の問合せ結果と同じ列が含まれていますが、列の順番の
指定が異なっているため表示が異なっています。
manu_name
Smith
Anza
Norge
Husky
Hero
Shimara
Karsten
Nikolus
ProCycle
manu_code lead_time
SMT
ANZ
NRG
HSK
HRO
SHM
KAR
NKL
PRC
問合せ結果 2- 6
3
5
7
5
4
30
21
8
9
行のソート
ORDER BY 節を SELECT 文に追加すると、特定の順番でデータをソートするよう
にシステムに指示することができます。ORDER BY 節で使用する列を、選択対象の
並びに明示的または暗黙的に含める必要があります。
問合せ 2- 7a で示すような明示的な選択対象の並びに、抽出したいすべての列名を
含める必要があります。
問合せ 2- 7a
SELECT manu_code, manu_name, lead_time
FROM manufact
ORDER BY lead_time
問合せ 2-7b が示すように、暗黙的な選択対象の並びはアスタリスク (*) を使用しま
す。
問合せ 2-7b
SELECT * FROM manufact
ORDER BY lead_time
簡単な SELECT 文の作成
2-13
すべての列と行の選択
問合せ 2- 7a と問合せ 2-7b の問合せ結果は同じです。問合せ結果 2- 7 に示すように、
表 manufact のすべての行についてすべての列が、列 lead_time の値の順に表示され
ます。
問合せ結果 2- 7
manu_code manu_name
SMT
HRO
HSK
ANZ
NRG
NKL
PRC
KAR
SHM
Smith
Hero
Husky
Anza
Norge
Nikolus
ProCycle
Karsten
Shimara
lead_time
3
4
5
5
7
8
9
21
30
昇順のソート
SELECT 文が抽出したデータは、デフォルトでは昇順にソートされて表示されま
す。昇順とは、文字型データの場合は、英大文字の A から始まり小文字の z にいた
る順です。数値型データの場合は数値が増加する順です。漢字などの日本語文字は
文字コードの順です。日付 (DATE) 型データと日時 (DATETIME) 型データの場合
は、最新のデータからもっとも古いデータの順でソートされます。時間隔
(INTERVAL) 型データの場合は、最短スパンから最長スパンの順です。
降順のソート
降順は昇順とは逆に、文字 (CHARACTER) 型データの場合は、英小文字の z から始
まり大文字の A にいたる順です。数値型データの場合は数値が減少する順です。漢
字などの日本語文字は文字コードの逆順です。日付 (DATE) 型と日時 (DATETIME)
型のデータは一番新しいものから順に並べられ、時間隔 (INTERVAL) 型のデータ
は、時間隔が一番長いものから順に並べられます。問合せ 2- 8 は降順のソートの例
です。
問合せ 2- 8
SELECT * FROM manufact
ORDER BY lead_time DESC
列名の後にキーワード DESC を続けると、問合せ結果 2- 8 で示すように、抽出した
データを降順でソートすることができます。
2-14
Informix Guide to SQL: Tutorial
すべての列と行の選択
manu_code manu_name
SHM
KAR
PRC
NKL
NRG
HSK
ANZ
HRO
SMT
Shimara
Karsten
ProCycle
Nikolus
Norge
Husky
Anza
Hero
Smith
lead_time
問合せ結果 2- 8
30
21
9
8
7
5
5
4
3
ORDER BY 節には、テキスト (TEXT) 型またはバイト (BYTE) 型のデータを除い
て、任意の列を指定できます。データベースサーバは指定された列の値に基づいて
データをソートします。
複数の列を基にしたソート
ORDER BY 節に複数の列を指定して、多重ソートを行うことができます。デフォル
トは昇順のままですが、ORDER BY 節で最初にリストされる列が優先されます。
簡単な SELECT 文の作成
2-15
すべての列と行の選択
問合せ 2- 9 と問合せ 2- 10 は、多重ソートの例です。それぞれに対応する問合せ結
果を併せて示します。選択されたデータの表示の順番を変更するには、ORDER BY
節で命名した二つの列の順番を変えます。
問合せ 2- 9
SELECT * FROM stock
ORDER BY manu_code, unit_price
問合せ結果 2- 9 では、列 manu_code の値が昇順に並ぶようにソートされ、同じ
manu_code を持つ行 (ANZ, HRO など ) があれば、それらの行はさらに列 unit_price
の値により昇順にソートされています。
問合せ結果 2- 9
stock_num manu_code description
unit_price unit unit_descr
5
9
6
313
201
310
301
304
110
205
8
302
309
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
HRO
HRO
tennis racquet
volleyball net
tennis ball
swim cap
golf shoes
kick board
running shoes
watch
helmet
3 golf balls
volleyball
ice pack
ear drops
$19.80
$20.00
$48.00
$60.00
$75.00
$84.00
$95.00
$170.00
$244.00
$312.00
$840.00
$4.50
$40.00
each
each
case
box
each
case
each
box
case
case
case
each
case
each
each
24 cans/case
12/box
each
12/case
each
10/box
4/case
24/case
24/case
each
20/case
113
5
6
1
SHM
SMT
SMT
SMT
18-spd, assmbld
tennis racquet
tennis ball
baseball gloves
$685.90
$25.00
$36.00
$450.00
each
each
case
case
each
each
24 cans/case
10 gloves/case
.
.
.
2-16
Informix Guide to SQL: Tutorial
すべての列と行の選択
問合せ 2- 10 では、ORDER BY 節の列の順番が前の例とは逆になっています。
問合せ 2- 10
SELECT * FROM stock
ORDER BY unit_price, manu_code
この場合の問合せ結果は、問合せ結果 2- 10 に示すように、列 unit_price の値が昇順
に並ぶようにソートされ、同じ単価を持つ行 ($20.00、$48.00、$312.00) が複数ある
ときは、それらの行は列 manu_code で昇順にソートされています。
問合せ結果 2- 10
stock_nummanu_codedescription
unit_price unit unit_descr
302
302
5
9
103
106
5
HRO
KAR
ANZ
ANZ
PRC
PRC
SMT
ice pack
ice pack
tennis racquet
volleyball net
frnt derailleur
bicycle stem
tennis racquet
$4.50
$5.00
$19.80
$20.00
$20.00
$23.00
$25.00
each each
each each
each each
each each
each each
each each
each each
301
204
108
6
305
303
311
HRO
KAR
SHM
ANZ
HRO
PRC
SHM
running shoes
putter
crankset
tennis ball
first-aid kit
socks
water gloves
$42.50
$45.00
$45.00
$48.00
$48.00
$48.00
$48.00
each each
each each
each each
case 24 cans/case
case 4/case
box 24 pairs/box
box 4 pairs/box
110
205
205
205
1
4
102
111
112
7
203
113
1
8
4
HSK
ANZ
HRO
NKL
SMT
HRO
PRC
SHM
SHM
HRO
NKL
SHM
HSK
ANZ
HSK
helmet
3 golf balls
3 golf balls
3 golf balls
baseball gloves
football
bicycle brakes
10-spd, assmbld
12-spd, assmbld
basketball
irons/wedge
18-spd, assmbld
baseball gloves
volleyball
footbal
.
.
.
.
.
.
$308.00
$312.00
$312.00
$312.00
$450.00
$480.00
$480.00
$499.99
$549.00
$600.00
$670.00
$685.90
$800.00
$840.00
$960.00
case 4/case
case 24/case
case 24/case
case 24/case
case 10 gloves/case
case 24/case
case 4 sets/case
each each
each each
case 24/case
case 2 sets/case
each each
case 10 gloves/case
case 24/case
case 24/case
簡単な SELECT 文の作成
2-17
特定の列の抽出
ORDER BY 節では、列の順番とキーワード DESC の位置が重要になります。問合せ
2- 11 に示す 4 つの文は、ORDER BY 節が同一の要素で構成されていますが、問合
せの結果 ( ここには示していません ) は異なります。
問合せ 2- 11
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
特定の列の抽出
前節では、表からすべてのデータを抽出してソートする方法について説明しまし
た。しかし、すべてのデータではなく、特定の列のデータのみを抽出したい場合も
よくあります。この場合も、SELECT 節と FROM 節を使用して列と表を指定しま
す。通常、ORDER BY 節も指定して、データを昇順か降順に並べます。
2-18
Informix Guide to SQL: Tutorial
特定の列の抽出
表 orders のすべての顧客番号を探索する場合は、問合せ 2- 12 に示す文を使用しま
す。
問合せ 2- 12
SELECT customer_num FROM orders
この問合せ結果は、問合せ結果 2- 12 に示すように、表 orders の列顧客番号のデー
タをすべて抽出して一覧表示します。重複した顧客番号も表示されます。
customer_num
問合せ結果 2- 12
104
101
104
106
116
112
117
110
111
115
104
117
104
106
110
119
120
121
122
123
124
126
127
問合せ結果に重複する顧客番号が含まれているのは、一部の顧客が複数件の注文を
出しているためです。それぞれの値が現れる頻度を見たい場合は、重複行を表示す
る必要がありますが、どんな値があるかだけを見たい場合もあります。
簡単な SELECT 文の作成
2-19
特定の列の抽出
重複行を避けるには、問合せ 2- 13 で示すように、選択対象の並びの先頭にキー
ワード DISTINCT、または、キーワード UNIQUE を含めます。
問合せ 2- 13
SELECT DISTINCT customer_num FROM orders
SELECT UNIQUE customer_num FROM orders
リストを読みやすくするには、問合せ 2- 13 を使用して、問合せ結果 2- 13 で示すよ
うに表 orders の顧客番号のみの表示にします。
customer_num
101
104
106
110
111
112
115
116
117
119
120
121
122
123
124
126
127
2-20
Informix Guide to SQL: Tutorial
問合せ結果 2- 13
特定の列の抽出
ある顧客からの電話の問合せで顧客注文番号 DM354331 を見つけることが必要に
なったとします。表 orders のすべての顧客注文番号をリストするために、問合せ 214 で示す文を使用します。
問合せ 2- 14
SELECT po_num FROM orders
この SELECT 文の問合せ結果は、問合せ結果 2- 14 に示すように、表 orders の列
po_num をすべて抽出して表示します。
po_num
問合せ結果 2- 14
B77836
9270
B77890
8006
2865
Q13557
278693
LZ230
4745
429Q
B77897
278701
B77930
8052
MA003
PC6782
DM354331
S22942
Z55709
W2286
C3288
W9925
KF2961
簡単な SELECT 文の作成
2-21
特定の列の抽出
しかし、このデータ一覧は便利な順番に並んでいるとはいえません。ORDER BY 節
を追加して列データを昇順でソートすると、問合せ結果 2- 15 で示すように特定の
po_num を見つけやすくすることができます。
問合せ 2- 15
SELECT po_num FROM orders
ORDER BY po_num
po_num
278693
278701
2865
429Q
4745
8006
8052
9270
B77836
B77890
B77897
B77930
C3288
DM354331
KF2961
LZ230
MA003
PC6782
Q13557
S22942
W2286
W9925
Z55709
2-22
Informix Guide to SQL: Tutorial
問合せ結果 2- 15
特定の列の抽出
表から複数の列を抽出するには、それらの列を SELECT 節の選択対象の並びに記述
します。問合せ 2- 16 は、列が選択された順番が、列が作成される順番 ( 左から右 )
となることを示しています。
問合せ 2- 16
SELECT paid_date, ship_date, order_date,
customer_num, order_num, po_num
FROM orders
ORDER BY paid_date, order_date, customer_num
2-15 ページの「複数の列を基にしたソート」に記載されているように、ORDER BY
節を使用して昇順または降順でデータをソートし、多重ソートを実行することがで
きます。問合せ結果 2- 16 の問合せ結果は降順にソートされています。
問合せ結果 2- 16
paid_date
ship_date order_date customer_num
06/03/1998
06/14/1998
06/21/1998
07/10/1998
07/21/1998
07/22/1998
07/31/1998
08/06/1998
08/06/1998
08/21/1998
08/22/1998
08/22/1998
08/22/1998
08/29/1998
08/31/1998
09/02/1998
09/20/1998
05/30/1998 05/22/1998
05/30/1998
06/05/1998 05/31/1998
06/29/1998 06/18/1998
07/12/1998 06/29/1998
07/13/1998 07/09/1998
05/26/1998 05/21/1998
05/23/1998 05/22/1998
06/09/1998 05/24/1998
07/03/1998 06/25/1998
07/06/1998 06/07/1998
06/01/1998 05/20/1998
07/10/1998 06/22/1998
07/13/1998 07/10/1998
07/16/1998 07/11/1998
06/21/1998 06/14/1998
06/29/1998 06/17/1998
07/25/1998 07/23/1998
07/30/1998 07/24/1998
07/03/1998 06/18/1998
07/16/1998 06/27/1998
07/30/1998 07/24/1998
07/16/1998 07/11/1998
106
112
117
117
119
120
101
104
116
106
110
104
104
121
122
111
115
124
127
104
110
126
123
order_num
1004
1006
1007
1012
1016
1017
1002
1003
1005
1014
1008
1001
1013
1018
1019
1009
1010
1021
1023
1011
1015
1022
1020
po_num
8006
Q13557
278693
278701
PC6782
DM354331
9270
B77890
2865
8052
LZ230
B77836
B77930
S22942
Z55709
4745
429Q
C3288
KF2961
B77897
MA003
W9925
W2286
簡単な SELECT 文の作成
2-23
特定の列の抽出
表の複数の列に対して SELECT 節と ORDER BY 節を使用する場合、ORDER BY 節
では、実際の列名ではなくその列名の選択対象の並びでの位置を示す整数を指定す
ることができます。実際の列名を記述するよりも簡単に指定できます。問合せ 2- 17
の文では、問合せ結果 2- 17 のデータと同じデータを抽出して表示します。
問合せ 2- 17
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
問合せ結果 2- 17
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
2-24
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
Informix Guide to SQL: Tutorial
特定の列の抽出
問合せ 2- 18 で示すように、列名に整数を割り当てるとキーワード DESC を
ORDER BY 節に含めることができます。
問合せ 2- 18
SELECT customer_num, order_num, po_num, order_date
FROM orders
ORDER BY 4 DESC, 1
このように指定すると、抽出されたデータは、まず列 order_date の値で降順にソー
トされ、次に列 customer_num の値で昇順にソートされます。
GLS
ORDER BY と NLS( 各国語サポート )
デフォルトでは、INFORMIX データベースサーバは、データベースのデータ用にロ
ケールと呼ばれる米国英語 (U.S.English) の言語環境を使用します。米国英語ロケー
ルでは、コードセットの順番でソートされたデータを指定します。このデフォルト
ロケールでは、ISO 8859-1 のコードセットを使用しています。
ユーザのデータベースに英語以外のデータが含まれている場合は、ORDER BY 節
が、その言語に該当する順番でデータを戻します。問合せ 2- 19 では、SELECT 文
を ORDER BY 節と一緒に使用して表 abonné s を探索し、選択した情報を列 nom の
データ順に並べます。
問合せ 2- 19
SELECT numéro,nom,prénom
FROM abonnés
ORDER BY nom;
この問合せ結果の照合順序は、次のようにシステムによって異なります。
■
列 nom が、文字 (CHAR) 型データ、または、各国語文字 (NCHAR) 型データ
の場合。データベースサーバは文字 (CHAR) 型列のデータをコードセット
に出てくる順序でソートします。データベースサーバは各国語文字
(NCHAR) 型列のデータをロケールの照合部分にリストされている文字の
順序でソートします。英語以外のデータは、その言語でソートした結果を
保存しておくために、各国語文字 (NCHAR) 型列 ( または各国語可変長文
字 (NVARCHAR) 型列 ) に格納します。
■
データベースへのアクセス時に、データベースサーバが英語以外の正しい
ロケールを使用している場合。英語以外のロケールを使用するには、環境
変数 CLIENT_LOCALE および DB_LOCALE を該当するロケール名に設定
する必要があります。
簡単な SELECT 文の作成
2-25
特定の列の抽出
問合せ 2- 19 で予想通りの結果を戻すには、列 nom が、フランス語のロケールを使
用するデータベース内の各国語文字 (NCHAR) 型データでなければなりません。ま
た、より小さい、より大きい、... に等しいなどの演算は、ユーザ指定のロケールの
影響を受けます。英語以外のデータおよびロケールについての詳細は、
『Informix
Guide to GLS Functionality』を参照してください。
問合せ結果 2- 19a と問合せ結果 2-19b は、二つの出力サンプルを示しています。
問合せ結果 2- 19a
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
問合せ結果 2- 19a は、ISO 8859-1 のコードセットの順番に準拠しています。この
コードセットでは、小文字より大文字が優先されるので、アクセント付き文字で始
まる名前 (Ålesund、Étaix、Ötker、および Øverst) をリストの末尾に移動します。
問合せ結果 2-19b
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
2-26
Informix Guide to SQL: Tutorial
特定の列の抽出
問合せ結果 2-19b は、データベースサーバで該当するロケールファイルを参照する
と、英語以外の文字で始まる名前 (Ålesund、Étaix、Ötker、および Øverst) は
ISO8859-1 コードセットとは異なる順番で照合されることを示しています。英語以
外で始まっている名前は、ロケールで正しくソートされます。この場合、大文字と
小文字は区別されません。
部分文字列の選択
文字列の値の一部を選択するには、部分文字列を選択対象の並びに含めます。たと
えば、ある会社で顧客に何かを郵送する場合、郵便番号を基に顧客の地理的分布状
況を事前に把握しておくと便利です。問合せ 2- 20 と同様に問合せを書き込むこと
ができます。
問合せ 2- 20
SELECT zipcode[1,3], customer_num
FROM customer
ORDER BY zipcode
簡単な SELECT 文の作成
2-27
WHERE 節の使用方法
問合せ 2- 20 では、部分文字列で列 zipcode( 州を示す ) の最初の 3 文字と
customer_num 全体を選択して、問合せ結果 2- 20 で示されているように、それらを
郵便番号で昇順にリストします。
問合せ結果 2- 20
zipcode customer_num
021
080
085
198
322
604
740
802
850
850
940
940
940
940
940
940
940
940
940
940
940
940
940
940
941
943
943
946
125
119
122
121
123
127
124
126
128
120
105
112
113
115
104
116
110
114
106
108
117
111
101
109
102
103
107
118
WHERE 節の使用方法
特定の顧客からの注文または特定の顧客サービス代理店からの問合せを確認したい
場合は、WHERE 節を SELECT 文に追加します。
WHERE 節は、比較条件や結合条件を設定する場合にも使用されます。ここでは、
比較条件の設定についてのみ説明します。結合条件については、次の節と第 3 章を
参照してください。
SELECT 文で戻される行のセットはアクティブセットです。1 行のみ返す SELECT
文を特に単一 SELECT 文と呼びます。SQL API で複数の行を抽出するには、カーソ
ルを使用します。詳細は、第 5 章「SQL を使用したプログラミング」と、第 6 章
「SQL プログラムによるデータの更新」を参照してください。
2-28
Informix Guide to SQL: Tutorial
比較条件の作成
比較条件の作成
SELECT 文の WHERE 節で、見たい行を指定します。比較条件はキーワードや演算
子を使用して検索範囲を設定します。
たとえば、一致するかどうかを検査するにはキーワード BETWEEN、IN、LIKE、
MATCHES のうちいずれかを使用します。NULL かどうかを検査するにはキーワー
ド IS NULL を使用します。キーワード NOT とこれらのキーワードを組み合わせて、
否定条件を設定することもできます。
次の表は、キーワードの代わりに WHERE 節で使用して、等値関係を検査する関係
演算子のリストです。
図 2-2
同等関係を検査する関係演算子
演算子
演算
=
等しい
!= または <>
等しくない
>
より大きい
>=
より大きいまたは等しい
<
より小さい
<=
より小さいまたは等しい
文字 (CHAR) 型の式の場合、「より大きい」は、ASCII 照合順序が " ∼より後 " であ
ることを意味します。ASCII コードでは数字が先にきて、その後に英大文字、英小
文字と続きます。『Informix Guide to SQL: Syntax』に記載されている ASCII 文字セッ
トのチャートを参照してください。日付 (DATE) 型と日時 (DATETIME) 型の式の場
合、
「より大きい」は、後の日付を意味し、時間隔 (INTERVAL) 型の式では、より
長い時間を意味します。
重要 : テキスト (TEXT) 型およびバイト (BYTE) 型の列は、NULL かどうかを検査する
場合以外は、文字列式に使用することはできません。
簡単な SELECT 文の作成
2-29
比較条件の作成
前頁に示したキーワードや演算子を WHERE 節に使用すると、次のような動作をす
る比較条件付き問合せを作成できます。
■
特定の値を検索する
■
特定の値を除外する
■
特定の範囲の値を検索する
■
一部の値を検索する
■
NULL を検索する
変数テキストを実行すると、以下に示す基準で検索が行われ、WHERE 節の先行す
るキーワードおよび演算子を使用して比較条件付きの問合せが作成されます。
■
文字列を正確に比較する
■
1 字長のワイルドカードを使用する
■
値の範囲を制限する 1 字長ワイルドカードを使用する
■
可変長ワイルドカードを使用する
■
サブスクリプト付け
これらの問合せのそれぞれの例を次に示します。
特定の行の検索
問合せ 2- 21 で示されているように、関係演算子等号 (=)を使用して行を WHERE 節
に含めます。
問合せ 2- 21
SELECT customer_num, call_code, call_dtime, res_dtime
FROM cust_calls
WHERE user_id = 'maryj'
問合せ 2- 21 では、問合せ結果 2- 21 で示されている行のセットを戻します。
customer_num call_code call_dtime
106 D
121 O
127 I
2-30
res_dtime
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
Informix Guide to SQL: Tutorial
問合せ結果 2- 21
比較条件の作成
特定の行の除外
特定の値の列を含まない行を検索するには、関係演算子 !=、または、<> を使用し
て、WHERE 節に条件を指定します。
問合せ 2- 22 では、問合せの対象が ANSI 標準準拠のデータベースであることを前
提にしています。SELECT 文には、表 customer の所有者、すなわち、この表の作成
者のログイン名が指定されています。この修飾子 ( 所有者名 ) は、表の作成者が現
行ユーザの場合や、データベースが ANSI 標準準拠でない場合必要ありません。し
かしどちらの場合でも修飾子を含めることはできます。所有者の命名については
『Informix Guide to SQL: Syntax』を参照してください。
問合せ 2- 22
SELECT customer_num, company, city, state
FROM odin.customer
WHERE state != 'CA'
SELECT customer_num, company, city, state
FROM odin.customer
WHERE state <> 'CA'
問合せ結果 2- 22 で示されているように、問合せ 2- 22 の二つの SELECT 文では、
ユーザ odin が所有する表 customer において、列 state 内の値と CA は等しくないと
いう指定によって値を除外しています。
customer_num company
119
120
121
122
123
124
125
126
127
128
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
state
Cherry Hill
Phoenix
Wilmington
Princeton
Jacksonville
Bartlesville
Brighton
Denver
Blue Island
Phoenix
NJ
AZ
DE
NJ
FL
OK
MA
CO
NY
AZ
問合せ結果 2- 22
簡単な SELECT 文の作成
2-31
比較条件の作成
行範囲の指定
WHERE 節に行の範囲を指定する方法には何通りかあります。問合せ 2- 23 に、その
中の二つの方法を示します。
問合せ 2- 23
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
問合せ 2- 23 の各 SELECT 文は、列 catalog_num の値の範囲を 10005 から 10008 ま
でと指定しています。最初の文ではキーワードを、2 番目の文では関係演算子をそ
れぞれ使用して、問合せ結果 2- 23 で示されている行の抽出を行います。
catalog_num
stock_num
manu_code
cat_advert
10005
3
HSK
High-Technology Design Expands the Sweet Spot
catalog_num
stock_num
manu_code
cat_advert
10006
3
SHM
Durable Aluminum for High School and Collegiate Athletes
catalog_num
stock_num
manu_code
cat_advert
10007
4
HSK
Quality Pigskin with Joe Namath Signature
catalog_num
stock_num
manu_code
cat_advert
10008
4
HRO
Highest Quality Football for High School
and Collegiate Competitions
問合せ結果 2- 23
表 catalog にはバイト (BYTE) 型のデータがありますが、この列は SELECT 文に指
定されていないことに注意してください。指定しても <BYTE value> と列名に表示
されるのみです。SQL API アプリケーションへの書込みを行うと、PROGRAM 属性
でテキスト (TEXT) 型値とバイト (BYTE) 型値を表示することができます。
2-32
Informix Guide to SQL: Tutorial
比較条件の作成
特定の範囲の行の除外
問合せ 2- 24 では、問合せ結果 2- 24 で示されているように、キーワード NOT
BETWEEN で列 zipcode 内の文字範囲が 94000 から 94999 までの行を実行します。
問合せ 2- 24
SELECT fname, lname, company, city, state
FROM customer
WHERE zipcode NOT BETWEEN '94000' AND '94999'
ORDER BY state
fname
lname
company
city
state
Fred
Frank
Eileen
Jason
Marvin
James
Bob
Cathy
Kim
Chris
Jewell
Lessor
Neelie
Wallack
Hanlon
Henry
Shorter
O’ Brian
Satifer
Putnum
Century* Pro Shop
Phoenix University
Neelie’s Discount Sp
City Sports
Bay Sports
Total Fitness Sports
The Triathletes Club
The Sporting Life
Big Blue Bike Shop
Putnum’s Putters
Phoenix
Phoenix
Denver
Wilmington
Jacksonville
Brighton
Cherry Hill
Princeton
Blue Island
Bartlesville
AZ
AZ
CO
DE
FL
MA
NJ
NJ
NY
OK
問合せ結果 2- 24
一部の値の検索
2-31 ページの「特定の行の除外」と同じく、問合せ 2- 25 の例も ANSI 標準準拠の
データベースを使用するものとしています。これらの例で所有者名を示す修飾子が
引用符で囲まれているのは、英大文字と英小文字を区別するためです。
問合せ 2- 25
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
簡単な SELECT 文の作成
2-33
比較条件の作成
問合せ 2- 25 の各 SELECT 文では、問合せ結果 2- 25 で示されているように、表
Aleta.customer の列 state にサブセット AZ または NJ が含まれている行を抽出しま
す。
問合せ結果 2- 25
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
テキスト (TEXT) 型列またはバイト (BYTE) 型列を検査する
重要 : キーワード IN で、
ことはできません。
問合せ 2- 26 は、ANSI 標準準拠のデータベースに対する問合せの例です。表の所有
者の名前は引用符で囲まれていません。問合せ 2- 25 の SELECT 文は、Aleta. の表
customer を検索し、問合せ 2- 26 の SELECT 文は、ALETA. の表 customer を検索し
ます。ANSI 標準準拠のデータベースは所有者名も含めて表を識別するため、Aleta.
の表 customer と ALETA. の表 customer は異なる二つの表を表すことになります。
問合せ 2- 26
SELECT lname, city, state, phone
FROM Aleta.customer
WHERE state NOT IN ('AZ', 'NJ')
ORDER BY state
2-34
Informix Guide to SQL: Tutorial
比較条件の作成
問合せ 2- 26 では、キーワード NOT IN を追加したため、列 state 内のサブセット AZ
および NJ を除外するように変更されています。この問合せ結果は、問合せ結果 226 のように列 state の値でソートされます。
問合せ結果 2- 26
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
NULL の検索
オプションのキーワード IS NULL または IS NOT NULL を使用して、NULL かどう
かを検査することができます。NULL とはデータが存在していない状態か、または
未知の値のいずれかです。NULL はゼロや空白とは異なります。
問合せ 2- 27 では、問合せ結果 2- 27 で示されているように、NULL の paid_date を含
むすべての行を戻します。
問合せ 2- 27
SELECT order_num, customer_num, po_num, ship_date
FROM orders
WHERE paid_date IS NULL
ORDER BY customer_num
簡単な SELECT 文の作成
2-35
比較条件の作成
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
問合せ結果 2- 27
06/05/1998
06/29/1998
07/12/1998
07/13/1998
複合条件の作成
二つ以上の比較条件またはブール式を結合するには、論理演算子 AND、OR、NOT
を使用します。論理式は TRUE( 真 ) か FALSE( 偽 ) と評価され、NULL が関係する
場合は UNKNOWN( 未知 ) と評価されます。テキスト (TEXT) 型やバイト (BYTE)
型のオブジェクトは、NULL かどうかを検査するとき以外は論理式で使用すること
はできません。
問合せ 2- 28 の SELECT 文では、WHERE 節で論理演算子 AND が二つの比較条件を
結合しています。
問合せ 2- 28
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
問合せでは、問合せ結果 2- 28 で示されているように、NULL の paid_date が含まれ
ていて、NULL の ship_date が含まれていないすべての行を戻します。
order_num customer_num
1004
1007
1012
1016
1017
2-36
106
117
117
119
120
po_num
ship_date
8006
278693
278701
PC6782
DM354331
05/30/1998
06/05/1998
06/29/1998
07/12/1998
07/13/1998
Informix Guide to SQL: Tutorial
問合せ結果 2- 28
比較条件の作成
変数テキスト検索の使用方法
フィールドの部分文字列の検索による変数テキストの問合せには、キーワード
LIKE および MATCHES を使用することができます。キーワード NOT を追加すれ
ば、反対の条件を指定できます。キーワード LIKE は ANSI 標準の SQL に準拠して
いますが、キーワード MATCHES は Informix 製品で拡張されたものです。
変数テキストの検索文字列には、次の表のキーワード LIKE または MATCHES と一
緒にワイルドカードを含めることができます。
図 2-3 LIKE および MATCHES で使用するワイルドカード
記号
意味
LIKE
%
0 または一つ以上の文字に評価します
_
単一の文字に評価します
¥
次の文字の特殊な意義をエスケープします
MATCHES
*
0 または一つ以上の文字に評価します
?
単一の文字 (NULL を除く ) に評価します
[]
単一の文字または値の範囲に評価します
¥
次の文字の特殊な意義をエスケープします
テキスト (TEXT) 型やバイト (BYTE) 型の列は、LIKE や MATCHES などのキー
ワードでは検査できません。
簡単な SELECT 文の作成
2-37
比較条件の作成
正確な文字列比較の使用方法
次に示す SELECT 文の例は、WHERE 節にキーワード LIKE または MATCHES を使
用するか、関係演算子の等号 (=) を使用して、指定された文字列と正確に一致する
文字列を持つ行を検索します。これまでの例と異なり、ここでは現行データベース
内にない表に対して問合せを行います。表が ANSI 標準準拠データベースに含まれ
てさえいれば、現行データベースに含まれていなくても、アクセスできます。
この章でこれまで使用してきたデータベースは、デモンストレーションデータベー
スですが、次の例の FROM 節で指定している所有者 bubba 作成の表 manatee は、
syzygy という名前の ANSI 標準準拠のデータベース内にあります。現行データベー
スに含まれていない表の定義についての詳細は、
『Informix Guide to SQL: Syntax』を
参照してください。
問合せ 2- 29 の各 SELECT 文では、問合せ結果 2- 29 のように、列 description に単一
ワード helmet が含まれているすべての行を抽出します。
問合せ 2- 29
SELECT * FROM syzygy:bubba.manatee
WHERE description = 'helmet'
ORDER BY mfg_code
SELECT * FROM syzygy:bubba.manatee
WHERE description LIKE 'helmet'
ORDER BY mfg_code
SELECT * FROM syzygy:bubba.manatee
WHERE description MATCHES 'helmet'
ORDER BY mfg_code
stock_no mfg_code
991
991
991
991
991
2-38
ANT
BKE
JSK
PRM
SHR
description
helmet
helmet
helmet
helmet
helmet
unit_price unit
$222.00
$269.00
$311.00
$234.00
$245.00
Informix Guide to SQL: Tutorial
case
case
each
case
case
unit_type
4/case
4/case
4/case
4/case
4/case
問合せ結果 2- 29
比較条件の作成
1 字長のワイルドカードの使用方法
問合せ 2- 30 の SELECT 文は、WHERE 節で 1 字長のワイルドカードを使用する方
法を示しています。また、現行のデータベースに含まれない表への問合せを行って
います。表 stock は、外部のデータベース sloth 内にあります。現行のデータベース
stores7 の外部にない場合、sloth は、meerkat というデータベースサーバ上にありま
す。
現行のデータベースに含まれないデータベースからの表の選択方法についてはこの
マニュアルの 2-102 ページの「現行データベース以外のデータベースからの表の検
索」と『Informix Guide to SQL: Syntax』を参照してください。
問合せ 2- 30
SELECT * FROM sloth@meerkat:stock
WHERE manu_code LIKE '_R_'
AND unit_price >= 100
ORDER BY description, unit_price
SELECT * FROM sloth@meerkat:stock
WHERE manu_code MATCHES '?R?'
AND unit_price >= 100
ORDER BY description, unit_price
問合せ 2- 30 の各 SELECT 文では、問合せ結果 2- 30 で示されているように、
manu_code の中央の文字が R になっている行のみを抽出します。
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 unit
$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
case
case
case
case
case
case
case
case
case
each
each
each
box
unit_descr
問合せ結果 2- 30
24/case
24/case
10 gloves/case
24/case
4 sets/case
10 pairs/case
24/case
4/case
4/case
each
each
each
10/box
簡単な SELECT 文の作成
2-39
比較条件の作成
キーワード LIKE の後の比較条件 '_R_' とキーワード MATCHES の後の比較条件
'?R?' の 3 文字は、左から右へそれぞれ次のような意味があります。
■
任意の 1 文字
■
文字 R
■
任意の 1 文字
制限 1 字長ワイルドカードのある WHERE 節
問合せ 2- 31 では、A から H までの文字で始まる manu_code を含む行のみを選択し
て、問合せ結果 2- 31 で示されている行を戻します。'[A-H]' は、A から H までの範囲
にある任意の英文字 1 字を表します。キーワード LIKE には、これに相当するワイ
ルドカードはありません。
問合せ 2- 31
SELECT * FROM stock
WHERE manu_code MATCHES '[A-H]*'
ORDER BY description, manu_code, unit_price
問合せ結果 2- 31
stock_num manu_code description
205
205
2
3
1
1
7
ANZ
HRO
HRO
HSK
HRO
HSK
HRO
unit_price unit
case
case
case
case
case
case
case
unit_descr
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
24/case
24/case
24/case
12/case
10 gloves/case
10 gloves/case
24/case
110 ANZ
110 HRO
110 HSK
helmet
helmet
helmet
$244.00 case 4/case
$260.00 case 4/case
$308.00 case 4/case
301
301
313
6
5
8
9
304
304
running shoes
running shoes
swim cap
tennis ball
tennis racquet
volleyball
volleyball net
watch
watch
$95.00
$42.50
$60.00
$48.00
$19.80
$840.00
$20.00
$170.00
$280.00
.
.
.
.
.
.
2-40
ANZ
HRO
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
HRO
Informix Guide to SQL: Tutorial
each
each
box
case
each
case
each
box
box
each
each
12/box
24 cans/case
each
24/case
each
10/box
10/box
比較条件の作成
可変長ワイルドカードの使用
問合せ 2- 32 の SELECT 文は、文字列の末尾にワイルドカードを使用して、列
description の値が bicycle で始まるすべての行を抽出します。
問合せ 2- 32
SELECT * FROM stock
WHERE description LIKE 'bicycle%'
ORDER BY description, manu_code
SELECT * FROM stock
WHERE description MATCHES 'bicycle*'
ORDER BY description, manu_code
各 SELECT 文が、問合せ結果 2- 32 で示されている行を戻します。
問合せ結果 2- 32
stock_num manu_code
102 PRC
102 SHM
114 PRC
107 PRC
106 PRC
101 PRC
101 SHM
105 PRC
105 SHM
description
bicycle brakes
bicycle brakes
bicycle gloves
bicycle saddle
bicycle stem
bicycle tires
bicycle tires
bicycle wheels
bicycle wheels
unit_price unit
$480.00
$220.00
$120.00
$70.00
$23.00
$88.00
$68.00
$53.00
$80.00
case
case
case
pair
each
box
box
pair
pair
unit_descr
4 sets/case
4 sets/case
10 pairs/case
pair
each
4/box
4/box
pair
pair
比較条件の 'bicycle%' または 'bicycle*' は、bicycle の後にゼロ個以上の任意の文字
が続く文字列を表します。bicycle stem の stem の部分がワールドカードに対応しま
す。列 description にこれに該当する値があれば、bicycle 単独の場合も一致します。
問合せ 2- 33 の SELECT 文では、PRC という列 manu_code の値を比較条件に追加し
て、検索範囲を狭くしています。
問合せ 2- 33
SELECT * FROM stock
WHERE description LIKE 'bicycle%'
AND manu_code NOT LIKE 'PRC'
ORDER BY description, manu_code
簡単な SELECT 文の作成
2-41
比較条件の作成
この SELECT 文では、問合せ結果 2- 33 で示されている行のみを抽出します。
問合せ結果 2- 33
stock_num manu_code
102 SHM
101 SHM
105 SHM
description
bicycle brakes
bicycle tires
bicycle wheels
unit_price unit
unit_descr
$220.00 case 4 sets/case
$68.00 box 4/box
$80.00 pair pair
'%cycle' のように比較条件の先頭にワイルドカードを使用して大規模な表に対する
問合せを行うと、実行にかなりの時間を要する場合がよくあります。インデックス
を使用することができないため、すべての行が検索されます。
GLS
MATCHES と英語以外のデータ
デフォルトでは、Informix データベースサーバは、データベースのデータ用にロ
ケールと呼ばれる米国英語 (U.S.English) の言語環境を使用します。このデフォルト
では、ISO 8859-1 のコードセットが使用されます。米国英語のロケールでは
MATCHES で使用されるコードセットの順番が使用されます。
ユーザのデータベースに英語以外のデータが含まれている場合、MATCHES 節では
該当する言語に対して英語以外の正しいコードセットを使用する必要があります。
問合せ 2- 34 は、WHERE 節内に MATCHES 節のある SELECT 文を使用して表
abonné s を検索し、列 nom 内のデータと選択した情報を比較します。
問合せ 2- 34
SELECT numéro,nom,prénom
FROM abonnés
WHERE nom MATCHES '[E-P]*'
ORDER BY nom;
この問合せでの比較結果は、nom が文字 (CHAR) 型列または各国語文字 (NCHAR)
型列のいずれの場合でも同じです。データベースサーバが使用するソート順は、ロ
ケールがどの文字が E から P の範囲にあるか判断するために指定するソート順で
す。この機能は例外です。原則としてデータベースサーバでは、文字 (CHAR) 型列
と可変長文字 (VARCHAR) 型列の照合をコードセットの順で、各国語文字
(NCHAR) 型列と各国語可変長文字 (NVARCHAR) 型列の照合をローケールが指定し
たソート順で行います。
2-42
Informix Guide to SQL: Tutorial
比較条件の作成
問合せ結果 2- 34a では、Étaix、Ötker、および Øverst を含む行が選択されないためリ
ストされません。ISO 8859-1 のコードセットの順番によると、列 nom では、各名
前のアクセント付きの先頭文字が E から P の MATCHES の範囲にないためです。
問合せ結果 2- 34a
numéro
13607
13602
13604
13610
13613
13603
13611
nom
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
列 nom が文字 (CHAR) 型の場合、データベースサーバはコードセットの順序を使用
します。また列が各国語文字 (NCHAR) 型データの場合は、ローカライズした順番
が使用されるので、デフォルト以外のロケールを指定します。
問合せ結果 2- 34a では、データベースサーバがロケール別の比較を行うので、
Étaix、Ötker、および Øverst を含む行がリストに含まれます。
問合せ結果 2-34b
numéro
nom
prénom
13608
13607
13602
13604
13610
13613
13603
13611
13605
13614
Étaix
Hammer
Hämmer
LaForêt
LeMaître
Llanero
Montaña
Oatfield
Ötker
Øverst
Émile
Gerhard
Greta
Jean-Noël
Héloïse
Gloria Dolores
José Antonio
Emily
Hans-Jürgen
Per-Anders
英語以外のデータおよびロケールについての詳細は、
『Informix Guide to GLS
Functionality』を参照してください。
簡単な SELECT 文の作成
2-43
比較条件の作成
特殊文字の比較
問合せ 2- 35 の SELECT 文は、キーワード LIKE または MATCHES の後にキーワー
ド ESCAPE を追加して、特殊文字がワールドカードと誤って解釈されるのを防い
でいます。
問合せ 2- 35
SELECT * FROM cust_calls
WHERE res_descr LIKE '%!%%' ESCAPE '!'
キーワード ESCAPE では、後続の文字を保護してワイルドカードではなくデータと
して解釈するために、エスケープ文字 ( この例の場合は !) を指定します。この例で
は、エスケープ文字を指定すると、中央のパーセント記号 (%) がデータとして処理
されます。キーワード ESCAPE を使用すると、ワイルドカード LIKE のパーセント
記号 (%) で、列 res_descr 内のパーセント記号 (%) のオカレンスを検索することがで
きます。この問合せでは、問合せ結果 2- 35 で示されている行を抽出します。
customer_num 116
call_dtime
1997-12-21 11:24
user_id
mannyn
call_code
I
call_descr
Second complaint from this customer! Received
two cases right-handed outfielder gloves
(1 HRO) instead of one case lefties.
res_dtime
1997-12-27 08:19
res_descr
Memo to shipping (Ava Brown) to send case of
left-handed 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
問合せ結果 2- 35
WHERE 節での部分文字列の使用方法
問合せ 2- 36 に示すように、変数を部分文字列に使用することはできません。
問合せ 2- 36
SELECT catalog_num, stock_num, manu_code, cat_advert,
cat_descr
FROM catalog
WHERE cat_advert[1,4] = 'High'
問合せ結果 2- 36 に示すように、サブスクリプト [1,4] を使用すると、問合せ 2- 36
では、列 cat_advert の最初の 4 文字が High であるすべての行を抽出します。
2-44
Informix Guide to SQL: Tutorial
比較条件の作成
問合せ結果 2- 36
catalog_num
stock_num
manu_code
cat_advert
10004
2
HRO
Highest Quality Ball Available, from
Hand-Stitching 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
stock_num
manu_code
cat_advert
10008
4
HRO
Highest Quality Football for High School and
Collegiate Competitions
cat_descr
NFL-style, pigskin.
catalog_num
10012
stock_num
6
manu_code
SMT
cat_advert
High-Visibility Tennis, Day or Night
cat_descr
Soft yellow color for easy visibility in sunlight or
artificial light.
catalog_num
stock_num
manu_code
cat_advert
10043
202
KAR
High-Quality Woods Appropriate for High School
Competitions or Serious Amateurs
cat_descr
Full set of woods designed for precision control and
power performance.
catalog_num
stock_num
manu_code
cat_advert
10045
204
KAR
High-Quality Beginning Set of Irons
Appropriate for High School Competitions
cat_descr
Ideally balanced for optimum control. Nylon covered shaft.
catalog_num
stock_num
manu_code
cat_advert
cat_descr
10068
310
ANZ
High-Quality Kickboard
簡単な SELECT 文の作成
2-45
特定の行を選択するための FIRST 節の使用
特定の行を選択するための FIRST 節の使用
SELECT 文に FIRST 節を含めて、SELECT 文の条件に一致する最初の行を、指定さ
れた数だけ返すようにすることができます。キーワード FIRST のすぐ後に数値を入
れて、問合せで返す行の最大数を指定します。FIRST 節を含む SELECT 文が実行さ
れたときにデータベース サーバが返す行は、その SELECT 文に ORDER BY 節も含
まれるかどうかにより異なります。
SELECT 文が副問合せ、またはビュー定義の一部であるときは、FIRST 節は使用で
きません。
『Informix Guide to SQL: Syntax』の SELECT 文
FIRST 節の使用上の制約については、
の説明を参照してください。
ORDER BY 節のない FIRST 節
FIRST 節を使用する SELECT 文に ORDER BY 節を含めない場合は、SELECT 文の
条件に一致する行はどれでも返される可能性があります。言い替えると、適合する
行のどれを返すかをデータベース サーバが決定し、問合せ結果はオプティマイザが
選択する問合せ計画により異なります。
問合せ 2- 37 では、FIRST 節を使用して表 state の最初の 5 行を返します。
問合せ 2- 37
SELECT FIRST 5 *
FROM state
問合せ結果 2- 37
code sname
AK
HI
CA
OR
WA
2-46
Alaska
Hawaii
California
Oregon
Washington
Informix Guide to SQL: Tutorial
特定の行を選択するための FIRST 節の使用
すべての列の名前、および表に含まれるデータの型だけを知りたいとき、または多
数の行を返すような問合せをテストしたいときなどに FIRST 節を使用できます。問
合せ 2- 38 は、FIRST 節を使用して表の先頭行の列の値を返す方法を示しています。
問合せ 2- 38
SELECT FIRST 1 *
FROM orders
問合せ結果 2- 38
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
ORDER BY 節のある FIRST 節
FIRST 節を使用する SELECT 文に ORDER BY 節を含めて、指定された列について
の最高値または最低値が入ったいくつかの行を返すことができます。問合せ 2- 38
には ORDER BY 節が含まれ、表 state の ( アルファベット順の ) 最初の 5 つを返し
ます。問合せ 2- 39 は ORDER BY 節を除いて他は問合せ 2- 37 と同じですが、問合
せ 2- 37 とは異なる行のセットを返します。
問合せ 2- 39
SELECT FIRST 5 *
FROM state ORDER BY sname
問合せ結果 2- 39
code sname
AL
AK
AZ
AR
CA
Alabama
Alaska
Arizona
Arkansas
California
簡単な SELECT 文の作成
2-47
特定の行を選択するための FIRST 節の使用
問合せ 2- 40 は、ORDER BY 節と一緒に FIRST 節を使用して、表 stock にリストさ
れた項目の中の最も高価な 10 項目を検出する方法を示しています。
問合せ 2- 40
SELECT FIRST 10 description, unit_price
FROM stock ORDER BY unit_price DESC
問合せ結果 2- 40
description
unit_price
football
volleyball
baseball gloves
18-spd, assmbld
irons/wedge
basketball
12-spd, assmbld
10-spd, assmbld
football
bicycle brakes
$960.00
$840.00
$800.00
$685.90
$670.00
$600.00
$549.00
$499.99
$480.00
$480.00
ユニオン問合せの FIRST 節
AD/XP
Informix Dynamic Server with Advanced Decision Support and Extended Parallel Options を
使用する場合は、FIRST 節を使用して、ユニオン問合せから得られた行の最初のい
くつかを選択することもできます。問合せ 2- 41 では、FIRST 節を使用して、表
stock と表 item のユニオンの最初の 5 行を返します。
問合せ 2- 41
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
問合せ結果 2- 41
stock_num manu_code
311
9
301
6
204
2-48
SHM
ANZ
HRO
ANZ
KAR
Informix Guide to SQL: Tutorial
式と導出値
式と導出値
SELECT 文の SELECT 節には、列名以外の要素も指定できます。SELECT 節を使用
して、一つ以上の列の値に対して計算を行い、そこから導き出された結果を表示す
ることができます。これを実行するには選択対象の並びで式をリストします。
式の基本構成要素は、列名、定数、引用符付き文字列、キーワードです。これらを
演算子で自由に組み合わせて式を構成します。また、SELECT 文をプログラムに埋
め込むと、式にホスト変数 ( プログラムデータ ) を含めることができます。
算術式
算術式は、次にリストされている一つ以上の算術演算子から構成されて数値を算出
します。
演算子
演算
+
addition
-
subtraction
*
multiplication
/
division
重要 : テキスト (TEXT) 型とバイト (BYTE) 型の列は、算術式では使用できません。
簡単な SELECT 文の作成
2-49
式と導出値
算術演算子は、データベース内のデータを実際に変更することなく、指定した計算
の結果を確認することができます。INTO TEMP 節を追加して、詳細な参照計算、
即時レポート用に変更済みデータを一時表に保存することができます。問合せ 2- 42
では、列 unit_price が 400 ドル以上の場合、列 unit_price の 7 パーセントの売上税を
計算します ( データベース内のデータは更新しません )。
問合せ 2- 42
SELECT stock_num, description, unit, unit_descr,
unit_price, unit_price * 1.07
FROM stock
WHERE unit_price >=400
DB-Access またはリレーショナルオブジェクトマネージャを使用すると、問合せ結
果 2- 42 で示されているように、計算結果は列 expression に表示されます。
問合せ結果 2- 42
stock_num description
1
1
4
4
7
8
102
111
112
113
203
2-50
baseball gloves
baseball gloves
football
football
basketball
volleyball
bicycle brakes
10-spd, assmbld
12-spd, assmbld
18-spd, assmbld
irons/wedge
unit
unit_descr
case
case
case
case
case
case
case
each
each
each
case
10 gloves/case
10 gloves/case
24/case
24/case
24/case
24/case
4 sets/case
each
each
each
2 sets/case
Informix Guide to SQL: Tutorial
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.0000
$481.5000
$1027.2000
$513.6000
$642.0000
$898.8000
$513.6000
$534.9893
$587.4300
$733.9130
$716.9000
式と導出値
問合せ 2- 43 では、注文量が 5 より少ない場合、6.50 ドルの追加料金を計算します。
問合せ 2- 43
SELECT item_num, order_num, quantity,
total_price, total_price + 6.5
FROM items
WHERE quantity < 5
DB-Access またはリレーショナルオブジェクトマネージャを使用すると、問合せ結
果 2- 43 で示されているように、計算結果は列 expression に表示されます。
問合せ結果 2- 43
item_num
order_num
quantity
total_price
(expression)
1
1
2
1
2
1
2
3
4
.
.
.
1
2
3
4
1
2
3
1
2
3
4
5
6
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
1021
1021
1021
1021
1022
1022
1022
1023
1023
1023
1023
1023
1023
2
3
3
2
1
2
2
2
2
1
1
1
1
$75.00
$225.00
$690.00
$624.00
$40.00
$96.00
$96.00
$40.00
$116.00
$80.00
$228.00
$170.00
$190.00
$81.50
$231.50
$696.50
$630.50
$46.50
$102.50
$102.50
$46.50
$122.50
$86.50
$234.50
$176.50
$196.50
簡単な SELECT 文の作成
2-51
式と導出値
問合せ 2- 44 は (DB-Access またはリレーショナルオブジェクトマネージャを使用し
た場合 )、顧客の請求を受け取った時 (call_dtime) からその請求内容を処理した時
(res_dtime) までの間隔を日、時、分の単位で計算し、列 expression に表示した例で
す。
問合せ 2- 44
SELECT customer_num, user_id, call_code,
call_dtime, res_dtime - call_dtime
FROM cust_calls
ORDER BY user_id
customer_num user_id
116
116
106
121
127
110
119
mannyn
mannyn
maryj
maryj
maryj
richc
richc
call_code
call_dtime
I
I
D
O
I
L
B
1997-12-21
1997-11-28
1998-06-12
1998-07-10
1998-07-31
1998-07-07
1998-07-01
(expression)
11:24
13:34
08:20
14:05
14:30
10:24
15:00
問合せ結果 2- 44
5 20:55
0 03:13
0 00:05
0 00:01
0 00:06
0 17:21
表示ラベルの使用
表示ラベルを計算済みデータまたは導出データの列に設定して、デフォルトの列の
ヘッダ expression と置き換えることができます。問合せ 2- 42、問合せ 2- 43、および
問合せ 2- 44 では、導出データを列 (expression) に表示します。また、問合せ 2- 45
では、導出値が表示されますが、その導出値を表示する列には、説明のためのヘッ
ダ taxed が含まれます。
問合せ 2- 45
SELECT stock_num, description, unit, unit_descr,
unit_price, unit_price * 1.07 taxed
FROM stock
WHERE unit_price>=400
2-52
Informix Guide to SQL: Tutorial
式と導出値
問合せ結果 2- 45 ではラベル taxed が、演算結果 unit_price*1.07 を表示する選択対
象の並びに当てられていることを示しています。
問合せ結果 2- 45
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
unit_descr
unit_price
case
case
case
case
case
case
case
each
each
each
case
10 gloves/case
10 gloves/case
24/case
24/case
24/case
24/case
4 sets/case
each
each
each
2 sets/case
$800.00
$450.00
$960.00
$480.00
$600.00
$840.00
$480.00
$499.99
$549.00
$685.90
$670.00
taxed
$856.0000
$481.5000
$1027.2000
$513.6000
$642.0000
$898.8000
$513.6000
$534.9893
$587.4300
$733.9130
$716.9000
問合せ 2- 46 では、ラベル surcharge を、演算結果 total_price + 6.50 を表示する列に
定義します。
問合せ 2- 46
SELECT item_num, order_num, quantity,
total_price, total_price + 6.5 surcharge
FROM items
WHERE quantity < 5
問合せ結果 2- 46 で示されているように、出力では、列に surcharge というラベルが
付きます。
item_num
.
.
.
2
3
4
1
2
1
1
2
3
4
1
2
.
.
.
order_num
1013
1013
1013
1014
1014
1015
1016
1016
1016
1016
1017
1017
1
1
2
1
1
1
2
3
1
1
4
1
quantitytotal_pricesurcharge
$36.00
$48.00
$40.00
$960.00
$480.00
$450.00
$136.00
$90.00
$308.00
$120.00
$150.00
$230.00
問合せ結果 2- 46
$42.50
$54.50
$46.50
$966.50
$486.50
$456.50
$142.50
$96.50
$314.50
$126.50
$156.50
$236.50
簡単な SELECT 文の作成
2-53
式と導出値
問合せ 2- 47 では、ラベル label を日時 (DATETIME) 型の列 res_dtime から日時
(DATE-TIME) 型の列 call_dtime を減算した結果を表示する列に設定します。
問合せ 2- 47
SELECT customer_num, user_id, call_code,
call_dtime, res_dtime - call_dtime span
FROM cust_calls
ORDER BY user_id
問合せ結果 2- 47 で示されているように、出力では列に span というラベルが付きま
す。
問合せ結果 2- 47
customer_num user_id
116
116
106
121
127
110
119
mannyn
mannyn
maryj
maryj
maryj
richc
richc
call_code
call_dtime
span
I
I
D
O
I
L
B
1997-12-21 11:24
1997-11-28 13:34
1998-06-12 08:20
1998-07-10 14:05
1998-07-31 14:30
1998-07-07 10:24
1998-07-01 15:00
5 20:55
0 03:13
0 00:05
0 00:01
0 00:06
0 17:21
CASE 式
CASE 式は、プログラミング言語の CASE 文の概念に似た条件式です。データを表
示する方法を変えたいときに、CASE 式を使用します。CASE 式を使用すると、使
用できるいくつかの結果の中から、条件テストで TRUE となったものが戻ります。
たとえば配偶者の有無が数値 1、2、3、4 で表され、それぞれ未婚、既婚、離婚、
死別という意味が対応付けられた列を考えます。場合によっては、データベースに
効率的に格納するために短い値 (1、2、3、4) が適していますが、従業員には、詳し
い値 ( 未婚、既婚、離婚、死別 ) のほうが都合がよいことがあります。CASE 式は、
値の異なるセット間のこのような変換を簡単に実行できます。
2-54
Informix Guide to SQL: Tutorial
式と導出値
次の例は、複数の WHEN 節を使用する CASE 文です。この文は、表 stock の列
manu_code について、より詳しい値を返します。WHEN 条件に真のものが 1 つもな
い場合は、NULL がデフォルトの結果として戻ります (ELSE NULL 節は省略できま
す )。
SELECT
CASE
WHEN manu_code
WHEN manu_code
WHEN manu_code
WHEN manu_code
ELSE NULL
END
FROM stock;
=
=
=
=
"HRO" THEN "Hero"
"SHM" THEN "Shimara"
"PRC" THEN "ProCycle"
"ANZ" THEN "Anza"
CASE 式の中に WHEN 節を少なくとも 1 つ含める必要があります。この後の
WHEN 節と ELSE 節は任意です。真になる WHEN 条件が 1 つもない場合は、結果
の値は NULL 値です。IS NULL 式を使用して、NULL の結果を操作できます。
NULL 値の処理については、『Informix Guide to SQL: Syntax』を参照してください。
次の例は、簡単な CASE 式を示しています。この式は、顧客にまだ出荷されていな
い注文を表 orders から抽出し、これを示す文字列の値を返します。
問合せ 2- 48
CASE
WHEN ship_date IS NULL
THEN "order not shipped"
END
FROM orders;
簡単な SELECT 文の作成
2-55
式と導出値
問合せ結果 2- 48
order_num order_date
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
(expression)
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
order not shipped
CASE 式を使用して列を更新する方法については、4-16 ページの「CASE 式を使用
する列の更新」を参照してください。
導出列を基にしたソート
問合せ 2- 49 で示されているように、式として ORDER BY 節を使用すると、式に設
定した表示ラベルまたは整数を使用することができます。
問合せ 2- 49
SELECT customer_num, user_id, call_code,
call_dtime span
FROM cust_calls
ORDER BY span
call_dtime, res_dtime -
問合せ 2- 49 では、問合せ 2- 47 と同様に、表 cust_calls から同じデータを抽出しま
す。問合せ 2- 49 では、問合せ結果 2- 49 で示されているように、ORDER BY 節を使
用して、列 span 内の導出値で昇順にデータを表示します。
2-56
Informix Guide to SQL: Tutorial
SELECT 文での関数の使用
customer_num
127
121
106
110
116
119
116
user_id
mary
maryj
maryj
richc
mannyn
richc
mannyn
call_code
I
O
D
L
I
B
I
call_dtime
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
問合せ結果 2- 49
0 00:01
0 00:05
0 00:06
0 03:13
0 17:21
5 20:55
問合せ 2- 50 では、res_dtime - call_dtime の演算結果を整数で表示して、問合せ結
果 2- 49 で表示されている行を抽出します。
問合せ 2- 50
SELECT customer_num, user_id, call_code,
call_dtime span
FROM cust_calls
ORDER BY 5
call_dtime, res_dtime -
SELECT 文での関数の使用
列名と演算子と同様に、式には、一つまたは複数の関数を含むことができます。
この節では集計関数、時刻関数、変換関数、文字列操作関数、またその他の関数の
使い方について説明しています。
次の SQL 関数とその他の SQL 関数の構文についての説明は、
『Informix Guide to
SQL: Syntax』の式セグメントを参照してください。
集計関数
すべての Informix データベース サーバは、次の集計関数をサポートします。
✮
AVG
✮
COUNT
✮
MAX
✮
MIN
✮
RANGE
✮
STDEV
簡単な SELECT 文の作成
2-57
SELECT 文での関数の使用
✮
SUM
✮
VARIANCE
集計関数は、選択したすべての行に関連した値を使用し、行自体ではなく行につい
ての情報を戻します。
重要: 集計関数をテキスト(TEXT)型列やバイト(BYTE)型列とともに使用することは
できません。
集合は、表内のグループ行についての情報をまとめる際に多く使用されます。この
集合の使用方法については、第 3 章「高度な SELECT 文の作成」で記載されていま
す。集計関数を表全体に適用すると、結果は、選択したすべての行をまとめた単一
行となります。
COUNT 関数の使用
問合せ 2- 51 では、表 stock 内の行の合計数をカウントして表示します。
問合せ 2- 51
SELECT COUNT(*)
FROM stock
問合せ結果 2- 51
(count(*))
73
問合せ 2- 51 では、特定の行をカウントする際に WHERE 節を表 stock に含めます。
この場合、SHM という manu_code を持つ行がカウント対象となります。
問合せ 2- 52
SELECT COUNT (*)
FROM stock
WHERE manu_code = 'SHM'
問合せ結果 2- 52
(count(*))
17
2-58
Informix Guide to SQL: Tutorial
SELECT 文での関数の使用
キーワード DISTINCT( またはキーワード UNIQUE) と問合せ 2- 53 に示されている
列名を含めると、表 stock 内の別のメーカーコード数を計算することができます。
問合せ 2- 53
SELECT COUNT (DISTINCT manu_code)
FROM stock
問合せ結果 2- 53
(count)
9
AVG 関数の使用
問合せ 2- 54 では、表 stock 内のすべての行の平均 unit_price を計算します。
問合せ 2- 54
SELECT AVG (unit_price)
FROM stock
問合せ結果 2- 54
(avg)
$197.14
問合せ 2- 55 では、SHM という manu_code を持つ表 stock 内の行の平均 unit_price を
計算します。
問合せ 2- 55
SELECT AVG (unit_price)
FROM stock
WHERE manu_code = 'SHM'
(avg)
問合せ結果 2- 55
$204.93
簡単な SELECT 文の作成
2-59
SELECT 文での関数の使用
MAX 関数と MIN 関数の使用
同じ SELECT 文の中で、集計関数を組み合せて使用することができます。たとえば
問合せ 2- 56 が示すように、MAX 関数と MIN 関数の両方を選択対象の並びで使用
できます。
問合せ 2- 56
SELECT MAX (ship_charge), MIN (ship_charge)
FROM orders
問合せ 2- 56 では、問合せ結果 2- 56 で示されているように、表 orders 内の
ship_charge の最大値および最小値を検索して表示します。
(max)
(min)
$25.20
$5.00
問合せ結果 2- 56
SUM 関数の使用
問合せ 2- 57 では、1998 年 7 月 13 日に出荷した注文合計 ship_weight を計算します。
問合せ 2- 57
SELECT SUM (ship_weight)
FROM orders
WHERE ship_date = '07/13/1998'
問合せ結果 2- 57
(sum)
130.5
RANGE 関数の使用
RANGE 関数は、母集団のサンプルの変動範囲を計算します。つまりこの関数は、
最大値と最小値の差を計算します。
2-60
Informix Guide to SQL: Tutorial
SELECT 文での関数の使用
RANGE 関数は、数値の列だけに使用できます。問合せ 2- 58 では、表 stock の項目
の価格の変動範囲を表示します。
問合せ 2- 58
SELECT RANGE(unit_price) FROM stock
問合せ結果 2- 58
(range)
955.50
問合せ 2- 59 に示すように、GROUP BY 節を含む問合せでは、RANGE 関数は他の
集計関数と同様にグループ内の行に適用されます。
問合せ 2- 59
SELECT RANGE(unit_price) FROM stock
GROUP BY manu_code
問合せ結果 2- 59
(range)
820.20
595.50
720.00
225.00
632.50
0.00
460.00
645.90
425.00
STDEV 関数の使用
STDEV 関数は、母集団のサンプルの標準偏差を計算します。つまりこの関数は、
VARIANCE 関数の平方根を計算します。
STDEV 関数は、数値の列だけに適用できます。次の問合せでは、母集団の標準偏
差を表示します。
SELECT STDEV(age) FROM u_pop WHERE u_pop.age > 0
簡単な SELECT 文の作成
2-61
SELECT 文での関数の使用
次の例に示すように、GROUP BY 節を含む問合せでは、STDEV 関数は他の集計関
数と同様にグループ内の行に適用されます。
SELECT STDEV(age) FROM u_pop
GROUP BY birth
WHERE STDEV(age) > 0
指定された列のすべての値が NULL である場合を除いて、NULL 値は無視されま
す。すべての列の値が NULL の場合、STDEV 関数はその列には NULL を返します。
『Informix Guide to SQL: Syntax』の式に関する節を
STDEV 関数の詳細については、
参照してください。
VARIANCE 関数の使用
VARIANCE 関数は、値のサンプルの分散を母集団の分散の不偏推定値として返し
ます。この関数は、次の値を計算します。
(SUM(Xi**2) - (SUM(Xi)**2)/N)/(N-1)
この例では、Xi は列の各値であり、N は列の値の総数です。VARIANCE 関数は、
数値の列だけに適用できます。次の問合せでは、母集団の分散を表示します。
SELECT VARIANCE(age) FROM u_pop WHERE u_pop.age > 0
次の例に示すように、GROUP BY 節を含む問合せでは、VARIANCE 関数は他の集
計関数と同様にグループ内の行に適用されます。
SELECT VARIANCE(age) FROM u_pop
GROUP BY birth
WHERE VARIANCE(age) > 0
指定された列のすべての値が NULL である場合を除いて、NULL 値は無視されま
す。すべての列値が NULL の場合、VARIANCE 関数はその列には NULL を返しま
す。
VARIANCE 関数の詳細については、『Informix Guide to SQL: Syntax』の式に関する
節を参照してください。
2-62
Informix Guide to SQL: Tutorial
SELECT 文での関数の使用
式への関数の適用
問合せ 2- 60 は、関数を式の中で使用して、その結果に表示ラベルを付ける方法を
示しています。
問合せ 2- 60
SELECT MAX (res_dtime - call_dtime) maximum,
MIN (res_dtime - call_dtime) minimum,
AVG (res_dtime - call_dtime) average
FROM cust_calls
問合せ 2- 60 は、顧客の注文を受け取ってから処理するまでの時間 ( 日、時間、分
の単位 ) の最大値、最小値、および平均値を計算して表示し、さらにその値に適切
なラベルを付けます。問合せ結果 2- 60 に、この 3 種類の時間を示します。
問合せ結果 2- 60
maximum
minimum
average
5 20:55
0 00:01
1 02:56
時刻関数
DAY、MDY、MONTH、WEEKDAY、および YEAR の時刻関数は、問合せの
SELECT 節または WHERE 節のどちらの場合でも使用することができます。これら
の時刻関数は、関数の呼出しに使用する式または引数に対応する値を戻します。ま
た CURRENT 関数で現在の日付と時刻の値を戻したり、EXTEND 関数で日付
(DATE) 型値または日時 (DATETIME) 型値の精度を調整することができます。
DAY 関数と CURRENT 関数の使用
問合せ 2- 61 では、二つの expression という列に列 call_dtime および res_dtime の日
付を戻します。
問合せ 2- 61
SELECT customer_num, DAY (call_dtime), DAY (res_dtime)
FROM cust_calls
簡単な SELECT 文の作成
2-63
SELECT 文での関数の使用
customer_num
(expression)
(expression)
106
110
119
121
127
116
116
12
7
1
10
31
28
21
12
7
2
10
問合せ結果 2- 61
28
27
問合せ 2- 62 では、DAY 関数と CURRENT 関数で列の値と現在の日付を比較しま
す。この問合せでは、現在の日付より以前の日付が含まれている行のみを選択しま
す。
問合せ 2- 62
SELECT customer_num, DAY (call_dtime), DAY (res_dtime)
FROM cust_calls
WHERE DAY (call_dtime) <DAY (CURRENT)
問合せ結果 2- 62
customer_num
(expression)
(expression)
106
110
119
121
12
7
1
10
12
7
2
10
問合せ 2- 63 では、CURRENT 関数の別の使用方法として、現在の日付より以前の
日付が含まれている行を選択します。
問合せ 2- 63
SELECT customer_num, call_code, call_descr
FROM cust_calls
WHERE call_dtime <CURRENT YEAR TO DAY
2-64
Informix Guide to SQL: Tutorial
SELECT 文での関数の使用
customer_num
call_code
call_descr
106
D
Order was received, but two of the cans of ANZ tennis balls
within the case were empty
customer_num
call_code
call_descr
116
I
Received plain white swim caps (313 ANZ) instead of navy with
team logo (313 SHM)
customer_num
116
call_code
I
call_descr
Second complaint from this customer! Received two cases
handed outfielder gloves (1 HRO) instead of one case
lefties.
問合せ結果 2- 63
right-
MONTH 関数の使用
問合せ 2- 64 では、MONTH 関数を使用して顧客からの請求を受け取って処理した
月を抽出して表示し、結果を示す列の表示ラベルを使用します。しかし通信コン
ポーネントは実際には存在します。
問合せ 2- 64
SELECT customer_num,
MONTH (call_dtime) call_month,
MONTH (res_dtime) res_month
FROM cust_calls
customer_num
call_month
res_month
106
110
119
121
127
116
116
6
7
7
7
7
11
12
6
7
7
7
問合せ結果 2- 64
11
12
簡単な SELECT 文の作成
2-65
SELECT 文での関数の使用
問合せ 2- 65 では、MONTH 関数、キーワード、DAY、および CURRENT を使用し
て、DAY が現在の日付より以前である場合、顧客からの請求を受け取って処理し
た月を表示します。
問合せ 2- 65
SELECT customer_num,
MONTH (call_dtime) called,
MONTH (res_dtime) resolved
FROM cust_calls
WHERE DAY (res_dtime) <DAY (CURRENT)
問合せ結果 2- 65
customer_num
called
resolved
106
119
121
6
7
7
6
7
7
WEEKDAY 関数の使用
問合せ 2- 66 では、WEEKDAY 関数を使用して顧客からの請求を受け取って処理し
た曜日 (0 は日曜日、1 は月曜日など ) を示し、式の列にラベルを付けます。
問合せ 2- 66
SELECT customer_num,
WEEKDAY (call_dtime) called,
WEEKDAY (res_dtime) resolved
FROM cust_calls
ORDER BY resolved
customer_num
called
resolved
127
110
119
121
116
106
116
3
0
1
3
3
3
5
0
2
3
3
3
4
2-66
Informix Guide to SQL: Tutorial
問合せ結果 2- 66
SELECT 文での関数の使用
問合せ 2- 67 では、COUNT 関数と WEEKDAY 関数を使用して、週末に顧客から受
け取った請求の数をカウントします。この種の SELECT 文を使用すると、顧客から
の請求パターンがどのようなものか、または時間外手当が必要かどうかを示すこと
ができます。
問合せ 2- 67
SELECT COUNT(*)
FROM cust_calls
WHERE WEEKDAY (call_dtime) IN (0,6)
問合せ結果 2- 67
(count(*))
4
YEAR 関数の使用
問合せ 2- 68 では、call_dtime が今年の 1 月 1 日より以前の日付が含まれている行を
抽出します。
問合せ 2- 68
SELECT customer_num, call_code,
YEAR (call_dtime) call_year,
YEAR (res_dtime) res_year
FROM cust_calls
WHERE YEAR (call_dtime) < YEAR (TODAY)
問合せ結果 2- 68
customer_num call_code
116 I
116 I
call_year
res_year
1997
1997
1997
1997
日時 (DATETIME) 型値のフォーマット
問合せ 2- 69 では、EXTEND 関数を使用して指定したサブフィールドのみを表示す
ることで二つの日時 (DATETIME) 型値に制限を設定します。
問合せ 2- 69
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
簡単な SELECT 文の作成
2-67
SELECT 文での関数の使用
問合せ結果 2- 69 では、列 call_time および res_time の月から分までの範囲を戻して、
作業負荷を示します。
customer_num
127
106
119
110
121
116
116
call_time
07-31
06-12
07-01
07-07
07-10
11-28
12-21
問合せ結果 2- 69
res_time
14:30
08:20
15:00
10:24
14:05
13:34
11:24
06-12
07-02
07-07
07-10
11-28
12-27
08:25
08:21
10:30
14:06
16:47
08:19
日付変換関数
IDS
次の変換関数は、日付と文字値との間で変換処理を行います。
✮
DATE
✮
TO_CHAR
✮
TO_DATE
日付変換関数は、式を使用する部分ならどこででも使用できます。
DATE 関数の使用方法
DATE 関数は、文字列を日付 (DATE) 型値に変換します。問合せ 2- 70 では、日時
(DATETIME) 型値との比較のために、DATE 関数で文字列を日付 (DATE) 型値に変
換します。この問合せでは、call_dtime が指定された日付 (DATE) 型値より後の値で
ある場合だけ、日時 (DATETIME) 型値を抽出します。
問合せ 2- 70
SELECT customer_num, call_dtime, res_dtime
FROM cust_calls
WHERE call_dtime>DATE('12/31/97')
customer_num call_dtime
106
110
119
121
127
2-68
1998-06-12
1998-07-07
1998-07-01
1998-07-10
1998-07-31
問合せ結果 2- 70
res_dtime
08:20
10:24
15:00
14:05
14:30
1998-06-12
1998-07-07
1998-07-02
1998-07-10
Informix Guide to SQL: Tutorial
08:25
10:30
08:21
14:06
SELECT 文での関数の使用
問合せ 2- 71 では、all_dtime が指定された日付以上の値である場合、DATETIME 値
を日付 (DATE) 型のフォーマットに変換してラベルを付けて表示します。
問合せ 2- 71
SELECT customer_num,
DATE (call_dtime) called,
DATE (res_dtime) resolved
FROM cust_calls
WHERE call_dtime >= DATE ('1/1/98')
customer_num called
resolved
106 06/12/1998
110 07/07/1998
119 07/01/1998
121 07/10/1998
127 07/31/1998
06/12/1998
07/07/1998
07/02/1998
07/10/1998
問合せ結果 2- 71
TO_CHAR 関数の使用
TO_CHAR 関数は、日時 (DATETIME) 型 ( または日付 (DATE) 型 ) 値を文字列値に
変換します。TO_CHAR 関数は、指定された日付フォーマットに従って日時
(DATETIME) 型値を評価し、各国語可変長文字 (NVARCHAR) 型値を返します。サ
ポートされる日付フォーマットの完全なリストについては、
『Informix Guide to GLS
Functionality』の環境変数 GL_DATETIME の説明を参照してください。
問合せ 2- 72 は、TO_CHAR 関数を使用して日時 (DATETIME) 型値を読みやすい文
字列に変換しています。
問合せ 2- 72
SELECT customer_num,
TO_CHAR(call_dtime, "%A %B %d %Y") call_date
FROM cust_call
WHERE call_code = "B"
問合せ結果 2- 72
customer_num
call_date
119
Friday July 01 1998
簡単な SELECT 文の作成
2-69
SELECT 文での関数の使用
問合せ 2- 73 は、TO_CHAR 関数を使用して日付 (DATE) 型値を読みやすい文字列に
変換しています。
問合せ 2- 73
SELECT order_num,
TO_CHAR(ship_date,"%A %B %d %Y") date_shipped
FROM orders
WHERE paid_date IS NULL
問合せ結果 2- 73
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
TO_DATE 関数の使用
TO_DATE 関数は、文字型データの引数を受け入れ、この値を日時 (DATATIME) 型
値に変換します。TO_DATE 関数は、指定された日付フォーマットに従って文字列
を評価し、日時 (DATETIME) 型値を返します。サポートされる日時フォーマットの
完全なリストについては、
『Informix Guide to GLS Functionality』の環境変数
GL_DATETIME の説明を参照してください。
問合せ 2- 74 は、TO_DATE 関数を使用して文字列を指定されたフォーマットの日時
(DATETIME) 型値に変換しています。
問合せ 2- 74
SELECT customer_num, call_descr
FROM cust_calls
WHERE call_dtime = TO_DATE("1998-07-07 10:24",
"%Y-%m-%d %H:%M").
2-70
Informix Guide to SQL: Tutorial
SELECT 文での関数の使用
問合せ結果 2- 74
customer_num
110
call_descr
Order placed one month ago (6/7) not received.
DATE 関数または TO_DATE 関数を使用して、文字列を日付 (DATE) 型値に変換で
きます。TO_DATE 関数を使用する利点の 1 つは、戻される値のフォーマットを指
定できることです。( 常に日時 (DATETIME) 型値を返す TO_DATE 関数を使用し
て、文字列を日付 (DATE) 型値に変換することができます。これは、データベース
サーバが暗黙的に日付 (DATE) 型値と日時 (DATETIME) 型値の間の変換を行うため
です。)
問合せ 2- 75 では、TO_DATE 関数を使用して文字列値を、指定されたフォーマット
の日付 (DATE) 型値に変換します。
問合せ 2- 75
SELECT order_num, paid_date
FROM orders
WHERE order_date = TO_DATE( "6/7/98", "%m/%d/%iY")
問合せ結果 2- 75
order_num
paid_date
1008
07/21/1998
IDS
文字列操作関数
文字列操作関数は、文字 (CHAR) 型、各国語文字 (NCHAR) 型、可変長文字
(VARCHAR) 型、各国語可変長文字 (NVARCHAR) 型、またはラージ可変長文字
(LVARCHAR) 型の引数を受け入れます。文字列操作関数は、式を使用する部分な
らどこででも使用できます。
次の関数は、文字列の大文字と小文字の間の変換を行います。
✮
LOWER
✮
UPPER
✮
INITCAP
簡単な SELECT 文の作成
2-71
SELECT 文での関数の使用
次の関数は、いろいろな方法で文字列を操作します。
✮
REPLACE
✮
SUBSTR
✮
SUBSTRING
✮
LRAD
✮
RPAD
LOWER 関数の使用
LOWER 関数は、文字列の中の大文字をすべて小文字に置き換えます。LOWER 関
数は文字 (CHAR) 型データの引数を受け入れ、指定された引数と同じデータ型の値
を返します。
問合せ 2- 76 では、LOWER 関数を使用して、文字列のすべての大文字を小文字に置
き換えます。
問合せ 2- 76
SELECT manu_code, LOWER(manu_code)
FROM items
WHERE order_num = 1018.
問合せ結果 2- 76
manu_code
(expression)
PRC
KAR
PRC
SMT
HRO
prc
kar
prc
smt
hro
UPPER 関数の使用
UPPER 関数は、文字列の中の小文字をすべて大文字に置き換えます。UPPER 関数
は文字 (CHAR) 型データの引数を受け入れ、指定された引数と同じデータ型の値を
返します。
2-72
Informix Guide to SQL: Tutorial
SELECT 文での関数の使用
問合せ 2- 77 では、UPPER 関数を使用して、文字列のすべての小文字を大文字に置
き換えます。
問合せ 2- 77
SELECT call_code, UPPER(code_descr)
FROM call_type
問合せ結果 2- 77
call_code
(expression)
B
D
I
L
O
BILLING ERROR
DAMAGED GOODS
INCORRECT MERCHANDISE SENT
LATE SHIPMENT
OTHER
INITCAP 関数の使用
INITCAP 関数は、文字列のすべての語の最初の文字を大文字に置き換えます。
INICAP 関数は、英文字以外の文字が前にある文字を検出すると、これを新しい語
であるとみなします。INITCAP 関数は文字 (CHAR) 型データの引数を受け入れ、指
定された引数と同じデータ型の値を返します。
問合せ 2- 78 では、INITCAP 関数を使用して、文字列のすべての語の先頭文字を大
文字に変換します。
問合せ 2- 78
SELECT INITCAP(description)
FROM stock
WHERE manu_code = "ANZ"
問合せ結果 2- 78
(expression)
3 Golf Balls
Golf Shoes
Helmet
Kick Board
Running Shoes
Swim Cap
Tennis Ball
Tennis Racquet
Volleyball
Volleyball Net
Watch
簡単な SELECT 文の作成
2-73
SELECT 文での関数の使用
REPLACE 関数の使用
REPLACE 関数は、文字列の中の特定の文字のセットを別の文字に置き換えます。
問合せ 2- 79 の中で、REPLACE 関数は問合せが返すすべての行について、列 unit の
値 each を item に置き換えます。REPLACE 関数の最初の引数は、評価する式です。
2 番目の引数は、なにかで置き換えられる文字列を指定します。3 番目の引数は、
置き換えられる文字列に代わる新しい文字列を指定します。
問合せ 2- 79
SELECT stock_num, REPLACE(unit,"each", "item") cost_per, unit_price
FROM stock
WHERE manu_code = "HRO"
問合せ結果 2- 79
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
SUBSTRING 関数と SUBSTR 関数の使用
SUBSTRING 関数と SUBSTR 関数は、文字列の一部を返します。関数が返す文字列
の部分を決めるために、< 開始位置 > と < 長さ >(< 長さ > はオプションです ) を指
定します。
2-74
Informix Guide to SQL: Tutorial
SELECT 文での関数の使用
SUBSTRING 関数の使用
SUBSTRING 関数は、文字列の一部を返します。関数が返す文字列の部分を決める
ために、< 開始位置 > と < 長さ >(< 長さ > はオプションです ) を指定します。開始
位置は、正数または負数で指定できます。開始位置が 1 の場合は、SUBSTRING 関
数は文字列の先頭の位置から開始します。開始位置がゼロ (0) または負数の場合は、
SUBSTRING 関数は文字列の先頭から後方に数えます。
問合せ 2- 80 は、SUBSTRING 関数の例を示します。ここでは、問合せが返すすべて
の sname 列の値の先頭の 4 文字が戻されます。この例では、SUBSTRING 関数は文
字列の先頭から開始し、開始位置から数えて 4 文字を返します。
問合せ 2- 80
SELECT sname, SUBSTRING(sname FROM 1 FOR 4)
FROM state
WHERE code = "AZ"
問合せ結果 2- 80
sname
(expression)
Arizona
Ariz
問合せ 2- 81 では、SUBSTRING 関数に開始位置 6 を指定しますが、長さは指定し
ません。この関数は、6 番目の位置からその文字列の最後までの文字列を返します。
問合せ 2- 81
SELECT sname, SUBSTRING(sname FROM 6)
FROM state
WHERE code = "WV"
問合せ結果 2- 81
sname
(expression)
West Virginia
Virginia
簡単な SELECT 文の作成
2-75
SELECT 文での関数の使用
問合せ 2- 82 では、SUBSTRING 関数はこの問合せが返すすべての列 sname につい
て、先頭の文字だけを返します。SUBSTRING 関数では、開始位置が -2 のときは、
文字列の開始位置から位置を 3 つ (0、-1、-2) 後方に戻ります ( 開始位置が 0 のとき
は、文字列の先頭から位置を 1 つだけ戻します )。
問合せ 2- 82
SELECT sname, SUBSTRING(sname FROM -2 FOR 4)
FROM state
WHERE code = "AZ"
問合せ結果 2- 82
sname
(expression)
Arizona
A
SUBSTR 関数の使用
SUBSTR 関数は、SUBSTRING 関数と同じ目的で使用されますが、2 つの関数は構
文が異なります。
文字列の一部を返すには、< 開始位置 > と < 長さ >(< 長さ > はオプション ) を指定
して、SUBSTR 関数が返す文字列の部分を指定します。SUBSTR 関数の開始位置
は、正数または負数で指定できます。しかし SUBSTR 関数では、開始位置で指定さ
れた負数を、SUBSTRING 関数とは異なる方法で処理します。開始位置が負数のと
きは、SUBSTR 関数は文字列の最後から先頭に向かって数えます。開始位置が負数
で指定されたときは、SUBSTR 関数は文字列の最後から先頭に向かってに数えます
が、これは文字列の長さに依存し、語の文字の長さ、または文字列が含む目に見え
る文字の長さには影響されません。SUBSTR 関数は、開始位置にゼロ (0) または 1
が入っていると、文字列の先頭の位置であると解釈します。
2-76
Informix Guide to SQL: Tutorial
SELECT 文での関数の使用
問合せ 2- 83 は、開始位置に負数が指定された SUBSTR 関数の例です。開始位置が
-15 なので、SUBSTR 関数は文字列の最後から先頭方向に 15 数えて開始位置を検出
し、そこから 5 文字を返します。
問合せ 2- 83
SELECT sname, SUBSTR(sname, -15, 5)
FROM state
WHERE code = "CA"
問合せ結果 2- 83
sname
(expression)
California
Calif
開始位置に負数を使用するには、評価される値の長さを知っている必要がありま
す。列 sname は CHAR(15) として定義されているので、sname 型の引数を受け入れ
る SUBSTR 関数では、文字列の先頭から始まる文字列を返すには、関数の開始位置
に 0、1、-15 を使用することができます。
問合せ 2- 84 は、問合せ 2- 83 と同じ結果を返します。
問合せ 2- 84
SELECT sname, SUBSTR(sname, 1, 5)
FROM state
WHERE code = "CA
LPAD 関数の使用
LPAD 関数は、ある文字の連続を左に挿入した文字列のコピーを返します。この文
字の連続は、文字列の挿入部分の指定された長さに応じて、必要な回数だけ反復さ
れるか、または切り捨てられます。ソース文字列、戻される文字列の長さ、および
挿入句として使用される文字列を指定します。
ソース文字列および挿入句として使用される文字列のデータ型は、可変長文字
(VARCHAR) 型または各国語可変長文字 (NVARCHAR) 型に変換するデータ型なら
どれでも使用できます。
簡単な SELECT 文の作成
2-77
SELECT 文での関数の使用
問合せ 2- 85 は、長さを 21 バイトに指定した LPAD 関数の例です。ソース文字列は
長さが 15 バイトなので (sname は CHAR(15) で定義されています )、LPAD 関数は
ソース文字列の左の最初の 6 文字を挿入句にします。
問合せ 2- 85
SELECT sname, LPAD(sname, 21, "-")
FROM state
WHERE code = "CA"
2-78
Informix Guide to SQL: Tutorial
SELECT 文での関数の使用
問合せ結果 2- 85
sname
(expression)
California
------California
RPAD 関数の使用
RPAD 関数は、ある文字の連続で右に挿入した文字列のコピーを返します。この文
字の連続は、文字列の挿入部分の指定された長さに応じて、必要な回数だけ反復さ
れるか、または切り捨てられます。ソース文字列、戻される文字列の長さ、および
挿入句として使用される文字列を指定します。
ソース文字列および挿入句として使用される文字列のデータ型は、可変長文字
(VARCHAR) 型または各国語可変長文字 (NVARCHAR) 型に変換するデータ型なら
どれでも使用できます。
問合せ 2- 86 は、長さを 21 バイトに指定した RPAD 関数の例です。ソース文字列は
長さが 15 バイトなので (sname は CHAR(15) で定義されています )、RPAD 関数は
ソース文字列の右の最初の 6 文字を挿入句にします。
問合せ 2- 86
SELECT sname, RPAD(sname, 21, "-")
FROM state
WHERE code = "WV"
問合せ結果 2- 86
sname
(expression)
West Virginia West Virginia ------
その他の関数
定数使用の SQL 関数式では、LENGTH 関数、USER 関数、CURRENT 関数、およ
び TODAY 関数も使用することができます。また、DBSERVERNAME 関数を
SELECT 文に含めて、現行データベースが常駐するデータベースサーバの名前を表
示することができます。
これらの関数を使用すると、定数値から構成されている関数式または列データを含
む関数式を選択することができます。最初の例では、すべての行において同じ結果
が出力されます。
簡単な SELECT 文の作成
2-79
SELECT 文での関数の使用
また、HEX 関数で関数式を 16 進数に符号化した結果を戻したり、ROUND 関数で
四捨五入した関数式の値を戻したり、TRUNC 関数で切り詰めた関数式の値を戻す
ことができます。
上記の関数の詳細は、
『Informix Guide to SQL: Syntax』を参照してください。
LENGTH 関数の使用
問合せ 2- 87 では、company の長さが 15 より長い場合、LENGTH 関数で各行におい
て fname と lname を結合した列のバイト数を計算します。
問合せ 2- 87
SELECT customer_num,
LENGTH (fname) + LENGTH (lname) namelength
FROM customer
WHERE LENGTH (company) > 15
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
問合せ結果 2- 87
またはリレーショナルオブジェクトマネージャで作業すると、LENGTH 関数はあ
まり便利でないこともありますが、プログラムおよびレポートの文字列の長さを
決める場合には重要になります。LENGTH 関数は、文字 (CHARACTER) 型または
可変長文字 (VARCHAR) 型の文字列の短縮形の長さと、テキスト (TEXT) 型または
バイト (BYTE) 型の文字列の全バイト数を戻します。
2-80
Informix Guide to SQL: Tutorial
SELECT 文での関数の使用
USER 関数の使用
USER 関数はユーザの行しか入っていない表の制限付きビューを定義したいとき
に使用できます。ビューの作成方法についての詳細は、
『Informix Guide to Database
Design and Implementation』と『Informix Guide to SQL: Syntax』に記載されている
GRANT 文と CREATE VIEW 文を参照してください。
問合せ 2- 88a では、USER 関数と表 cust_calls を指定します。
問合せ 2- 88a
SELECT USER FROM cust_calls
問合せ 2-88b では、問合せを実行するユーザのユーザ名 ( ログインアカウント名 )
を戻します。この問合せは、表内の各行に対して 1 回行われます。
問合せ 2-88b
SELECT * FROM cust_calls
WHERE user_id = USER
現在のユーザのユーザ名が richc の場合、問合せ 2-88b に示すように、問合せ結果
2- 88 はユーザが所有する表 cust_calls の行のみ抽出します。
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
問合せ結果 2- 88
簡単な SELECT 文の作成
2-81
SELECT 文での関数の使用
TODAY 関数の使用
TODAY 関数は現在システム日付を戻します。現在のシステム日付が 1998 年 7 月
10 日の場合に問合せ 2- 89 を使用すると、次の 1 行が戻されます。
問合せ 2- 89
SELECT * FROM orders
WHERE order_date = TODAY
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
問合せ結果 2- 89
DBSERVERNAME 関数と SITENAME 関数の使用
DBSERVERNAME 関数 ( またはシノニム SITENAME) を SELECT 文に含めると、
データベースサーバの名前を検索することができます。行が含まれている表 ( シス
テムカタログ表など ) の DBSERVERNAME について問合せを実行することができ
ます。
問合せ 2- 90 では、ラベル server を DBSERVERNAME 関数式に設定し、列 tabid を
システムカタログ表 systables から選択します。この表はデータベース表を記述し、
tabid はシリアル時間隔識別子です。
問合せ 2- 90
SELECT DBSERVERNAME server, tabid
FROM systables
WHERE tabid <= 4
server
問合せ結果 2- 90
tabid
montague
montague
montague
montague
1
2
3
4
WHERE 節で tabid 内の値を制限しない場合は、表 systables の各行にデータベース
サーバ名が繰り返し使用されます。
2-82
Informix Guide to SQL: Tutorial
SELECT 文での関数の使用
HEX 関数の使用
問合せ 2- 91 では、HEX 関数が表 customer 内の指定した 3 つの列を 16 進数フォー
マットで戻します。
問合せ 2- 91
SELECT HEX (customer_num) hexnum, HEX (zipcode) hexzip,
HEX (rowid) hexrow
FROM customer
問合せ結果 2- 91
hexnum
hexzip
hexrow
0x00000065
0x00000066
0x00000067
0x00000068
0x00000069
0x0000006A
0x0000006B
0x0000006C
0x0000006D
0x0000006E
0x0000006F
0x00000070
0x00000071
0x00000072
0x00000073
0x00000074
0x00000075
0x00000076
0x00000077
0x00000078
0x00000079
0x0000007A
0x0000007B
0x0000007C
0x0000007D
0x0000007E
0x0000007F
0x00000080
0x00016F86
0x00016FA5
0x0001705F
0x00016F4A
0x00016F46
0x00016F6F
0x00017060
0x00016F6F
0x00016F86
0x00016F6E
0x00016F85
0x00016F46
0x00016F49
0x00016F6E
0x00016F49
0x00016F58
0x00016F6F
0x00017191
0x00001F42
0x00014C18
0x00004DBA
0x0000215C
0x00007E00
0x00012116
0x00000857
0x0001395B
0x0000EBF6
0x00014C10
0x00000001
0x00000002
0x00000003
0x00000004
0x00000005
0x00000006
0x00000007
0x00000008
0x00000009
0x0000000A
0x0000000B
0x0000000C
0x0000000D
0x0000000E
0x0000000F
0x00000010
0x00000011
0x00000012
0x00000013
0x00000014
0x00000015
0x00000016
0x00000017
0x00000018
0x00000019
0x0000001A
0x0000001B
0x0000001C
DBINFO 関数の使用
SELECT 文で DBINFO 関数を使用して、次の情報を抽出できます。
■
表領域番号または式に対応する DB 領域の名前
■
表に挿入された最新のシリアル値
■
選択、挿入、削除、更新、および実行プロシジャ文により処理された行の
数
簡単な SELECT 文の作成
2-83
SELECT 文での関数の使用
IDS
■
現行セッションのセッション ID
■
データベース サーバを実行しているホスト コンピュータの名前
■
クライアント アプリケーションが接続されるデータベース サーバの正確
なバージョン ♦
DBINFO 関数は、SQL 文およびストアド プロシジャの中のどの位置でも使用できま
す。
問合せ 2- 92 では、DBINFO 関数を使用してデータベース サーバを実行しているホ
スト コンピュータの名前を抽出する方法を示します。
問合せ 2- 92
SELECT DBINFO('dbhostname')
FROM systables
WHERE tabid = 1
問合せ結果 2- 92
(constant)
lyceum
tabid の値を制約する WHERE 節を使用しないと、データベース サーバが実行され
るコンピュータのホスト名が表 systables の各行で繰り返されてしまいます。
問合せ 2- 93 では、DBINFO 関数を使用して現行データベース サーバの完全なバー
ジョン番号とタイプを検索する方法を示します。
問合せ 2- 93
SELECT DBINFO('version','full')
FROM systables
WHERE tabid = 1
DBINFO 関数を使用して現行データベース サーバ、データベース セッション、ま
たはデータベースに関する情報を検索する方法については、
『Informix Guide to SQL:
Syntax』を参照してください。
IDS
DECODE 関数の使用
DECODE 関数は、式の 1 つの値を別の値に変換します。DECODE 関数の形式は次
のとおりです。
DECODE(exp_1, exp_2, exp_3, exp_4, exp_5, ..., exp_n, exp_n+1, exp_m )
2-84
Informix Guide to SQL: Tutorial
SELECT 文での関数の使用
DECODE は、< 式 2> が < 式 1> と等しいときに < 式 3> を戻し、< 式 4> が < 式 1>
と等しいときに < 式 5> を返します。一般に、< 式 n> が < 式 1> と等しいときに <
式 n+1> を返します。
いくつかの式が < 式 1> に等しい場合は、DECODE は検出した最初の式について <
式 n+1> を返します。式がどれも < 式 1> と一致しない場合は、DECODE は < 式 m>
を返します。式がどれも < 式 1> と一致せず、< 式 m> が指定されていない場合は、
DECODE は NULL を返します。
列 emp_id と列 evaluation を含む表 employee があるとします。問合せ 2- 94 を表
employee について実行した結果、問合せ結果 2- 94 に示される行が戻ると想定しま
す。
問合せ 2- 94
SELECT emp_id, evaluation
FROM employee:
問合せ結果 2- 94
emp_id
evaluation
012233
012344
012677
012288
012555
great
poor
NULL
good
very good
場合によっては、値のセットを変換したいことがあります。たとえば、前の例で列
evaluation の記述的な値を、対応する数値に変換したい場合を想定します。問合せ
2- 95 は、表 employee の各行について、DECODE 関数を使用して列 evaluation の値
を数値に変換する方法を示します。
問合せ 2- 95
SELECT emp_id, DECODE(evaluation, "poor", 0 "fair", 25, "good", 50,"very
good", 75, "great", 100, -1) as evaluation
FROM employee
問合せ結果 2- 95
emp_id
evaluation
012233
012344
012677
012288
012555
100
0
-1
50
75
簡単な SELECT 文の作成
2-85
SELECT 文での関数の使用
DECODE 関数の引数は、次の要件を満たす場合は任意のデータ型を指定できます。
■
引数 < 式 1>、< 式 2>、< 式 4>、...、< 式 n> はすべて同じデータ型か、または共
通互換データ型と評価される。
■
引数 < 式 3>、< 式 5>、...、< 式 n+1> はすべて同じデータ型か、または共通互
換データ型と評価される。
NVL 関数の使用
IDS
NVL 関数は、NULL と評価された式を、ユーザが指定する値に変換します。NVL
関数は 2 つの引数を使用します。最初の引数は、評価される式の名前です。2 番目
の引数は、最初の引数が NULL と評価されたときに関数が返す値を指定します。最
初の引数が NULL と評価されない場合、関数は最初の引数の値を返します。たとえ
ば列 name と列 address を含む表 student があるとします。問合せ 2- 96 を表 student
について実行すると、問合せ結果 2- 96 に示す行が返されます。
問合せ 2- 96
SELECT name, address
FROM student:
問合せ結果 2- 96
name
address
John Smith
Lauren Collier
Fred Frith
Susan Jordan
333 Vista Drive
1129 Greenridge Street
NULL
NULL
問合せ 2- 97 には NVL 関数が含まれています。これは列 address に NULL 値が含ま
れている表の各行について、新しい値を返します。
問合せ 2- 97
SELECT name, NVL(address, "address is unknown") as address
FROM student
2-86
Informix Guide to SQL: Tutorial
SELECT 文でのストアドプロシジャの使用
問合せ結果 2- 97
name
address
John Smith
Lauren Collier
Fred Frith
Susan Jordan
333 Vista Drive
1129 Greenridge Street
address is unknown
address is unknown
NVL 関数の 2 つの引数が共通互換データ型であると評価するなら、これらの引数に
任意のデータ型を指定できます。
NVL 関数の両方の引数が NULL と評価される場合、NULL が戻されます。
SELECT 文でのストアドプロシジャの使用
この章では、列名、演算子、および SQL 関数から構成される SELECT 文の関数式
の例を示してきました。ここでは、ストアドプロシジャの呼出しを含む関数式を示
します。
ストアドプロシジャには、SQL 文と一緒に特殊のストアドプロシジャ言語 (SPL) 文
が含まれています。ストアドプロシジャについての詳細は第 8 章「ストアド プロ
シジャの作成と使用」を参照してください。
ストアドプロシジャを使用すると、関数の使用範囲を拡張できます。すなわち選択
する各行について副問合せ文を実行することができます。
たとえば、顧客番号、顧客の姓、顧客からの注文数をリストしたいとします。問合
せ 2- 98 は、この情報を抽出する方法の 1 つを示しています。表 customer には、列
customer_num と lname がありますが、各顧客の注文数の記録はありません。プロシ
ジャ get_orders がすでに作成されているものと想定しており、各 customer_num の表
orders の問合せを行い、n_orders というラベルの付いている対応する注文の数を返
します。
問合せ 2- 98
SELECT customer_num, lname, get_orders(customer_num) n_orders
FROM customer
簡単な SELECT 文の作成
2-87
SELECT 文でのストアドプロシジャの使用
問合せ結果 2- 98 は、このストアドプロシジャからの出力を示しています。
問合せ結果 2- 98
customer_num lname
101 Pauli
102 Sadler
103 Currie
104 Higgins
105 Vector
106 Watson
107 Ream
108 Quinn
109 Miller
110 Jaeger
111 Keyes
112 Lawson
113 Beatty
114 Albertson
115 Grant
116 Parmelee
117 Sipes
118 Baxter
119 Shorter
120 Jewell
121 Wallack
122 O’ Brian
123 Hanlon
124 Putnum
125 Henry
126 Neelie
127 Satifer
128 Lessor
n_orders
1
0
0
4
0
2
0
0
0
2
1
1
0
0
1
1
2
0
1
1
1
1
1
1
0
1
1
0
ストアドプロシジャを使用して、問合せの中で実行回数の多い演算をカプセル化し
ます。たとえば、問合せ 2- 99 の条件には、在庫品 1 個当たりの価格を別の通貨に
換算し、輸入関税を加えるプロシジャ conv_price が入っています。
問合せ 2- 99
SELECT stock_num, manu_code, description
FROM stock
WHERE conv_price(unit_price, ex_rate = 1.50,
tariff = 50.00) < 1000
2-88
Informix Guide to SQL: Tutorial
複数表 SELECT 文
複数表 SELECT 文
複数の表からデータを選択するには、FROM 節で表に名前を指定します。WHERE
節を追加して、各表で関連した一つ以上の列を結合する条件を作成します。この
WHERE 節は一時複合表を作成します。結合条件を満たす行のペアはすべてリンク
され、単一行を形成しています。
単純結合では、各表内の一つの列関係に基づいた複数表の情報を結合します。複合
結合で、各表内の複数の列の関係に基づいた複数の表の結合です。
結合を作成するには、各表の最低一つの列の間の結合条件と呼ばれる関係を指定し
なければなりません。列は比較の対象となるので、互換性のあるデータ型を含んで
いなければなりません。大きな表を結合する場合は、結合条件で列にインデックス
を付けると効率的です。
データ型については『Informix Guide to SQL: Reference』と『Informix Guide to
Database Design and Implementation』で説明されています。インデックスの付け方に
ついての詳細は、『Administrator’s Guide』を参照してください。
デカルト積の作成
表の結合条件が明示的に示されていない複数表の問合せを実行する場合は、デカル
ト積を作成します。デカルト積は、表におけるすべての行の組み合わせからなりま
す。通常、デカルト積の結果は大きくなるのでデータは不正確です。
問合せ 2- 100 では、二つの表から選択してデカルト積を作成します。
問合せ 2- 100
SELECT * FROM customer, state
簡単な SELECT 文の作成
2-89
デカルト積の作成
表 state には 52 行、表 customer には 28 行しかありませんが、問合せ 2- 100 を行う
と、一方の表の行数と他方の表の行数の乗算が行われ、問合せ 2- 100 のように実用
性のない 1,456 行が抽出されます。
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
.
.
.
問合せ結果 2- 100
Sunnyvale
CA
94086
408-789-8075
AK
Alaska
Sunnyvale
CA
94086
408-789-8075
HI
Hawaii
101
Ludwig
Pauli
All Sports Supplies
213 Erstwild Court
Sunnyvale
CA
94086
408-789-8075
CA
California
連結行に表示されたデータには、不正確なデータが含まれている場合があります。
たとえば、表 customer の city と state はカルフォルニアの住所を示していますが、
表 state の code と sname は、別の住所を示している場合があります。
2-90
Informix Guide to SQL: Tutorial
結合の作成
結合の作成
理論的には、結合の最初の段階でデカルト積を作成します。このデカルト積を取捨
選択して不要なデータ行を除去するには、有効な結合条件と、一緒に WHERE 節
を SELECT 文に含めます。
ここでは、等結合、自然結合、および複数表結合について説明します。セルフ結合
や外部結合などの複雑なフォームは第 3 章「高度な SELECT 文の作成」で説明さ
れています。
等結合
等結合は、等価関係 ( 値が一致しているかどうか ) にもとづいた結合です。問合せ
2- 101 で示されているように、等価関係は、WHERE 節において比較演算の等号 (=)
で示されます。
問合せ 2- 101
SELECT * FROM manufact, stock
WHERE manufact.manu_code = stock.manu_code
問合せ 2- 101 では、列 manu_code の表 manufact と stock を結合します。この問合せ
では、問合せ結果 2- 101 で示されているように、二つの行の列の値が等しい場合、
それらの行のみを抽出します。
簡単な SELECT 文の作成
2-91
結合の作成
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
問合せ結果 2- 101
この等結合では、選択対象の並びですべての列が要求されたため、問合せ結果 2101 には、表 manufact と stock の両方の列 manu_code が含まれています。
追加の制約で、結合列の値が等しくないことを比較条件にしている等結合を作成す
ることもできます。このような等結合では、WHERE 節に指定される比較条件
で、等号 (=)ではなく関係演算子を使用します。
2-92
Informix Guide to SQL: Tutorial
結合の作成
同じ名前の列が含まれた表を結合するには、問合せ 2- 102 で示すように、各列名の
前にピリオドとその表名を付けます。
問合せ 2- 102
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 customer_num
問合せ 2- 102 では、列 customer_num で行を結合してから、表 cust_calls の call_dtime
が表 orders の ship_date 以上の行だけを選択します。問合せ結果 2- 102 は、返す行を
示しています。
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
問合せ結果 2- 102
Sent memo to shipping to send ANZ item 304
to customer and pickup HRO watches. Should
be done tomorrow, 8/1
簡単な SELECT 文の作成
2-93
結合の作成
自然結合
自然結合は、問合せ 2- 103 で示されているように、結合列のデータ表示が冗長に
ならないように構成されています。
問合せ 2- 103
SELECT manu_name, lead_time, stock.*
FROM manufact, stock WHERE manufact.manu_code = stock.manu_code
等結合の例と同じように、問合せ 2- 103 では、列 manu_code の表 manufact と stock
を結合します。問合せ結果 2- 103 で示されているように、選択対象の並びがより詳
細に定義されているので、manu_code は、抽出した各行に対して一回のみリストさ
れます。
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
2-94
Informix Guide to SQL: Tutorial
問合せ結果 2- 103
結合の作成
すべての結合には、結合性があります。つまり、WHERE 節内の結合タームの順序
は結合の意味には影響を与えません。
問合せ 2- 104 の二つの SELECT 文では、自然結合を作成します。
問合せ 2- 104
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
各 SELECT 文では、問合せ結果 2- 104 で示される行が抽出されます。
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
description
unit_price
unit
unit_descr
問合せ結果 2- 104
Ultimate in Puncture Protection, Tires
Designed for In-City Riding
bicycle tires
$88.00
box
4/box
問合せ 2- 104 には、テキスト (TEXT) 型の列 cat_descr、バイト (BYTE) 型の列
cat_picture、可変長文字 (VARCHAR) 型の列 cat_advert が含まれています。
簡単な SELECT 文の作成
2-95
結合の作成
複数表の結合
複数表の結合では、関連する一つまたは複数の列で複数の表を結合します。この結
合は、等結合または自然結合です。
問合せ 2- 105 では、表 catalog、stock、および manufact で等結合を作成して、次の
行を抽出します。
問合せ 2- 105
SELECT * FROM catalog, stock, manufact
WHERE catalog.stock_num = stock.stock_num
AND stock.manu_code = manufact.manu_code
AND catalog_num = 10025
問合せ 2- 105 では、問合せ結果 2- 105 で示される行を抽出します。
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
stock_num
manu_code
description
unit_price
unit
unit_descr
manu_code
manu_name
lead_time
問合せ結果 2- 105
ProCycle Stem with Pearl Finish
106
PRC
bicycle stem
$23.00
each
each
PRC
ProCycle
9
manu_code は 3 回 ( 一つの表につき 1 回 )、stock_num は 2 回使用されています。
問合せ 2- 105 のように複数表の問合せで行が重複しないようにするには、問合せ 2106 で示されているように、選択対象の並びに特定の列を含めて SELECT 文をより
詳細に定義します。
問合せ 2- 106
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
2-96
Informix Guide to SQL: Tutorial
簡単な問合せ方法
問合せ 2- 106 では、ワイルドカードを使用して、最も多くの列を含む表から列をす
べて選択し、他の二つの表の列を指定します。問合せ結果 2- 106 は、問合せ 2- 106
が作成した自然結合を示しています。この問合せでは、直前の例と同じ情報を表示
していますが、重複した行は含まれていません。
問合せ結果 2- 106
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
description
unit_price
unit
unit_descr
manu_name
lead_time
ProCycle Stem with Pearl Finish
bicycle stem
$23.00
each
each
ProCycle
9
簡単な問合せ方法
別名、INTO TEMP 節、表示ラベルを使用すると、各種の結合と複数表の問合せを
短時間で行ったり、他で使用するための出力を作成することができます。
別名の使用
SELECT 文で表に別名を設定すると、複数表の問合せが短時間で処理され、読み
やすくなります。別名は、FROM 節で表の名前の直後に付けるワードです。別名
は、他の節で列名に付けられるプレフィクスのように、表名が使用されている箇所
で使用することができます。
問合せ 2- 107a
SELECT s.stock_num, s.manu_code, s.description,
s.unit_price, s.unit, c.catalog_num,
c.cat_descr, 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
簡単な SELECT 文の作成
2-97
簡単な問合せ方法
結合性のある SELECT 文では、別名を定義する前に使用することができます。問合
せ 2- 107a では、表 stock の別名 s、表 catalog の別名 c、および表 manufact の別名 m
が FROM 節で指定され、列のプレフィクスとして SELECT 節と WHERE 節で使用
されます。
問合せ 2- 107a の長さと、別名を使用していない問合せ 2-107b の長さを比較してみ
ます。
問合せ 2-107b
SELECT stock.stock_num, stock.manu_code, stock.description,
stock.unit_price, stock.unit, catalog.catalog_num,
catalog.cat_descr, 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
2-98
Informix Guide to SQL: Tutorial
簡単な問合せ方法
問合せ 2- 107a と問合せ 2-107b は、実質的に等価であり、問合せ結果 2- 107 で示さ
れているデータを抽出しています。
stock_num
110
manu_code
HRO
description
helmet
unit_price
$260.00
unit
case
catalog_num
10033
cat_descr
Newest ultralight helmet uses plastic shell. Largest ventilation
channels of any helmet on the market. 8.5 oz.
cat_advert
Lightweight Plastic Slatted with Vents Assures Cool
Comfort Without Sacrificing Protection
lead_time
4
問合せ結果 2- 107
stock_num
110
manu_code
HSK
description
helmet
unit_price
$308.00
unit
each
catalog_num
10034
cat_descr
Aerodynamic (teardrop) helmet covered with anti-drag fabric.
Credited with shaving 2 seconds/mile from winner’ s time in
Tour de France time-trial. 7.5 oz.
cat_advert
Teardrop Design Endorsed by Yellow Jerseys,
You Can Time the Difference
lead_time
5
stock_num
205
manu_code
HRO
description
3 golf balls
unit_price
$312.00
unit
each
catalog_num
10048
cat_descr
Combination fluorescent yellow and standard white.
cat_advert HiFlier Golf Balls: Case Includes Fluorescent
Yellow and Standard White
lead_time
4
stock_num
301
manu_code
HRO
description
running shoes
unit_price
$42.50
unit
each
catalog_num
10050
cat_descr
Engineered for serious training with exceptional stability.
Fabulous shock absorption. Great durability. Specify
mens/womens, size.
cat_advert
Pronators and Supinators Take Heart: A Serious
Training Shoe For Runners Who Need Motion Control
lead_time
4
簡単な SELECT 文の作成
2-99
簡単な問合せ方法
テキスト (TEXT) 型列 cat_descr またはバイト (BYTE) 型列 cat_picture に対して
ORDER BY 節を使用することはできません。また、別名を使用すると、現行のデー
タベースにない表の問合せを簡単に行うことができます。
問合せ 2- 108 では、現在のデータベースまたはシステム以外の別のデータベースお
よびシステムに常駐する二つの表の列を結合します。
問合せ 2- 108
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
database@system:table のロング名である masterdb@central:customer と sales@western:
orders に別名 c と o をそれぞれ設定すると、別名によって WHERE 節内の関数式が
短縮され、問合せ結果 2- 108 で示されるデータが抽出されます。
order_num lname
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
Higgins
Pauli
Higgins
Watson
Parmelee
Lawson
Sipes
Jaeger
Keyes
Grant
fname
phone
Anthony
Ludwig
Anthony
George
Jean
Margaret
Arnold
Roy
Frances
Alfred
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
問合せ結果 2- 108
現行のデータベースにない表のアクセス方法については、このマニュアルの 2-102
ページの「現行データベース以外のデータベースからの表の検索」と『Informix
Guide to SQL: Syntax』を参照してください。
また、現行表と現行ビューのロング名だけでなく現行のデータベースにない表と
ビューのロング名に対するクイックリファレンスとしてシノニムを使用することが
できます。シノニムの作成方法と使用方法についての詳細は、
『Informix Guide to
Database Design and Implementation』を参照してください。
2-100 Informix Guide to SQL: Tutorial
簡単な問合せ方法
INTO TEMP 節
INTO TEMP 節を使用する SELECT 文に追加すると、データベースを変更せずに、
問合せまたは操作できる個別の表へ複数表の問合せ結果を一時的に保存することが
できます。SQL セッションを終了した場合、あるいはプログラムまたはレポートを
終了した場合は一時表が削除されます。
問合せ 2- 109 のように、一時表 stockman を作成して、その表に問合せ結果を格納
します。一時表では、すべての列に名前を付けなければならないため、別名
adj_price が必要です。
問合せ 2- 109
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
stock_num manu_name
1
1
1
2
3
4
4
.
.
.
306
307
308
309
309
310
310
311
312
312
313
313
description
unit_price
adj_price
Hero
Husky
Smith
Hero
Husky
Hero
Husky
baseball gloves
baseball gloves
baseball gloves
baseball
baseball bat
football
football
$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
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
$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
問合せ結果 2- 109
これで、この表の問合せを行い、他の表と結合することができます。こうすると、
複数ソートが回避されるため、データベース内をより短時間で移動することができ
ます。一時表の詳細は、
『Administrator’s Guide』を参照してください。
簡単な SELECT 文の作成
2-101
現行データベース以外のデータベースからの表の検索
現行データベース以外のデータベースからの表の
検索
CONNECT、DATABASE、または CREATE DATABASE 文がオープンするデータ
ベースが現行データベースです。現行データベース以外のデータベースの表を参照
するには、次の SELECT 文で示すように、データベース名を表名の一部として含め
ます。
SELECT name, number FROM salesdb:contacts
データベースは salesdb です。salesdb の中の表の名前は contacts です。結合の中で
も同じ表記を使用できます。データベース名を明示的に指定する必要があるとき
は、次の例に示すように、長い表名は別名を使用して短くしないと扱いにくくなり
ます。
SELECT C.custname, S.phone
FROM salesdb:contacts C, stores:customer S
WHERE C.custname = S.company
別のデータベース サーバが管理するデータベースにある表を指定するには、< デー
タベース サーバ名 > でデータベース名を修飾する必要があります。たとえば次の
SELECT 文では、データベース サーバ central に常駐するデータベース masterdb の、
表 customer を参照しています。
SELECT O.order_num, C.fname, C.lname
FROM masterdb@central:customer C, sales@boston:orders O
WHERE C.customer_num = O.Customer_num
INTO TEMP mycopy
上記の例では、2 つの表が結合されています。結合された行は現行データベースの
mycopy という名前の一時表に格納されます。表は、2 つのデータベース サーバ、
central と boston の中に配置されています。
Informix では、表名をオーバ修飾する ( 必要以上の情報を与える ) ことができます。
両方のテーブル名が完全に修飾されているので、現行データベースが masterdb と
sales のどちらであるかを示すことはできません。
2-102 Informix Guide to SQL: Tutorial
まとめ
まとめ
この章では、リレーショナルデータベースの問合せに使用する基本的な SELECT 文
の構文および実行結果のサンプルを示しています。2-11 ページの「一つの表に対す
る SELECT 文」では、以下の項目の操作方法について説明しています。
■
SELECT 節と FROM 節を持つ表からすべての列と行を選択する。
■
SELECT 節と FROM 節を持つ表から指定列の取り出す。
■
SELECT 節、FROM 節、および WHERE 節を使用して表から特定の行を選択
する。
■
SELECT 節でキーワード DISTINCT または UNIQUE を使用して、問合せ結果
から重複行を除去する。
■
ORDER BY 節とキーワード DESC を使用して、抽出したデータをソートす
る。
■
英語以外の文字を含むデータの選択と順序づけを行う。
■
キーワード BETWEEN、IN、MATCHES、LIKE と各種のリレーショナル
データベースを WHERE 節で使用して比較条件を作成する。
■
値を含む、値を除外する、値の範囲を ( キーワード、関係演算子、サブスク
リプト付けで ) 検索する、値のサブセットを検索するなどの比較条件を作
成する。
■
テキストの比較照合、可変長のワイルドカード、および制限付きと制限な
しのワイルドカードを使用して、変数テキストの検索を実行する。
■
論理演算子 AND、OR、NOT を使用して、WHERE 節の検索条件または
Boolean 式を結合する。
■
キーワード ESCAPE を使用して、問合せ内の特殊文字を保護する。
■
WHERE 節のキーワード IS NULL と IS NOT NULL を使用して、
NULL を検索
する。
■
FIRST 節を使用して、問合せが SELECT 文の条件に一致する行を指定した
数だけ返すように指定する。
■
SELECT 節の算術演算子を使用して、数値フィールドの計算を実行し、抽
出したデータを表示する。
■
部分文字列とサブスクリプトで、ユーザの問合せを調整する。
■
レポート用のフォーマット手段として、表示ラベルを計算済みの列に設定
する。
簡単な SELECT 文の作成
2-103
まとめ
■
SELECT 節で集計関数 COUNT、AVG、MAX、MIN、および SUM を使用し
て、特定のデータの計算と抽出を行う。
■
時刻関数 DATE、DAY、MDY、MONTH、WEEKDAY、YEAR、
CURRENT、EXTEND と TODAY 関数、LENGTH 関数、USER 関数をユー
ザの SELECT 文に含める。
■
SELECT 節で変換関数を使用して、日付値と文字値との間で変換を行う。
■
SELECT 節で文字列操作関数を使用して、大文字と小文字の変換、または
文字列のいろいろな操作を行う。
■
ストアドプロシジャをユーザの SELECT 文に含める。
この章では、複数の表のデータを選択して表示できる簡単な結合条件の概要につい
ても説明しました。2-11 ページの「一つの表に対する SELECT 文」では、以下の項
目について説明しました。
■
デカルト積を作成する。
■
有効な結合条件を指定した WHERE 節をユーザの問合せに含めて、デカル
ト積に制約条件を設定する。
■
自然結合と等結合を定義して作成する。
■
一つまたは複数の列で複数の表を結合する。
■
複数表の問合せで短縮形として別名を使用する。
■
選択したデータを INTO TEMP 節で個別の一時表内に抽出し、データベース
の外部で計算を行う。
次章では、セルフ結合と外部結合、GROUP BY 節と HAVING 節、集合演算
UNION、INTERSECTION、および DIFFERENCE などのより複雑な問合せや副問合
せについて説明します。
2-104 Informix Guide to SQL: Tutorial
第3章
高度な SELECT 文の作成
GROUP BY 節と HAVING 節の使用方法 .
GROUP BY 節の使用方法 . . . .
HAVING 節の使用方法 . . . . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. .
. .
. .
3-4
3-4
3-8
高度な結合の作成 . . . . . . . . .
セルフ結合 . . . . . . . . . .
rowid( 行 ID 番号 ) の値の使用方法 . . .
外部結合 . . . . . . . . . . .
単純結合. . . . . . . . . .
二つの表の単純な外部結合 . . . .
第 3 の表に対する単純結合との外部結合
第 3 の表に対する二つの表の外部結合 .
外部結合を組み合わせる結合. . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
. .
. . .
. .
. .
. .
. .
. .
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
. .
. . .
. .
. .
. .
. .
. .
. .
3-10
3-11
3-15
3-20
3-21
3-23
3-25
3-26
3-28
SELECT 文中の副問合せ文 . . .
キーワード ALL の使用方法 .
キーワード ANY の使用方法 .
値を一つだけ返す副問合せ文 .
相関副問合せ文 . . . . .
キーワード EXISTS の使用方法
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3-30
3-31
3-32
3-33
3-35
3-36
集合演算 . . .
和の集合演算
積の集合演算
差の集合演算
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3-39
3-40
3-48
3-50
. .
3-52
まとめ . . .
.
.
.
.
.
.
.
.
. . .
.
.
.
.
.
.
.
.
. .
.
.
.
.
. . .
. . .
. . .
. . .
3-2
Informix Guide to SQL: Tutorial
前章「簡単な SELECT 文の作成」では、SELECT 文を使用して、リレーショナル
データベースからデータを抽出するための基本的ないくつかの方法を紹介しまし
た。この章では、SQL 文の囲を広げて、さらに複雑なデータベースの問合せとデー
タ操作を実行できるようにします。
前章では、SELECT 文の構文を構成する節のうちの 5 つについて説明しましたが、
この章ではさらに二つの節を説明します。GROUP BY 節と集計関数をいっしょに使
用すると、FROM 節が返す行をグループ化することができます。HAVING 節を記述
すると、GROUP BY 節が返す値に条件を設けることができます。
この章では、結合についての説明の範囲を前よりも広げます。表をその表自体に結
合できるようにするセルフ結合、および複数の結合された表を平等に扱わないよう
にキーワード OUTER を使用する 4 種類の外部結合について例をあげて説明します。
また、その他にも、相関 / 非相関副問合せ文とその操作キーワード、演算子 UNION
を使用して問合せ文を結合する方法を説明し、集合演算の和、積、差を定義しま
す。
この章では例を使用して、問合せのときの一部またはすべての SELECT 文の節の使
用方法を説明します。各節は必ず次の順序で指定してください。
1.
SELECT 節
2.
FROM 節
3.
WHERE 節
4.
GROUP BY 節
5.
HAVING 節
6.
ORDER BY 節
7.
INTO TEMP 節
正しい順序でこれからの節をすべて使用する SELECT 文の例については、3-10 ペー
ジの問合せ 3- 8 を参照してください。
高度な SELECT 文の作成
3-3
GROUP BY 節と HAVING 節の使用方法
その他の SELECT 文の節である INTO 節 (SQL API にプログラム変数およびホスト
変数を指定するのに使用できます ) の説明は、製品に添付されているマニュアルに
記載されているだけではなく、第 5 章「SQL を使用したプログラミング」にも記載
されています。
GROUP BY 節と HAVING 節の使用方法
オプションの節である GROUP BY 節と HAVING 節を指定することによって、
SELECT 文の機能性を高めることができます。どちらか一方または両方を SELECT
文に記述すると、集計関数をより高度に活用できます。
GROUP BY 節は、選択対象の並びに表示されている列の値が同じ行を一つのグルー
プにまとめて、それぞれの行グループの結果を単一の行に生成します。HAVING 節
は生成されたグループに対して条件を設定します。HAVING 節を使わずに GROUP
BY 節だけを使用したり、GROUP BY 節を使わずに HAVING 節を使用したりするこ
ともできます。
GROUP BY 節の使用方法
GROUP BY 節は表をいくつかのセットに分けます。この節は、それらのセットのそ
れぞれに対して要約値を作成する集合関数と組み合わせて使用されることが多く
なっています。第 2 章「簡単な SELECT 文の作成」では、表全体に適用される集計
関数の使用方法を例を用いて説明しました。この章では、行グループに適用される
集計関数について説明します。
集計関数を使用せずに GROUP BY 節を使用することは、キーワード DISTINCT ま
たは UNIQUE を SELECT 節に使用する場合とよく似ています。第 2 章「簡単な
SELECT 文の作成」では、問合せ 3- 1b に示す文を説明しました。
問合せ 3- 1a
SELECT DISTINCT customer_num FROM orders
この文を問合せ 3- 1b に示すように書くこともできます。
問合せ 3- 1b
SELECT customer_num
FROM orders
GROUP BY customer_num
3-4
Informix Guide to SQL: Tutorial
GROUP BY 節の使用方法
問合せ 3- 1a と問合せ 3- 1b は、問合せ結果 3- 1 が示している行を返します。
問合せ結果 3- 1
customer_num
101
104
106
110
111
112
115
116
117
119
120
121
122
123
124
126
127
GROUP BY 節は各セット内の列 customer_num( 顧客番号 ) が同じになるように行を
セットにまとめます。何も列が選択されていないと、結果は一意の customer_num
の値のリストとして取り出されます。
GROUP BY 節は集計関数と一緒に使用するとその機能がよくわかります。
問合せ 3- 2 は、各注文についての品目数と各品目の合計金額を抽出します。
問合せ 3- 2
SELECT order_num, COUNT (*) number, SUM (total_price) price
FROM items
GROUP BY order_num
GROUP BY 節は、表 items( 注文品目 ) の行を、列 order_num( 注文番号 ) の値が同じ
行を一つのグループとしてまとめます。つまり、各注文を構成する品目を1グルー
プとしてまとめます。グループを生成した後は、集計関数 COUNT と SUM が各グ
ループに対し適用されます。
高度な SELECT 文の作成
3-5
GROUP BY 節の使用方法
問合せ 3- 2 はグループごとに一行ずつ返します。問合せ結果 3- 2 が示しているよう
に、ラベルを使用して COUNT 式と SUM 式の結果に名前を付けます。
問合せ結果 3- 2
order_num
1001
1002
1003
1004
1005
1006
1007
1008
.
.
.
1015
1016
1017
1018
1019
1020
1021
1022
number
price
1
2
3
4
4
5
5
2
$250.00
$1200.00
$959.00
$1416.00
$562.00
$448.00
$1696.00
$940.00
1
4
3
5
1
2
4
3
$450.00
$654.00
$584.00
$1131.00
$1499.97
$438.00
$1614.00
$232.00
問合せ結果 3- 2 は表 items の行を注文番号が同じグループにまとめて、各グループご
との行数の COUNT を計算し、各品目の合計金額を出力します。
テキスト (TEXT) 型やバイト (BYTE) 型の列を GROUP BY 節に記述することはでき
ないので注意してください。グループ化するには、ソートができなければなりませ
んがテキスト (TEXT) 型とバイト (BYTE) 型のデータについての自然なソート順は
ありません。
ORDER BY 節とは異なり、GROUP BY 節はデータの順序付けを行いません。特定
の順序でデータをソートしたい場合、または選択対象の並びの中の集合によって
ソートしたい場合は、GROUP BY 節の後に ORDER BY 節を置きます。
問合せ 3- 3 は問合せ 3- 2 と同じですが、問合せ結果 3- 3 が示しているように、抽出
された行を価格の昇順にソートするための ORDER BY 節が記述されています。
問合せ 3- 3
SELECT order_num, COUNT(*) number, SUM (total_price) price
FROM items
GROUP BY order_num
ORDER BY price
3-6
Informix Guide to SQL: Tutorial
GROUP BY 節の使用方法
order_num
1010
1011
1013
1022
1001
1020
1006
1015
1009
.
.
.
1018
1002
1004
1014
1019
1021
1007
number
price
2
1
4
3
1
2
5
1
1
$84.00
$99.00
$143.80
$232.00
$250.00
$438.00
$448.00
$450.00
$450.00
5
2
4
2
1
4
5
$1131.00
$1200.00
$1416.00
$1440.00
$1499.97
$1614.00
$1696.00
問合せ結果 3- 3
第 2 章「簡単な SELECT 文の作成」で説明したように、ORDER BY 節で整数を使
用して、選択対象の並びでの列名の位置を示すことができます。GROUP BY 節でも
同様に、グループリスト内の列名や表示ラベルの位置を示すために整数を使用する
ことができます。
問合せ 3- 4 は、問合せ結果 3- 3 が示しているように、問合せ 3- 3 と同じ行を返します。
問合せ 3- 4
SELECT order_num, COUNT(*) number, SUM (total_price) price
FROM items
GROUP BY 1
ORDER BY 3
問合せ文を作成するときには、SELECT 節での選択対象の並びのうちで集計関数の
適用を受けない列を必ず GROUP BY 節でのグループの並びに含めてください。
GROUPBY 節を持つ SELECT 文が返さなければならない行数は、グループあたり一
行だけだからです。GROUP BY 節の後に指定されている行は、必ずグループ内の別
個の値を一つだけ反映し、その値を返すことができます。しかし、GROUP BY 節の
後に指定されていない列の値は、グループ内の行の値がそれぞれ異なる可能性があ
ります ( つまり、一つのグループに対して複数の値を持つことになるため、問合せ
の結果を返せなくなります )。
高度な SELECT 文の作成
3-7
HAVING 節の使用方法
問合せ 3- 5 が示しているように、表を結合する SELECT 文の中で GROUP BY 節を
使用することができます。
問合せ 3- 5
SELECT o.order_num, SUM (i.total_price)
FROM orders o, items i
WHERE o.order_date > '01/01/93'
AND o.customer_num = 110
AND o.order_num = i.order_num
GROUP BY o.order_num
問合せ 3- 5 は、表 orders と表 items を結合して、これに表の別名を付け、問合せ結
果 3- 5 に示す行を返します。
問合せ結果 3- 5
order_num
1008
1015
(sum)
$940.00
$450.00
HAVING 節の使用方法
HAVING 節は、通常 GROUP BY 節を補足するために使用し、行がグループ化され
た後で、グループに対し選択のための一つまたは複数の条件を適用します。グルー
プ上の HAVING 節の効果は、WHERE 節が表の個々の行に条件を適用するのと似て
います。HAVING 節の利点はその探索条件に集計関数を記述できる点です。
WHERE 節の探索条件には集計関数を記述できません。
それぞれの HAVING 節の条件では、一つの列やグループに適用された集計関数の値
が、グループの別の集計関数の値や定数と比較されます。HAVING 節を使用して、
グループの並びの列の値と集計関数の値の両方に条件を設定することができます。
問合せ 3- 6 は、品目が 3 つ以上のすべての注文について品目ごとの平均合計金額を
返します。HAVING 節は、作成された各グループをテストし、複数の行で構成され
たグループを選択します。
問合せ 3- 6
SELECT order_num, COUNT(*) number, AVG (total_price) average
FROM items
GROUP BY order_num
HAVING COUNT(*) > 2
3-8
Informix Guide to SQL: Tutorial
HAVING 節の使用方法
問合せ結果 3- 6
order_num
1003
1004
1005
1006
1007
1013
1016
1017
1018
1021
1022
1023
number
3
4
4
5
5
4
4
3
5
4
3
6
average
$319.67
$354.00
$140.50
$89.60
$339.20
$35.95
$163.50
$194.67
$226.20
$403.50
$77.33
$137.33
GROUP BY 節を使用せずに HAVING 節を使用すると、HAVING 節の探索条件は、
その条件を満たすすべての行に適用されます。つまり、探索条件を満たすすべての
行が一つのグループを構成します。
問合せ 3- 7 は問合せ 3- 6 を書き直したもので、一行の結果、つまり表のすべての列
total_price( 合計価格 ) の平均を返します。
問合せ 3- 7
SELECT AVG (total_price) average
FROM items
HAVING count(*) > 2
問合せ結果 3- 7
average
$270.97
問合せ 3- 6 のように問合せ 3- 7 に選択対象の並びで集計関数が適用されていない列
order_ num が含まれている場合は、グループの並びのその列に GROUP BY 節を指定
しなければなりません。また、HAVING 節での条件が満たされていない場合は、列
ヘッダが表示され、該当する行が見つからなかったことを示すメッセージが表示さ
れます。
高度な SELECT 文の作成
3-9
高度な結合の作成
問合せ 3- 8 は、SQL の Informix バージョンで使用できるすべての SELECT 文の節が
含まれています ( プログラム変数またはホスト変数を指定できる INTO 節は、SQL
API でのみ使用できます )。
問合せ 3- 8
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/93'
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
問合せ 3- 8 は、表 orders と表 items を結合します。表示ラベル、表の別名、列標識
として使用されている整数を使用します。データのグループ化と順序付けも行いま
す。また、問合せ結果 3- 8 が示しているように次の結果を一時表に入れます。
問合せ結果 3- 8
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
高度な結合の作成
第 2 章「簡単な SELECT 文の作成」では、SELECT 文に WHERE 節を使用して、一
つまたは複数の列を結合列として複数の表を結合する方法を説明しました。そこで
説明した結合は、自然結合と等結合の二種類でした。
この章では、二種類の結合よりもさらに複雑な、セルフ結合と外部結合の使用につ
いて説明します。表セルフ結合やアウター結合においても、第 2 章で説明した単純
な結合と同じように、表の別名や表示ラベルを使用することができます。表に別名
を定義したり、式に表示ラベルを割り当てると、複数表からなる問合せ文の記述を
簡略化することができます。また、一時表にデータをソートする ORDER BY 節が
入った SELECT 文を発行することもできます。
3-10
Informix Guide to SQL: Tutorial
セルフ結合
セルフ結合
結合では必ずしも二つの異なる表を結合させる必要はありません。表をそれ自体に
結合させて、セルフ結合を作成できます。列内の値を同じ列内の別の値と比較した
いときには、表をその表自体と結合すると便利な場合があります。
セルフ結合を作成するには、FROM 節から表を二回リストして、これに一回ごとに
異なる別名を付けます。SELECT 節と WHERE 節ではこれらの別名を使用して、二
つの別な表があるかのように参照します。(SELECT 文内の別名は、このマニュアル
の第 2 章「簡単な SELECT 文の作成」に記載されていて、
『Informix Guide to SQL:
Syntax』に説明があります。)
異なる表の結合と同じように、セルフ結合でも算術式を使用できます。NULL を検
査することもできますし、ORDER BY 節を使用して、指定した列の値を昇順または
降順にソートすることもできます。
問合せ 3- 9 は、ship_weight が 5 倍以上異なり、ship_date が NULL ではないオー
ダーのペアを探索します。そして、ship_date によってデータを順序付けます。
問合せ 3- 9
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
order_num ship_weight
1004
1004
1004
1007
1007
1007
1007
1007
1007
1005
1005
1005
1012
1012
1013
1017
1018
.
.
.
95.80
95.80
95.80
125.90
125.90
125.90
125.90
125.90
125.90
80.80
80.80
80.80
70.80
70.80
60.80
60.00
70.50
ship_date
order_num
05/30/1998
05/30/1998
05/30/1998
06/05/1998
06/05/1998
06/05/1998
06/05/1998
06/05/1998
06/05/1998
06/09/1998
06/09/1998
06/09/1998
06/29/1998
06/29/1998
07/10/1998
07/13/1998
07/13/1998
1011
1020
1022
1015
1020
1022
1011
1001
1009
1011
1020
1022
1011
1020
1011
1011
1011
ship_weight ship_date
10.40
14.00
15.00
20.60
14.00
15.00
10.40
20.40
20.40
10.40
14.00
15.00
10.40
14.00
10.40
10.40
10.40
問合せ結果 3- 9
07/03/1998
07/16/1998
07/30/1998
07/16/1998
07/16/1998
07/30/1998
07/03/1998
06/01/1998
06/21/1998
07/03/1998
07/16/1998
07/30/1998
07/03/1998
07/16/1998
07/03/1998
07/03/1998
07/03/1998
高度な SELECT 文の作成
3-11
セルフ結合
セルフ結合の結果を一時表に格納したい場合は、SELECT 文に INTO TEMP 節を追
加して、それらに表示ラベルを割り当てることにより、少くとも一組の列を名前変
更してください。この処置を行わないと、列名の重複が原因でエラーが発生し、一
時表が作成されません。
問合せ 3- 10 は、問合せ 3- 9 に似ています。表 orders から選択されたすべての列に
表示ラベルを付け、shipping( 出荷 ) という名前の一時表に格納します。
問合せ 3- 10
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
この表から SELECT * で問合せを行うと、問合せ結果 3- 10 が示している行が表示
されます。
orders1 purch1
1004
1004
1004
1005
1005
1005
1007
1007
1007
1007
1007
1007
1012
1012
1013
1017
1018
1018
1019
1019
1019
1023
ship1
8006
8006
8006
2865
2865
2865
278693
278693
278693
278693
278693
278693
278701
278701
B77930
DM354331
S22942
S22942
Z55709
Z55709
Z55709
KF2961
05/30/1998
05/30/1998
05/30/1998
06/09/1998
06/09/1998
06/09/1998
06/05/1998
06/05/1998
06/05/1998
06/05/1998
06/05/1998
06/05/1998
06/29/1998
06/29/1998
07/10/1998
07/13/1998
07/13/1998
07/13/1998
07/16/1998
07/16/1998
07/16/1998
07/30/1998
orders2
1011
1020
1022
1011
1020
1022
1001
1009
1011
1015
1020
1022
1011
1020
1011
1011
1011
1020
1011
1020
1022
1011
purch2
ship2
B77897
W2286
W9925
B77897
W2286
W9925
B77836
4745
B77897
MA003
W2286
W9925
B77897
W2286
B77897
B77897
B77897
W2286
B77897
W2286
W9925
B77897
07/03/1998
07/16/1998
07/30/1998
07/03/1998
07/16/1998
07/30/1998
06/01/1998
06/21/1998
07/03/1998
07/16/1998
07/16/1998
07/30/1998
07/03/1998
07/16/1998
07/03/1998
07/03/1998
07/03/1998
07/16/1998
07/03/1998
07/16/1998
07/30/1998
07/03/1998
問合せ結果 3- 10
表はその表自体と何回でも結合できます。セルフ結合できる最大回数は、利用可能
なシステム資源によって異なります。
3-12
Informix Guide to SQL: Tutorial
セルフ結合
問合せ 3- 11 のセルフ結合では、表 stock( 取扱品目 ) の品目のうち、3 つのメーカー
から提供されるものを取り出します。セルフ結合では WHERE 節の最後の二つの条
件を指定することによって、重複するメーカーコードを抽出した行から除去できま
す。
問合せ 3- 11
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
問合せ結果 3- 11
manu_code
manu_code
manu_code
stock_num
description
HRO
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
HRO
HRO
HRO
HSK
ANZ
ANZ
ANZ
.
.
.
HRO
KAR
KAR
KAR
NKL
HSK
NRG
HRO
HRO
HRO
HSK
HSK
PRC
HSK
HSK
PRC
PRC
KAR
HRO
HRO
SMT
SMT
HSK
PRC
SHM
PRC
SHM
SHM
PRC
SHM
SHM
SHM
NKL
NKL
KAR
1
5
110
110
110
110
110
110
110
110
110
110
201
205
301
baseball gloves
tennis racquet
helmet
helmet
helmet
helmet
helmet
elmet
helmet
helmet
helmet
helmet
golf shoes
3 golf balls
running shoes
PRC
NKL
NKL
PRC
PRC
SHM
PRC
SHM
SHM
SHM
301
301
301
301
301
running shoes
running shoes
running shoes
running shoes
running shoes
高度な SELECT 文の作成
3-13
セルフ結合
給与表から行を選択して、上司よりも収入の多い従業員を判別したい場合は、問合
せ 3- 12a が示しているセルフ結合を作成できます。
問合せ 3- 12a
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
WHERE emp.gross_pay > mgr.gross_pay
AND emp.level < mgr.level
AND emp.dept_num = mgr.dept_num
ORDER BY 4
問合せ 3- 12b は、相関副問合せを使用して、注文された価格の高い品目の上位 10
品目を抽出して、表示します。
問合せ 3- 12b
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
問合せ 3- 12b は、問合せ結果 3- 12 が示している 10 個の行を返します。
問合せ結果 3- 12
order_num
total_price
1018
1013
1003
1005
1006
1013
1010
1013
1022
1023
$15.00
$19.80
$20.00
$36.00
$36.00
$36.00
$36.00
$40.00
$40.00
$40.00
同じような問合せ文を作成し、社内で最も年功が高い 10 人の従業員を探して表示
することもできます。
相関副問合せおよび非相関副問合せについては、3-30 ページの「SELECT 文中の副
問合せ文」に説明されています。
3-14
Informix Guide to SQL: Tutorial
セルフ結合
rowid( 行 ID 番号 ) の値の使用方法
データベースサーバは一意の行 ID 番号を断片化されていない表に割り当てます。
断片化された表の行には列 rowid は含まれません。断片化された表については、表
に列 rowid を追加するために WITH ROWIDS を使用することができます。
アプリケーションでのアクセス方法には、行 ID 番号ではなく主キーを使用するこ
とをお薦めします。主キーは SQL の ANSI 仕様で定義されているため、主キーを使
用してデータにアクセスすることで、アプリケーションの移植性が高まります。ま
た、データベースサーバでは、主キーを使用して断片化されている表内のデータに
アクセスした方が、行 ID 番号を使用して同一データにアクセスするよりも、所要
時間が短くて済みます。
高度な意思決定支援オプションと拡張型並列オプションを使用した Informix
Dynamic Server は、断片化された表の行 ID 番号をサポートしないため、断片化され
た表の行を識別するには列値を使用しなければなりません。 ♦
AD/XP
行 ID 番号と表についての詳細は、『Informix Guide to Database Design and
Implementation』を参照してください。
セルフ結合で隠れた列 rowid を使用して、同じ列の重複値を表から探すことができ
ます。以下の例の、条件 x.rowid !=y.rowid は、「行 x は行 y と同じ行ではない」こ
とを意味しています。
問合せ 3- 13 は表 cust_calls( サービス記録 ) からデータを 2 回選択して、それに表の
別名 x と y を割り当てています。
問合せ 3- 13
SELECT x.rowid, x.customer_num
FROM cust_calls x, cust_calls y
WHERE x.customer_num = y.customer_num
AND x.rowid != y.rowid
問合せ 3- 13 は、列 customer_num 内の重複値を探索し、その行 ID 番号に対して、
問合せ結果 3- 13 が示しているペアを見つけます。
rowid
customer_num
515
769
116
116
問合せ結果 3- 13
高度な SELECT 文の作成
3-15
セルフ結合
問合せ 3- 13 が示しているように、最後の条件を書き込むことができます。
AND x.rowid != y.rowid
AND NOT x.rowid = y.rowid
重複値を見つけるもう一つの方法は、問合せ 3- 14 が示しているように、相関副問
合せを使用する方法です。
問合せ 3- 14
SELECT x.customer_num, x.call_dtime
FROM cust_calls x
WHERE 1 <
(SELECT COUNT (*) FROM cust_calls y
WHERE x.customer_num = y.customer_num)
問合せ 3- 14 は、問合せ 3- 13 と同じ二つの重複する customer_num の値を見つけ、
問合せ結果 3- 14 が示している行を返します。
問合せ結果 3- 14
customer_num
116
116
call_dtime
1997-11-28 13:34
1997-12-21 11:24
セルフ結合の初めの方に示されている rowid を使用して、データベース表の行と関
連付けられている内部レコード番号を見つけることができます。rowid は、実際は
どの表にも存在する隠れた列です。rowid の連続値には特に意味はなく、チャンク
内の物理データの格納場所によって異なる場合があります。rowid が例とは異なっ
ている場合があります。rowid の使用方法についての詳細は、『Administrator’s
Guide』を参照してください。
3-16
Informix Guide to SQL: Tutorial
セルフ結合
問合せ 3- 15 では、SELECT 節で rowid とワイルドカードアスタリスクシンボル (*)
を使用して、表 manufact( メーカー ) の各行をその rowid とともに抽出します。
問合せ 3- 15
SELECT rowid, * FROM manufact
rowid
257
258
259
260
261
262
263
264
265
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- 15
3
5
7
5
4
30
21
8
9
問合せ 3- 16 が示しているように、特定の列を選択するときに rowid を使用するこ
ともできます。
問合せ 3- 16
SELECT rowid, manu_code FROM manufact
問合せ結果 3- 16
rowid manu_code
258
261
260
263
264
259
265
262
257
ANZ
HRO
HSK
KAR
NKL
NRG
PRC
SHM
SMT
高度な SELECT 文の作成
3-17
セルフ結合
rowid を WHERE 節で使用すると、その内部レコード番号に基づいて行を抽出する
ことができます。この方法は、rowid 以外に一意な列が表に存在しない場合に便利
です。問合せ 3- 17 では、問合せ 3- 16 の結果の rowid を使用します。
問合せ 3- 17
SELECT * FROM manufact WHERE rowid = 263
問合せ 3- 17 は、問合せ結果 3- 17 が示している行を返します。
manu_code
manu_name lead_time
KAR
Karsten
問合せ結果 3- 17
21
USER 関数の使用方法
rowid と USER 関数を組み合わせて、表に関する追加情報を入手できます。
問合せ 3- 18 は、username というラベルを USER 式の列に割り当てて、表 cust_calls
に関する次の情報を返します。
問合せ 3- 18
SELECT USER username, rowid FROM cust_calls
username
zenda
zenda
zenda
zenda
zenda
zenda
zenda
rowid
問合せ結果 3- 18
257
258
259
513
514
515
769
rowid を選択するときに、USER 関数を WHERE 節に使用することもできます。
3-18
Informix Guide to SQL: Tutorial
セルフ結合
問合せ 3- 19 は、この問合せを行うユーザによって挿入または更新される行のみに
rowid を返します。
問合せ 3- 19
SELECT rowid FROM cust_calls WHERE user_id = USER
たとえば、ユーザ richc が問合せ 3- 19 を使用した場合には、問合せ結果 3- 19 は出
力を示します。
問合せ結果 3- 19
rowid
258
259
DBSERVERNAME 関数の使用方法
DBSERVERNAME 関数またはそのシノニムの SITENAME を問合せに追加して、現
行データベースの常駐場所を知ることができます。
問合せ 3- 20 は、rowid と tabid( システムカタログ表のシリアル時間隔表識別子 ) だ
けではなく、データベースサーバ名とユーザ名も探します。
問合せ 3- 20
SELECT DBSERVERNAME server, tabid, rowid, USER username
FROM systables
WHERE tabid >= 105 OR rowid <= 260
ORDER BY rowid
問合せ 3- 20 は、問合せ結果 3- 20 に示されているとおりに表示ラベルを
DBSERVERNAME 式と USER 式に割り当て、systables システム カタログ表から 10
行を返します。
問合せ結果 3- 20
server
manatee
manatee
manatee
manatee
manatee
manatee
manatee
manatee
manatee
manatee
tabid
1
2
3
4
105
106
107
108
109
110
rowid username
257
258
259
260
274
1025
1026
1027
1028
1029
zenda
zenda
zenda
zenda
zenda
zenda
zenda
zenda
zenda
zenda
高度な SELECT 文の作成
3-19
外部結合
rowid は変わることがあるので、絶対に rowid を永久表に格納したり、外部キーと
して使用したりしないでください。たとえば、表をいったん削除してから外部デー
タから再ロードすると、rowid の値はすべて変わります。
USER 文と DBSERVERNAME 文については、第 2 章「簡単な SELECT 文の作成」
で説明されています。
外部結合
第 2 章「簡単な SELECT 文の作成」には、単純結合の作成方法と使用方法が説明
されています。単純結合では、結合の対象となる二つ以上の表が対等に扱われます
が、外部結合では非等価的に扱われます。外部結合は、表 dominant(preserved とも
呼ばれる ) のうちの一つをその他の従表の上に作成します。
データベースサーバは次の外部結合の 3 つの基本的なタイプをサポートします。
■
二つの表の単純な外部結合
■
第 3 の表との単純な外部結合
■
第 3 の表に対する二つの表との外部結合
ここでは、これらのタイプの外部結合について説明します。構文、使用方法、およ
び外部結合論理についての詳細は、
『Informix Guide to SQL: Syntax』を参照してくだ
さい。
単純結合では、結合条件を満たす行の組合せのみが表から取り出され、問合せ結果
として表示されます。結合条件を満たさない行は無視されます。
外部結合でも、結合条件を満たす行の組合せが表から取り出されて、問合せ結果に
表示されます。さらに単純結合の場合と異なるのは、主表の行と一致する行が従表
に見つからない場合でも、主表の行は捨てられずに保存される点です。主表の行に
従表の行と対応しない列があれば、選択する列に対して射影が行われる前に、従表
の NULL である行が代わりに使用されます。
外部結合は、条件を従表に適用する一方、結合条件を主表の行に順次適用します。
条件は WHERE 節に指定されます。
3-20
Informix Guide to SQL: Tutorial
外部結合
外部結合では、SELECT 節、FROM 節、および WHERE 節を必ず指定してくださ
い。単純結合を外部結合に変換するには、FROM 節の従表の名前の直前にキーワー
ド OUTER を挿入します。後述するように、キーワード OUTER は問合せ文に何回
でも指定できます。
外部結合を多用する前に、一つまたは複数の単純結合が機能できるかどうかを決定
してください。結合の結果に他の表からの補足情報を必要としないときは、多くの
場合は単純結合だけで十分です。
ここで説明する例では、記述を簡単にするために表の別名を使用しています。表の
別名についての詳細は、第 2 章「簡単な SELECT 文の作成」を参照してください。
単純結合
問合せ 3- 21 は、第 2 章「簡単な SELECT 文の作成」に示したように、表 customer(
顧客情報 ) と表 cust_calls を単純結合した例です。
問合せ 3- 21
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
問合せ 3- 21 は、問合せ結果 3- 21 が示しているように、顧客サービスに顧客が電話
した行のみを返します。
高度な SELECT 文の作成
3-21
外部結合
問合せ結果 3- 21
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
customer_num
lname
company
phone
call_dtime
call_descr
110
Jaeger
AA Athletics
415-743-3611
1998-07-07 10:24
Order placed one month ago (6/7) not received.
customer_num
lname
company
phone
call_dtime
call_descr
119
Shorter
The Triathletes Club
609-663-6079
1998-07-01 15:00
Bill does not reflect credit from previous order
customer_num
lname
company
phone
call_dtime
call_descr
121
Wallack
City Sports
302-366-7511
1998-07-10 14:05
Customer likes our merchandise. Requests that we
stock more types of infant joggers. Will call back
to place order.
customer_num
lname
company
phone
call_dtime
call_descr
127
Satifer
Big Blue Bike Shop
312-944-5691
1998-07-31 14:30
Received Hero watches (item # 304) instead of
ANZ watches
customer_num
lname
company
phone
call_dtime
call_descr
116
Parmelee
Olympic City
415-534-8822
1997-11-28 13:34
Received plain white swim caps (313 ANZ) instead
of navy with team logo (313 SHM)
customer_num
lname
company
phone
call_dtime
call_descr
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.
3-22
Informix Guide to SQL: Tutorial
外部結合
二つの表の単純な外部結合
問合せ 3- 22 は、前の例と同じ選択対象の並び、表および比較条件を使用していま
すが、今度は単純な外部結合を作成します。
問合せ 3- 22
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
この問合せ文では、表 cust_calls を従表にするために、キーワード OUTER を表
cust_calls の前に指定しています。外部結合にすると、顧客サービスに電話したかど
うかに関係なく、顧客全員に関する情報が返されます。問合せ結果 3- 22 が示して
いるように、主表 customer のすべての行が抽出され、従表 cust_calls の列の該当す
る行に NULL が割り当てられます。
高度な SELECT 文の作成
3-23
外部結合
customer_num
lname
company
phone
call_dtime
call_descr
101
Pauli
All Sports Supplies
408-789-8075
customer_num
lname
company
phone
call_dtime
call_descr
102
Sadler
Sports Spot
415-822-1289
customer_num
lname
company
phone
call_dtime
call_descr
103
Currie
Phil’ s Sports
415-328-4543
customer_num
lname
company
phone
call_dtime
call_descr
104
Higgins
Play Ball!
415-368-1100
customer_num
lname
company
phone
call_dtime
call_descr
105
Vector
Los Altos Sports
415-776-3249
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
customer_num
lname
company
phone
call_dtime
call_descr
107
Ream
Athletic Supplies
415-356-9876
customer_num
lname
company
phone
call_dtime
call_descr
108
Quinn
Quinn’ s Sports
415-544-8729
3-24
Informix Guide to SQL: Tutorial
問合せ結果 3- 22
外部結合
第 3 の表に対する単純結合との外部結合
問合せ 3- 23 は、第 3 の表に対する単純結合との外部結合を示しています。この第 2
のタイプの外部結合は入れ子になった単純結合と呼ばれています。
問合せ 3- 23
SELECT c.customer_num, c.lname, o.order_num,
i.stock_num, i.manu_code, i.quantity
FROM customer c, OUTER (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
問合せ 3- 23 は、最初に表 orders と表 items に対して単純結合を実行して、列
manu_code( メーカーコード ) の値が KAR または SHM である品目のすべての注文に
ついての情報を抽出します。次に外部結合を実行して、この情報を主表 customer の
データと結合します。オプションの ORDER BY 節は、問合せ結果 3- 23 が示してい
るフォームにデータを再編成します。
高度な SELECT 文の作成
3-25
外部結合
問合せ結果 3- 23
customer_num
114
118
113
103
115
123
123
125
104
110
120
120
111
112
128
109
126
122
116
101
124
108
107
102
127
127
127
119
117
105
121
106
lname
Albertson
Baxter
Beatty
Currie
Grant
Hanlon
Hanlon
Henry
Higgins
Jaeger
Jewell
Jewell
Keyes
Lawson
Lessor
Miller
Neelie
O’ Brian
Parmelee
Pauli
Putnum
Quinn
Ream
Sadler
Satifer
Satifer
Satifer
Shorter
Sipes
Vector
Wallack
Watson
order_num
stock_num
manu_code
quantity
1020
1020
301
204
KAR
KAR
4
2
1017
1017
202
301
KAR
SHM
1
2
1019
111
SHM
3
1021
202
KAR
3
1023
1023
1023
1016
306
105
110
101
SHM
SHM
SHM
SHM
1
1
1
2
1018
302
KAR
3
第 3 の表に対する二つの表の外部結合
問合せ 3- 24 は、二つの表のそれぞれの外部結合の結果と第 3 の表との外部結合を
示しています。この第 3 のタイプの外部結合では、結合関係は主表と従表との間で
のみ成立します。
問合せ 3- 24
SELECT c.customer_num, 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
3-26
Informix Guide to SQL: Tutorial
外部結合
問合せ 3- 24 は、従表 orders と cust_calls を主表 customer に個別に結合します。二つ
の従表どうしは結合しません。INTO TEMP 節は、問合せ結果 3- 24 が示しているよ
うに結果を一時表に格納して、さらに操作や問合せを実行できるようにします。
問合せ結果 3- 24
customer_num
114
118
113
103
115
123
125
104
104
104
104
110
110
120
111
112
109
128
126
122
116
116
101
124
108
107
102
127
119
117
117
105
121
106
106
lname
Albertson
Baxter
Beatty
Currie
Grant
Hanlon
Henry
Higgins
Higgins
Higgins
Higgins
Jaeger
Jaeger
Jewell
Keyes
Lawson
Miller
Moore
Neelie
O’ Brian
Parmelee
Parmelee
Pauli
Putnum
Quinn
Ream
Sadler
Satifer
Shorter
Sipes
Sipes
Vector
Wallack
Watson
Watson
order_num order_date call_dtime
1010 06/17/1998
1020 07/11/1998
1003 05/22/1998
1001 05/20/1998
1013 06/22/1998
1011 06/18/1998
1015 06/27/1998 1998-07-07 10:24
1008 06/07/1998 1998-07-07 10:24
1017 07/09/1998
1009 06/14/1998
1006 05/30/1998
1022 07/24/1998
1019 07/11/1998
1005 05/24/1998 1997-12-21 11:24
1005 05/24/1998 1997-11-28 13:34
1002 05/21/1998
1021 07/23/1998
1023 07/24/1998 1998-07-31 14:30
1016 06/29/1998 1998-07-01 15:00
1007 05/31/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
問合せ 3- 25 が示しているように、問合せ 3- 24 が二つの従表 o と x の間に結合条件
を作成しようとすると、エラーメッセージが返されて、両面外部結合の作成を示し
ます。
問合せ 3- 25
WHERE o.customer_num = x.customer_num
高度な SELECT 文の作成
3-27
外部結合
外部結合を組み合わせる結合
複数のレベルの入れ子を達成するために、三種類の外部結合のどの組合せの結合も
作成できます。問合せ 3- 26 は、2 つの表の単純な外部結合と二番目の外部結合の組
合せの結果である結合を作成しています。
問合せ 3- 26
SELECT c.customer_num, 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
問合せ 3- 26 は、まず、表 orders と表 items で外部結合を実行し、KAR または SHM
の manu_code で項目についてのすべての注文に関する情報を抽出します。次いで、
この情報と主表 customer からのデータを組み合わせる第 2 の外部結合を実行しま
す。問合せ 3- 26 は、以前の例が削除した注文番号を保存し、どちらの製造業者
コードも付いていない項目の注文行を戻します。問合せ結果 3- 26 は、ORDER BY
節がデータを再編成する方法を示します。
3-28
Informix Guide to SQL: Tutorial
外部結合
問合せ結果 3- 26
customer_num
114
118
113
103
115
123
123
125
104
104
104
104
110
110
120
120
111
112
128
109
126
122
116
101
124
108
107
102
127
127
127
119
117
117
105
121
106
106
lname
Albertson
Baxter
Beatty
Currie
Grant
Hanlon
Hanlon
Henry
Higgins
Higgins
Higgins
Higgins
Jaeger
Jaeger
Jewell
Jewell
Keyes
Lawson
Lessor
Miller
Neelie
O’Brian
Parmelee
Pauli
Putnum
Quinn
Ream
Sadler
Satifer
Satifer
Satifer
Shorter
Sipes
Sipes
Vector
Wallack
Watson
Watson
order_num stock_num manu_code
1010
1020
1020
quantity
204 KAR
301 KAR
2
4
301 SHM
202 KAR
2
1
111 SHM
3
202 KAR
3
1023
1023
1023
1016
1012
1007
110
105
306
101
SHM
SHM
SHM
SHM
1
1
1
2
1018
1014
1004
302 KAR
3
1011
1001
1013
1003
1008
1015
1017
1017
1009
1006
1022
1019
1005
1002
1021
外部結合を第 3 の表との外部結合の結果に適用する場合、結合条件を 2 つの方法で
述べることができます。2 つの従表が結合されますが、主表と従表が共通列を共有
している場合、その結果に影響を与えることなくどちらの従表にも主表を結合する
ことができます。
高度な SELECT 文の作成
3-29
SELECT 文中の副問合せ文
SELECT 文中の副問合せ文
別の SELECT 文 ( または INSERT 文、DELETE 文および UPDATE 文 )WHERE 節に
入れ子になっている SELECT 文は、副問合せ文と呼ばれます。個々の副問合せ文に
は SELECT 節と FROM 節が含まれていなければなりません。副問合せ文は、デー
タベースサーバがその動作を最初に実行するように、カッコで囲まなければなりま
せん。
副問合せ文には、相関副問合せ文と非相関副問合せ文の 2 種類があります。副問合
せ文 ( 内側の SELECT 文とも呼ばれます ) は、生成する値がその外側の SELECT 文
の生成する値によって変わる場合に、相関副問合せ文と呼ばれます。それ以外の副
問合せ文はすべて、非相関副問合せ文です。
相関副問合せの重要な特徴は、相関副問合せは外側の SELECT 文の値に依存してい
るので、外側の SELECT 文が作成するすべての値に対して一回ずつ、繰り返し実行
しなければならないという点です。非相関副問合せ文は 1 回しか実行されません。
副問合せ文を含む SELECT 文は、独立した二つの SELECT 文の代わりに使用するこ
とがあります。
SELECT 文で副問合せ文を使用すると、次の操作を行うことができます。
■
式を、別の SELECT 文の結果と比較する。
■
別の SELECT 文の結果に式を含めるかどうかを決定する。
■
別の SELECT 文が行を選択するかどうかを決定する。
オプションの WHERE 節は、探索条件を狭めるために使用されることがよくありま
す。
3-30
Informix Guide to SQL: Tutorial
キーワード ALL の使用方法
副問合せ文は値を取り出して、その値を最初の SELECT 文か外側の SELECT 文に
返します。副問合せ文は、一つも値を返さないか、一つまたは一組の値を返しま
す。
■
副問合せ文が値を返さない場合、その問合せは行を返しません。このよう
な副問合せ文は NULL 値と同じです。
■
副問合せが値を一つ返す場合、値のフォームは一つの集計式または一つの
行と一つの列です。このような副問合せ文は単一の数値か文字値と同じで
す。
■
副問合せ文が値の並びまたはセットを返す場合、それらの値は一つの行ま
たは一つの列を表します。
SELECT 文の WHERE 節では次のキーワードを副問合せ文の前に記述します。
■
ALL
■
ANY
■
IN
■
EXISTS
関係演算子のどれかとキーワード ALL および ANY を一緒に使用すると、副問合せ
文が返した値の各値 (ALL) またはいずれか一つ (ANY) と比較することができます。
キーワード ANY の代わりにキーワード SOME を使用することもできます。演算子
IN は =ANY と同等です。反対の探索条件を作成するには、キーワード NOT か他の
関係演算子を使用してください。
演算子 EXISTS は、副問合せ文を検査して、何らかの値が返されたかを確認しま
す。つまり、副問合せ文の結果が NULL でないかどうかを調べます。テキスト
(TEXT) 型データやバイト (BYTE) 型データを使用する列が含まれている副問合せ文
では、キーワード EXISTS は使用できません。
副問合せ文での条件の作成に使用する構文についての詳細は、
『Informix Guide to
SQL: Syntax』を参照してください。
キーワード ALL の使用方法
副問合せ文が返すどの値についても比較が真であるかどうかを判定するには、副問
合せ文の前にキーワード ALL を指定します。副問合せ文が値を一つも返さない場
合は、探索条件は真です ( 値を返さない場合は、すべてのゼロ値について条件が真
とみなされます )。
高度な SELECT 文の作成
3-31
キーワード ANY の使用方法
問合せ 3- 27 は、注文番号が 1023 である注文に含まれるどの品目よりも合計金額が
少ない品目を見つけて、その品目を含むすべての注文についての情報を取り出しま
す。
問合せ 3- 27
SELECT order_num, stock_num, manu_code, total_price
FROM items
WHERE total_price < ALL
(SELECT total_price FROM items
WHERE order_num = 1023)
order_num
1003
1005
1006
1010
1013
1013
1018
stock_num
9
6
6
6
5
6
302
manu_code total_price
ANZ
SMT
SMT
SMT
ANZ
SMT
KAR
問合せ結果 3- 27
$20.00
$36.00
$36.00
$36.00
$19.80
$36.00
$15.00
キーワード ANY の使用方法
副問合せ文が返す値の少なくとも一つについて比較条件が真であることを判定する
には、副問合せ文の前にキーワード ANY( またはそのシノニム SOME) を指定しま
す。副問合せ文が値を一つも返さない場合は、探索条件は偽です ( 値が存在しない
ので、いずれの値についても条件は真になりません )。
問合せ 3- 28 は、注文番号が 1005 の注文に含まれる品目のいずれか一つの合計金額
よりも合計金額が多い品目を見つけて、その品目を含むすべての注文の注文番号を
返します。
問合せ 3- 28
SELECT DISTINCT order_num
FROM items
WHERE total_price > ANY
(SELECT total_price
FROM items
WHERE order_num = 1005)
3-32
Informix Guide to SQL: Tutorial
値を一つだけ返す副問合せ文
問合せ結果 3- 28
order_num
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
値を一つだけ返す副問合せ文
副問合せ文が外側の SELECT 文に返す値が一つだけであることがわかっている場合
は、キーワード ALL や ANY を使用する必要はありません。値を一つだけ返す副問
合せ文は、関数として扱うことができます。このような副問合せ文では、集計関数
を使用して値を一つ返す副問合せ文が作成されます。
高度な SELECT 文の作成
3-33
値を一つだけ返す副問合せ文
問合せ 3- 29 は、副問合せ文に集計関数 MAX を使用して、バレーボール用ネット
の数が最も多い注文の列 order_num を探します。
問合せ 3- 29
SELECT order_num FROM items
WHERE stock_num = 9
AND quantity =
(SELECT MAX (quantity)
FROM items
WHERE stock_num = 9)
問合せ結果 3- 29
order_num
1012
問合せ 3- 30 は、副問合せ文に集計関数 MIN を使用して、合計金額がその最小価格
の 10 倍よりも多い品目を取り出します。
問合せ 3- 30
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)
3-34
order_num
stock_num
1003
1018
1018
1018
8
307
110
304
manu_code total_price
ANZ
PRC
PRC
HRO
Informix Guide to SQL: Tutorial
$840.00
$500.00
$236.00
$280.00
問合せ結果 3- 30
相関副問合せ文
相関副問合せ文
問合せ 3- 31 は、表 orders から出荷日を日付の新しい順に 10 番目まで見つけて返す
相関副問合せ文の例です。結果をソートするための ORDER BY 節が副問合せ文の
後に指定されているのは、副問合せ文の内部には ORDER BY 節を指定できないた
めです。
問合せ 3- 31
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
この副問合せ文が作成する数値は、外側の SELECT 文が作成する値 main.ship_date
によって異なるので、これは相関副問合せ文です。したがって、この副問合せ文は
外側の SELECT 文が調べる各行について、1 回ずつ実行されなければなりません。
問合せ 3- 31 は、COUNT 関数を使用して値を外側の SELECT 文に返します。次に
ORDER BY 節がデータをソートします。この問合せは、問合せ結果 3- 31 が示して
いるように、10 の最新の出荷日を持つ 13 の行を見つけて返します。
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
問合せ結果 3- 31
問合せ 3- 31 のような相関副問合せ文を大規模な表に対して使用する場合は、列
ship_date にインデックスを付けて効率を向上させる必要があります。インデックス
を付けないと、この SELECT 文は表のすべての行に対して副問合せ文を一回実行す
るので非効率的です。インデックス作成と性能問題についての詳細は、お手持ちの
『Administrator’s Guide』と『Performance Guide』を参照してください。
高度な SELECT 文の作成
3-35
キーワード EXISTS の使用方法
キーワード EXISTS の使用方法
キーワード EXISTS は存在作用素としても知られています。問合せ 3- 32a が示して
いるように、副問合せ文が真になるのは、外側の SELECT が最低でも一つの行を見
つけた場合のみだからです。
問合せ 3- 32a
SELECT UNIQUE manu_name, lead_time
FROM manufact
WHERE EXISTS
(SELECT * FROM stock
WHERE description MATCHES '*shoe*'
AND manufact.manu_code = stock.manu_code)
IN を使用する問合せ文に相当する問合せ文を、EXISTS を使用して構築できます。
問合せ 3- 32b は、問合せ 3- 32a と同じ結果を返す問合せを構築する IN 述部を使用
します。
問合せ 3- 32b
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
問合せ 3- 32a と問合せ 3- 32b は、何らかの種類の靴を製造するメーカーの行と、製
品を注文する場合の納期を返します。問合せ結果 3- 32 は戻り値を示しています。
問合せ結果 3- 32
manu_name
Anza
Hero
Karsten
Nikolus
ProCycle
Shimara
lead_time
5
4
21
8
9
30
これらの問合せの探索条件とは反対の探索条件を作成するには、キーワード NOT を
IN や EXISTS に追加します。NOT IN の代わりに !=ALL を使用することもできます。
3-36
Informix Guide to SQL: Tutorial
キーワード EXISTS の使用方法
問合せ 3- 33 で示すように、同じ操作を二つの方法で行うことができます。データ
ベースの設計と表のサイズによって、一方の方法が他方よりもデータベースサーバ
に対する負担が少ない場合があります。どちらの問合せが適切かを知るには、SET
EXPLAIN コマンドを使用して問合せ計画の一覧を表示してください。SET
『Performance Guide』および『Informix Guide to SQL:
EXPLAIN コマンドについては、
Syntax』に説明されています。
問合せ 3- 33
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)
問合せ 3- 33 の個々の文は、問合せ結果 3- 33 が示している行を返します。これらの
行は、注文をしなかった顧客を示します。
問合せ結果 3- 33
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
キーワード EXISTS と IN は積として知られている集合演算のために使用され、キー
ワード NOT EXISTS と NOT IN は差として知られている集合演算のために使用されま
す。これらの概念については、3-39 ページの「集合演算」に説明されています。
問合せ 3- 34 は、表 items に対して副問合せを実行し、まだ注文されていない表
stock 内のすべての品目を示します。
問合せ 3- 34
SELECT stock.* FROM stock
WHERE NOT EXISTS
(SELECT * FROM items
WHERE stock.stock_num = items.stock_num
AND stock.manu_code = items.manu_code)
高度な SELECT 文の作成
3-37
キーワード EXISTS の使用方法
問合せ 3- 34 は、問合せ結果 3- 34 が示している行を返します。
問合せ結果 3- 34
stock_num
101
102
102
105
106
107
108
109
110
110
112
113
201
202
203
205
205
301
301
301
301
302
303
305
306
308
309
310
310
311
312
312
313
313
manu_code
description
PRC
SHM
PRC
PRC
PRC
PRC
SHM
SHM
ANZ
HRO
SHM
SHM
KAR
NKL
NKL
NKL
HRO
NKL
HRO
PRC
ANZ
HRO
KAR
HRO
PRC
PRC
SHM
SHM
ANZ
SHM
SHM
HRO
SHM
ANZ
bicycle tires
bicycle brakes
bicycle brakes
bicycle wheels
bicycle stem
bicycle saddle
crankset
pedal binding
helmet
helmet
12-spd, assmbld
18-spd, assmbld
golf shoes
metal woods
irons/wedge
3 golf balls
3 golf balls
running shoes
running shoes
running shoes
running shoes
ice pack
socks
first-aid kit
tandem adapter
twin jogger
ear drops
kick board
kick board
water gloves
racer goggles
racer goggles
swim cap
swim cap
unit_price
$88.00
$220.00
$480.00
$53.00
$23.00
$70.00
$45.00
$200.00
$244.00
$260.00
$549.00
$685.90
$90.00
$174.00
$670.00
$312.00
$312.00
$97.00
$42.50
$75.00
$95.00
$4.50
$36.00
$48.00
$160.00
$280.00
$40.00
$80.00
$84.00
$48.00
$96.00
$72.00
$72.00
$60.00
unit
unit_descr
box
case
case
pair
each
pair
each
case
case
case
each
each
each
case
case
case
case
each
each
each
each
each
box
case
each
each
case
case
case
box
box
box
box
box
4/box
4 sets/case
4 sets/case
pair
each
pair
each
4 pairs/case
4/case
4/case
each
each
each
2 sets/case
2 sets/case
24/case
24/case
each
each
each
each
each
24 pairs/box
4/case
each
each
20/case
10/case
12/case
4 pairs/box
12/box
12/box
12/box
12/box
SELECT 文が持つことができる副問合せの数に論理的な制限はありませんが、どん
な文のサイズも、文字列と見なされる場合には物理的に制限されます。しかし、こ
の制限は通常作成する文の長さよりも長いので問題にはならないでしょう。
3-38
Informix Guide to SQL: Tutorial
集合演算
データベースに情報が正しく入力されたかを確認したい場合があるかもしれませ
ん。データベース内のエラーを見つける一つの方法として、エラーが存在するとき
のみ出力を返す問合せ文を書く方法があります。この種の副問合せは、問合せ 3- 35
が示しているように、一種の監査問合せの役割を果たします。
問合せ 3- 35
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)
問合せ 3- 35 は、注文された品目の合計金額がその品目の単価と数量を掛けたもの
と一致しない行だけを返します。値引きが適用されていないなければ、それらの返
された行は、データベースに正しく入力されなかったと考えられます。この問合せ
文では、エラーが発生したときにだけ行を返します。情報が正しくデータベースに
挿入されていれば、行は返されません。
問合せ結果 3- 35
item_num
1
2
order_num stock_num
manu_code
1004
1006
HRO
NRG
1
5
quantity
total_price
1
5
$960.00
$190.00
集合演算
標準の集合演算である和、積、差を使用してデータベース情報を操作することがで
きます。この 3 つの演算では、更新、挿入または削除を実行した後にデータベース
の整合性を検査するために SELECT 文を使用します。これらの演算は、たとえば
データを履歴表に転送して、元の表からデータを削除する前に履歴表に正しいデー
タが入っていることを確認したい場合に便利です。
高度な SELECT 文の作成
3-39
和の集合演算
和の集合演算
和の演算では、UNION 演算子を使用して、二つの問合せ文を一つの複合問合せ文
に結合します。キーワード UNION を複数の SELECT 文の間に使用すればそれらを
結合して、元の表の一部または全部に存在している行を含む一時表を作成すること
ができます。ビューの定義の中で UNION 演算子を使用することもできます。
図 3-1
和集合演算
SELECT DISTINCT stock_num, manu_code
FROM stock
WHERE unit_price < 25.00
quantity
UNION
SELECT stock_num, manu_code
FROM items
WHERE quantity > 3
25.00 以下
3 よりも
大きい
3 以下
該当
該当
unit_price < 25.00
quantity > 3
unit_price
25.00 以上
該当
キーワード UNION は、二つの問合せ文が取り出す行をすべて結合し、重複行を削
除して、残った行を返します。問合せの結果は単一の結果に結合されるので、各問
合せでの選択対象の並びは、同じ数の列を持っていなければなりません。また、各
表から選択される該当する列には同じデータ型が含まれていなければならず ( 文字
(CHARACTER) 型の列は同じ長さでなければなりません )、これらの該当する列は、
すべて NULL を許可するか、あるいは、すべて NULL を許可しないかのどちらかで
なければなりません。
3-40
Informix Guide to SQL: Tutorial
和の集合演算
問合せ 3- 36 は、表 stock と表 items の列 stock_num と列 manu_code に対して和の集
合演算を実行します。
問合せ 3- 36
SELECT DISTINCT stock_num, manu_code
FROM stock
WHERE unit_price < 25.00
UNION
SELECT stock_num, manu_code
FROM items
WHERE quantity > 3
問合せ結果 3- 36 が示しているように、問合せ 3- 36 は、単価が $25.00 未満の品目、
または注文数量が 3 つよりも多かった品目を選択して、その stock_num と
manu_code をリストします。
問合せ結果 3- 36
stock_num manu_code
5
5
5
9
103
106
201
301
302
302
ANZ
NRG
SMT
ANZ
PRC
PRC
NKL
KAR
HRO
KAR
ORDER BY 節を記述する場合は、問合せ 3- 36 の後に指定してください。また、
ソートする列の参照には、識別子ではなく整数を使用してください。ソートは集合
演算が完了した後で行われます。
問合せ 3- 37
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
高度な SELECT 文の作成
3-41
和の集合演算
問合せ 3- 37 の複合問合せは問合せ 3- 36 と同じ行を選択しますが、問合せ結果 337 が示しているように、メーカーコード順に表示します。
問合せ結果 3- 37
stock_num manu_code
5
9
302
301
302
201
5
103
106
5
ANZ
ANZ
HRO
KAR
KAR
NKL
NRG
PRC
PRC
SMT
デフォルトでは、キーワード UNION は重複行を除外します。問合せ 3- 38 が示して
いるように、オプションのキーワード ALL を追加して、重複値を保存します。
問合せ 3- 38
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 stockitem
3-42
Informix Guide to SQL: Tutorial
和の集合演算
問合せ 3- 38 は、UNION ALL キーワードを使用して 2 つの SELECT 文を結合し、
INTO TEMP 節を最後の SELECT 文の後に追加して、結果を一時表に入れます。こ
れは問合せ 3- 37 と同じ行を返しますが、重複値も含みます。
問合せ結果 3- 38
stock_num manu_code
9
5
9
5
9
5
5
5
302
302
301
201
5
5
103
106
5
5
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
HRO
KAR
KAR
NKL
NRG
NRG
PRC
PRC
SMT
SMT
複合問合せの場合は、選択対象の並び内の対応する列同士のデータ型が同じでなけ
ればなりませんが、列に同じ識別子を使用する必要はありません。
問合せ 3- 39 は、表 customer から列 state を選択して、表 state から対応する列 code
を選択します。
問合せ 3- 39
SELECT DISTINCT state
FROM customer
WHERE customer_num BETWEEN 120 AND 125
UNION
SELECT DISTINCT code
FROM state
WHERE sname MATCHES '*a'
高度な SELECT 文の作成
3-43
和の集合演算
問合せ結果 3- 39 は、顧客番号 120 ∼ 125 の州コードの略語と、sname が a で終
わっている州の州コードの略語を返します。
問合せ結果 3- 39
state
AK
AL
AZ
CA
DE
FL
GA
IA
IN
LA
MA
MN
MT
NC
ND
NE
NJ
NV
OK
PA
SC
SD
VA
WV
複合問合せでは、最初の SELECT 文に含まれる列名または表示ラベルが、問合せ結
果に使用されます。したがって、問合せ 3- 39 では、2 番目の SELECT 文からの列
名 code の代わりに、最初の SELECT 文からの列名 state が使用されます。
3-44
Informix Guide to SQL: Tutorial
和の集合演算
問合せ 3- 40 は、3 つの表を結合します。結合できる表の最大数は、実際に使用する
アプリケーションやメモリ制限によって異なります。
問合せ 3- 40
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
問合せ 3- 40 は、表 stock での unit_price が 600 ドルを超える品目と、表 catalog での
catalog_num が 10025 である品目、または表 items での quantity が 10 である品目を
取り出します。さらに、この問合せでは manu_code に基づいてデータがソートされ
ます。問合せ結果 3- 40 は返り値を示しています。
問合せ結果 3- 40
stock_num manu_code
5
9
8
4
1
203
5
106
113
ANZ
ANZ
ANZ
HSK
HSK
NKL
NRG
PRC
SHM
高度な SELECT 文の作成
3-45
和の集合演算
『Informix Guide to SQL:
SELECT 文と UNION 演算子の完全な構文については、
Syntax』を参照してください。INFORMIX-ESQL/C 製品に固有の情報および INTO
節と複合問合せに関する制限については、
『INFORMIX-ESQL/C Programmer’s
Manual』を参照してください。
問合せ 3- 41 では、複合問合せ文を使用して、データを一時表に格納し、単純問合
せを追加して一時表のデータをソートしてから表示します。複合問合せ文と単純問
合せ文はセミコロン (;) で分離しなければなりません。
この複合問合せ文では、選択対象の並びにリテラルを使用して、結合された問合せ
結果にタグを付けています。タグを付けるのは、問合せ結果がどの問合せ文からの
ものであるかを後で区別できるようするためです。タグにはソートキーというラベ
ルが与えられています。単純問合せ文では、そのタグをソートキーとして使用して
抽出した行をソートします。
問合せ 3- 41
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
問合せ結果 3- 41 が示しているように、問合せ 3- 41 は、最も頻繁に電話を掛けたカ
リフォルニアの顧客が最初に列挙されるリストを作成します。
3-46
Informix Guide to SQL: Tutorial
和の集合演算
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
1
Beatty
Lana
Sportstown
Menlo Park
CA
415-356-9982
sortkey
lname
fname
company
city
state
phone
1
Currie
Philip
Phil’ s Sports
Palo Alto
CA
415-328-4543
sortkey
lname
fname
company
city
state
phone
.
.
.
sortkey
lname
fname
company
city
state
phone
1
Grant
Alfred
Gold Medal Sports
Menlo Park
CA
415-356-1123
sortkey
lname
fname
company
city
state
phone
2
Shorter
Bob
The Triathletes Club
Cherry Hill
NJ
609-663-6079
sortkey
lname
fname
company
city
state
phone
2
Wallack
Jason
City Sports
Wilmington
DE
302-366-7511
問合せ結果 3- 41
2
Satifer
Kim
Big Blue Bike Shop
Blue Island
NY
312-944-5691
高度な SELECT 文の作成
3-47
積の集合演算
積の集合演算
二つの行のセットに対して積の集合演算を行うと、元の表のどちらにも存在する行
からなる表が生成されます。二つのセットの積を示す副問合せ文には、キーワード
EXISTS または IN を使用します。図 3-2 は、積の集合演算を示しています。
図 3-2
積の集合演算
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 に
ない
問合せ 3- 42 は、表 stock と表 items の積を示す入れ子になった SELECT 文の例で
す。
問合せ 3- 42
SELECT stock_num, manu_code, unit_price
FROM stock
WHERE stock_num IN
(SELECT stock_num FROM items)
ORDER BY stock_num
問合せ結果 3- 42 には、二つのセットのすべての要素が含まれ、次の 57 行を返しま
す。
3-48
Informix Guide to SQL: Tutorial
積の集合演算
stock_num
1
1
1
2
3
3
4
4
5
5
5
6
6
7
8
9
101
101
103
104
105
105
109
109
110
110
110
110
110
111
114
201
201
201
202
202
204
205
205
205
301
301
301
301
301
301
302
302
303
303
304
304
306
306
307
309
309
manu_code
HRO
HSK
SMT
HRO
HSK
SHM
HRO
HSK
ANZ
NRG
SMT
ANZ
SMT
HRO
ANZ
ANZ
PRC
SHM
PRC
PRC
PRC
SHM
PRC
SHM
ANZ
HRO
HSK
PRC
SHM
SHM
PRC
ANZ
KAR
NKL
KAR
NKL
KAR
ANZ
HRO
NKL
ANZ
HRO
KAR
NKL
PRC
SHM
HRO
KAR
KAR
PRC
ANZ
HRO
PRC
SHM
PRC
HRO
SHM
unit_price
問合せ結果 3- 42
$250.00z
$800.00
$450.00
$126.00
$240.00
$280.00
$480.00
$960.00
$19.80
$28.00
$25.00
$48.00
$36.00
$600.00
$840.00
$20.00
$88.00
$68.00
$20.00
$58.00
$53.00
$80.00
$30.00
$200.00
$244.00
$260.00
$308.00
$236.00
$228.00
$499.99
$120.00
$75.00
$90.00
$37.50
$230.00
$174.00
$45.00
$312.00
$312.00
$312.00
$95.00
$42.50
$87.00
$97.00
$75.00
$102.00
$4.50
$5.00
$36.00
$48.00
$170.00
$280.00
$160.00
$190.00
$250.00
$40.00
$40.00
高度な SELECT 文の作成
3-49
差の集合演算
差の集合演算
二つの行のセット間の差を処理すると、最初のセットには存在するが 2 番目のセッ
トには存在しない行からなる表が生成されます。二つのセット間の差を示す副問合
せ文には、キーワード NOT EXISTS または NOT IN を使用します。図 3-3 は、差の
集合演算を示しています。
図 3-3
差の集合演算
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
表 stock に存
在している
表 items に
存在してい
る
表 items に
ない
表 stock
該当
表 items
表 stock に
ない
3-50
stock_num
Informix Guide to SQL: Tutorial
差の集合演算
問合せ 3- 43 は、表 stock と表 items 間の差を示す入れ子になった SELECT 文の例で
す。
問合せ 3- 43
SELECT stock_num, manu_code, unit_price
FROM stock
WHERE stock_num NOT IN
(SELECT stock_num FROM items)
ORDER BY stock_num
問合せ結果 3- 43 には、17 行を返す最初のセットのみのすべての要素が含まれて
います。
stock_num manu_code unit_price
102
102
106
107
108
112
113
203
305
308
310
310
311
312
312
313
313
PRC
SHM
PRC
PRC
SHM
SHM
SHM
NKL
HRO
PRC
ANZ
SHM
SHM
HRO
SHM
ANZ
SHM
問合せ結果 3- 43
$480.00
$220.00
$23.00
$70.00
$45.00
$549.00
$685.90
$670.00
$48.00
$280.00
$84.00
$80.00
$48.00
$72.00
$96.00
$60.00
$72.00
高度な SELECT 文の作成
3-51
まとめ
まとめ
この章では、第 2 章「簡単な SELECT 文の作成」で紹介した概念を基に説明が進め
られています。リレーショナルデータベースに対する問合せを実行するために使用
するより複雑な種類の SELECT 文の構文および結果のサンプルも記載されていま
す。以下に、この章で説明した内容を示します。
3-52
■
GROUP BY 節と HAVING 節についての説明。これらの節を集計関数と一緒
に使用して行グループを返し、これらのグループに条件を適用することが
できます。
■
rowidを使用して内部レコード番号を表およびシステムカタログ表から抽出
する方法についての説明と、内部表識別子 (tabid) についての説明。
■
セルフ結合で表をそれ自体に結合し、同じ列内の他の値と比較して、重複
行を識別する方法についての説明。
■
キーワード OUTER の紹介と、4 種類の外部結合の例をあげ、外部結合が複
数の表を非対称に扱う方法について説明。
■
SELECT文を別のSELECT文のWHERE節に入れ子にして相関副問合せ文と
非相関副問合せ文を作成する方法と、副問合せ文での集計関数の使用方法
の説明。
■
副問合せ文を作成するときのキーワード ALL、ANY、EXISTS、IN、SOME
の使用方法と、キーワード NOT または関係演算子を追加した場合の効果
についての説明。
■
和、積および差などの集合演算についての説明。
■
キーワード UNIONと UNION ALL を使用して、複数のSELECT 文からなる複
合問合せを作成する方法についての説明。 Informix Guide to SQL: Tutorial
第4章
データの更新
データを更新する文 . .
. .
. . .
. . .
. . .
. . .
. .
4-3
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4-4
4-4
4-5
4-5
4-6
行の挿入 . . . . . . . . . . . . .
単一行の挿入 . . . . . . . . . .
VALUES 節に指定できる値 . . . . .
特定の列名と値だけを指定する . . . .
複数の行の挿入と式の使用方法 . . . . .
INSERT 文に SELECT 文を使用する場合の制約.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4-7
4-7
4-8
4-9
4-10
4-11
行の更新 . . . . . . .
更新対象の行の選択 . .
一様値を使用する更新 . .
更新の制限 . . . . .
選択値を使用する更新 . .
CASE 式を使用する列の更新
結合を使用する列の更新 .
行の削除 . . . . . . . . . . .
表のすべての行の削除 . . . . . .
削除対象の行数がわかっている場合の削除
削除対象の行数が不明の場合の削除 . .
複雑な削除条件 . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4-12
4-13
4-14
4-15
4-15
4-16
4-17
データベースでのアクセス権 . . .
データベースレベルのアクセス権
表レベルのアクセス権 . . . .
表アクセス権の表示 . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4-17
4-18
4-18
4-19
データの整合性 . . . . . . . . . . . .
実体整合性 . . . . . . . . . . . .
意味整合性 . . . . . . . . . . . .
参照整合性 . . . . . . . . . . . .
オプション ON DELETE CASCADE の使用方法
カスケード削除の例 . . . . . . . .
カスケード削除に対する制約. . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4-20
4-21
4-21
4-22
4-24
4-25
4-26
オブジェクトモードと違反の検出 . . . .
オブジェクトモードの制約. . . . .
オブジェクトモードの一意性インデックス
オブジェクトモードのトリガ . . . .
SQL 文と例 . . . . . . . . .
4-2
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4-26
4-26
4-27
4-28
4-28
中断された更新 . . . . . . . . . . . . . . . . . .
トランザクション . . . . . . . . . . . . . . . .
トランザクションログ機能 . . . . . . . . . . . . . .
Informix Dynamic Server with AD and XP Options のトランザクション
ログ機能 . . . . . . . . . . . . . . .
ログ機能とカスケード削除. . . . . . . . . . . . .
トランザクションの指定 . . . . . . . . . . . . . .
.
.
.
4-28
4-30
4-30
.
.
.
4-31
4-31
4-32
Informix データベースサーバを使用したバックアップとログ .
. . .
. .
4-33
並列度とロック
. . .
. .
4-34
データレプリケーション . . . . . . . . . . . . . . .
Informix データベースサーバによるデータレプリケーション . . .
. .
. .
4-35
4-36
まとめ . . .
. .
4-37
. .
. .
. . .
. . .
Informix Guide to SQL: Tutorial
. . .
. . .
. . .
. . .
. . .
. . .
. . .
データの更新は、データの問合せとは基本的に異なるものです。データの問合せで
は、表の内容を調査するだけですが、データの更新では、表の内容を変更します。
問合せ中にシステムのハードウェアやソフトウェアに障害が発生した場合を考えて
みます。この場合、アプリケーションには非常に大きい影響がありますが、データ
ベース自体は被害を受けません。ただし、更新を行っている最中にシステムに障害
が発生すると、データベースの状態は不確かなものとなります。不確かな状態にあ
るデータベースが、広範囲に影響を与えることは明らかです。データベースの行を
削除、挿入、または更新する前に、次の点を確認してください。
■
データベースや表に対するユーザアクセス権の設定は適切かどうか。つま
り、特定のユーザに対してデータベースや表レベルのアクセス権が制限さ
れているかどうか。
■
更新されたデータは、データベースの既存の整合性を維持しているかどう
か。
■
データベースを構築しているシステムは、システムやハードウェアの障害
の原因となり得る外部のイベントから十分保護されているかどうか。
上記のそれぞれの質問に「はい」と答えられなくても、心配の必要はありません。
データベースサーバの機能を上手に利用すれば、これらの問題のすべてを解決する
ことができます。この章では、データを更新する文を紹介した後、その解決策につ
いて解説します。
『Informix Guide to Database Design and Implementation』では、これ
らのトピックについてさらに詳しく扱います。
データを更新する文
データを更新する文は、次のとおりです。
✮
DELETE 文
✮
INSERT 文
✮
UPDATE 文
データの更新
4-3
行の削除
これらの文は SELECT 文に比べると比較的簡単ですが、データベースの内容を変更
する文のため、注意して使用する必要があります。
行の削除
DELETE 文は、任意の行や行の組合せを表から削除します。トランザクションがコ
ミットされた後は、削除した行は復旧できません。( トランザクションについては
4-28 ページの「中断された更新」に説明されています。ここでは、トランザクショ
ンは SQL 文と同じものと考えてかまいません。)
行を削除する場合は、その削除する行に値が依存している他の表の行も細心の注意
を払って削除しなければなりません。データベースが参照制約を強制する場合は、
CREATE TABLE 文または ALTER TABLE 文の ON DELETE CASCADE オプション
を使用して、ある表から別の表への関係によって、カスケード削除することができ
ます。参照制約と ON DELETE CASCADE オプションについての詳細は、4-22 ペー
ジの「参照整合性」を参照してください。
表のすべての行の削除
DELETE 文を使用するときは通常、表のどの行を削除するかを WHERE 節で指定し
ます。DELETE 文に表だけを指定して、WHERE 節を使用しない場合、その表から
すべての行が削除されます。次の文は、絶対に実行しないでください。
DELETE FROM customer
この文には WHERE 節がないため、表 customer のすべての行が無条件に削除されて
しまいます。メニューオプション DB-Access またはリレーショナルオブジェクトマ
ネージャを使用して無条件削除を行う場合、プログラムからの警告が表示され、確
認を要求してきます。しかし、プログラム中で無条件削除が指定されている場合
は、この警告が表示されずに削除が実行されてしまいます。
4-4
Informix Guide to SQL: Tutorial
削除対象の行数がわかっている場合の削除
削除対象の行数がわかっている場合の削除
DELETE 文の WHERE 節のフォームは、SELECT 文の WHERE 節と同じです。
WHERE 節を使用すると、どの行を削除するかを正確に指定できます。次の例が示
しているように、特定の顧客番号を持つ顧客を削除できます。
DELETE FROM customer WHERE customer_num = 175
この例では、列 customer_num が一意性制約を持っているため、複数の行が削除さ
れないことを保証できます。
削除対象の行数が不明の場合の削除
また、次の例が示しているように、インデックスの付いていない列をベースにして
いる行を選択することもできます。
DELETE FROM customer WHERE company = 'Druid Cyclery'
検査される列は一意性制約を持っていないので、この文は複数の行を削除する場合
があります。(Druid Cyclery( ドルイド自転車店 ) は名前は同じで、顧客番号が異な
る二つの店舗を持っているかもしれません。)
DELETE 文が影響を与える行数を知るには、Druid Cyclery の表 customer から修飾行
のカウント数を選択します。
SELECT COUNT(*) FROM customer WHERE company = 'Druid Cyclery'
また、行を選択して表示し、削除したい行であることを確認することもできます。
ただし、SELECT 文を使用した検査は、複数のユーザが並行してデータベースを使
用している場合は、必ずしも正確ではありません。SELECT 文を実行してから次に
DELETE 文を実行するまでの間に、行を削除しようとしている表に他のユーザが操
作を加えた可能性があるからです。この例の場合、DELETE 文を実行する前に他の
ユーザが次の操作をするかもしれません。
■
Druid Cyclery という名前で顧客番号が異なる別の顧客の行を、表に挿入す
る。
■
行を挿入する前に一つまたは複数の Druid Cyclery の行を削除する。
■
Druid Cyclery の行を別の新しい会社名に更新したり、あるいは他の顧客の
行の会社名を Druid Cyclery に更新したりする。
データの更新
4-5
複雑な削除条件
この短い時間に他のユーザがこれらの操作を行う可能性は非常に低いものですが、
その可能性がまったくないわけではありません。これと同じ問題は、UPDATE 文に
ついても発生します。この問題に対処する方法は、4-34 ページの「並列度とロッ
ク」に説明されている他、第 7 章「マルチユーザ環境のためのプログラミング」に
もさらに詳しく説明されています。
考えられるもう一つの問題は、この文が終了する前にハードウェア障害またはソフ
トウェア障害が発生することです。このような障害が発生すると、データベースが
まったく行を削除しなかったか、いくつかの行を削除したか、または指定されたす
べての行を削除したかがわからなくなります。データベースの状態がわからないと
いうのは望ましいことではありません。このような状態を防止するには、4-28 ペー
ジの「中断された更新」に説明されているように、トランザクションログ機能を使
用します。
複雑な削除条件
DELETE 文の WHERE 節も、SELECT 文の WHERE 節と同様に複雑になることがあ
ります。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 になります。次に、カウントが 0 の行が表 stock から削除用に選
択されます。
複雑な条件を持つ DELETE 文を記述する一つの方法として、削除対象の行を正確に
返す SELECT 文を最初に記述する方法があります。これは SELECT * と記述してく
ださい。希望の行が返されたら、SELECT * を DELETE に変更して、もう一度実行
してください。
4-6
Informix Guide to SQL: Tutorial
行の挿入
DELETE 文の WHERE 節には、削除対象の表自体を検査する副問合せ文は使用でき
ません。たとえば、表 stock の行を削除する場合、この表から行を選択する副問合せ
文を DELETE 文の WHERE 節に指定することはできません。
このルールの重要な点は FROM 節にあります。DELETE 文の FROM 節で指定した
表を、DELETE 文の副問合せ文の FROM 節には指定できません。
行の挿入
INSERT 文は、一つまたは複数の新しい行を表に追加します。この文には、二つの
基本的な機能があります。列の値を指定して単一の新しい行を作成することができ
ます。また、他の表から選択したデータを使用して複数の新しい行を作成すること
もできます。
単一行の挿入
もっとも簡単なフォームの INSERT 文は、VALUES 節に列の値の並びを 1 行記述
し、それを表に追加するものです。次の文に、表 stock に行を追加する方法を示しま
す。
INSERT INTO stock
VALUES (115, 'PRC', 'tire pump', 108, 'box', '6/box')
表 stock の各列を以下に示します。
■
stock_num ( 商品のタイプを示す取扱品目番号 )
■
manu_code ( 表 manufact への外部キーであるメーカーコード )
■
description ( 商品の内容を示す品目内容 )
■
unit_price ( 商品の単価である単価 )
■
unit ( 商品の販売単位である最小販売単位 )
■
unit_descr ( 販売単位表記である単位内容 )
上記の例の VALUES 節でリストされる値は、表 stock の列と一対一の対応関係を
持っています。VALUES 節は、表の各列の名前とデータ型、および順番がわかって
いないと正確に記述することはできません。
データの更新
4-7
単一行の挿入
VALUES 節に指定できる値
VALUES 節は定数値のみを受け入れ、式は受け入れません。指定できる値は以下の
とおりです。
■
リテラル番号
■
日時型の値
■
時間隔型の値
■
引用符付き文字列または文字
■
NULL を表すキーワード NULL
■
現在の日付を表わすキーワード TODAY
■
現在の日時を表すキーワード CURRENT
■
ユーザ名を表すキーワード USER
■
データベースサーバがインストールされているコンピュータの名前を表す
キーワード DBSERVERNAME または SITENAME
表には、NULL が許可されない列が含まれている場合があります。そのような列に
NULL を挿入しようとすると、文は拒否されます。あるいは、表の列が重複値を許
可しない場合があります。このような列の中にすでにある値と重複する値を指定す
ると、その文は拒否されます。列によっては、許可されている指定可能な列の値さ
えも制限されます。これらの列の制限は、データ整合性制約を使用して指定されま
す。データの整合性制約についての詳細は、4-20 ページの「データの整合性」を参
照してください。
シリアル (SERIAL) 型の列は、一つの表に一つのみ作成することができます。デー
タベースサーバが、シリアル型の列の値を生成します。値を挿入した時点で生成さ
せるには、シリアル型の列に値 0 を指定してください。データベースサーバは、次
の実際の値を続けて生成します。シリアル型の列は、NULL を許可しません。
シリアル型の列に対しては非ゼロ値を指定でき ( その列の既存の値と同じでない限
り )、データベースサーバはその値を使用します。しかし、その非ゼロ値は、データ
ベースサーバが生成する値の新しい開始点を設定することがあります。データベー
スサーバが次に生成する値は、その列の最大値よりも 1 だけ大きい値になります。
金額 (MONEY) 型の値を含む列には、通貨記号を指定しないでください。金額を示
す数値のみを指定してください。
4-8
Informix Guide to SQL: Tutorial
単一行の挿入
データベースサーバは、数値型と文字型の変換を実行できます。数値型の列の値と
して、数値の文字列 ('-0075.6' など ) を指定することができます。データベース
サーバは、この数値文字列を数値に変換することができます。この文字列が数値を
表わしていない場合に限り、エラーが発生します。
文字 (CHAR) 型列の値として、数値または日付を指定できます。データベースサー
バは、その値を文字列に変換します。たとえば、文字 (CHAR) 型列の値として
TODAY を指定すると、現在の日付を表す文字列が使用されます ( 環境変数
DBDATE は、使用されるフォーマットを指定します )。
特定の列名と値だけを指定する
INSERT 文には、表のすべての列の値を指定する必要はありません。代わりに、表
名の後に列名をリストして、指定したそれらの列のみに値を指定することができま
す。次の例に、表 stock に新しい行を挿入する例を示します。
INSERT INTO stock (stock_num, description, unit_price, manu_code)
VALUES (115, 'tyre pump', 114, 'SHM')
在庫番号、説明、単価およびメーカーコードのデータのみが提供されます。データ
ベースサーバは次の規則に従って、残りの列に値を提供します。
■
リストされていないシリアル型の列の場合は、シリアル番号を生成しま
す。
■
列に固有なデフォルト値が存在する場合は、その値を生成します。
■
NULL を許可する任意の列の NULL を生成しますが、デフォルト値として
NULL を指定する任意の列のデフォルト値の指定は行いません。
つまり、固有のデフォルト値を持たない列や、NULL を許可しない列に対
しては、必ず値を指定しなければなりません。
それらの列は、値が同じ順序でリストされる限りは、どんな順序でもリストできま
す。NULL の指示方法あるいは列のデフォルト値の指示方法についての詳細は、
『Informix Guide to Database Design and Implementation』を参照してください。
データの更新
4-9
複数の行の挿入と式の使用方法
前例の INSERT 文が実行された後、次に示す新しい行が表 stock に挿入されます。
stock_num manu_code description unit_price unit unit_descr
115
SHM
tyre pump 114
unit と unit_descr はどちらも空白で、この二つの列に NULL があることを示します。
列 unit は NULL を許可するので、$114 で購入されたタイヤポンプの数はわかりま
せん。もちろん、box のデフォルト値がこの列に対して指定された場合は、box は
販売単位になります。いずれにしても、表の特定の列に値を挿入する場合は、その
行にどんなデータが必要かに注意を払ってください。
複数の行の挿入と式の使用方法
INSERT 文のもう一つのフォームは、VALUES 節を SELECT 文で置き換えます。こ
のフォームの特徴は、次のようなデータを挿入できることです。
■
文が一つだけある複数の行 (SELECT 文が一行を返すたびに一行が挿入され
る)
■
計算値 (VALUE節は定数だけを許可)選択対象の並びは式を含むことができ
るため。
たとえば、決済は済んだが出荷が済んでいない注文について、出荷要求の電話連絡
を行う必要が生じたと仮定します。次の例の 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 の指定された列に挿入されます。シリアル型の列 order_num
から注文番号の値が挿入される列は文字型の列問合せ内容です。整数値を文字型の
列に挿入することは可能です。データベースサーバが自動的にシリアル値を 10 進
数の文字列に変換します。
4-10
Informix Guide to SQL: Tutorial
INSERT 文に SELECT 文を使用する場合の制約
INSERT 文に SELECT 文を使用する場合の制約
INSERT 文で使用する SELECT 文には、以下に示す制約があります。
AD/XP
■
INTO 節を含むことはできません。
■
INTO TEMP 節を含むことはできません。
■
ORDER BY 節を含むことはできません。
■
行を挿入する表を参照することはできません。
高度な意思決定支援オプションと拡張型並列オプションを使用した Informix
Dynamic Server では、SELECT 文は ORDER BY 節を INSERT SELECT 文に含めるこ
とができます。 ♦
INTO、INTO TEMP、および ORDER BY 節の制約はわずかなものです。このコンテ
キストでは、INTO 節は有効ではありません。( 詳細は、第 5 章「SQL を使用した
プログラミング」を参照。
)INTO TEMP 節の制約を回避するには、まず、一時表に
挿入したいデータを選択し、そのデータを INSERT 文を使用して一時表から挿入し
ます。同様に、ORDER BY 節を使用できないことも大きな問題ではありません。新
しい行を表内で物理的に順序付ける必要がある場合は、まずこれらの行を選択して
一時表に入れて順序付け、次に一時表から挿入することができます。また、すべて
の挿入が完了した後でクラスタ化インデックスを使用し、物理的な順序を表に適用
することもできます。
最後の制約は、INSERT 文の INTO 節と SELECT 文の FROM 節の両方で同じ表を指
定できないため、これまでの制約よりも重要です。INSERT 文の INTO 節と
SELECT 文の FROM 節の両方で同じ表を指定すると、データベースサーバは、挿入
された各行が再選択されて再挿入される永久ループに入ります。
しかし、データを挿入しなければならない表そのものから選択したい場合もありま
す。たとえば、Nikolus 社が Anza 社と同じ製品を半額で提供していることがわかっ
た場合を考えます。この二つの会社の相違を反映するために、表 stock に行を追加
したいと考えるでしょう。表 stock の行から Anza 社のすべてのデータを選択し、そ
れを Nikolus 社のメーカーコードで再び挿入するのが最良の方法です。しかし、挿
入対象の表から選択することはできません。
データの更新
4-11
行の更新
この制限を回避するには、一時表に挿入したいデータを選択します。そして、次の
例が示しているように、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 行でも無効なデータが含まれていると、データベー
スサーバがエラーをレポートします。この種のエラーが発生すると、この文は早期
に終了します。たとえエラーが発生しない場合でも、この文の実行中にハードウェ
ア障害またはソフトウェア障害 ( たとえば、ディスクがいっぱいになる ) が発生す
る危険性が、非常に低いとはいえ存在します。
いずれの場合でも、新しい行が何行挿入されたかは簡単にはわかりません。文全体
を繰り返し実行すると、行が重複して作成されてしまうことがあるかもしれませ
ん。データベースの状態がわからないため、対処方法も見つけることができませ
ん。解決策は、4-28 ページの「中断された更新」に説明されているように、トラン
ザクションを使用することです。
行の更新
表に含まれる既存の行の列の内容を変更するには、UPDATE 文を使用します。この
文には、基本的に異なる二つのフォームがあります。一つのフォームでは、特定の
値を名前によって列に割り当てることができます。もう一つのフォームでは、
SELECT 文によって返される値の並びを列の並びに割り当てることができます。い
ずれのフォームでも、行を更新している場合にいくつかの列にデータ整合性制約が
設定されていれば、変更するデータはこれらの制約を満たすものでなければなりま
せん。データ整合性制約についての詳細は、4-20 ページの「データの整合性」を参
照してください。
4-12
Informix Guide to SQL: Tutorial
更新対象の行の選択
更新対象の行の選択
いずれのフォームの 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 の各行をこの注文番号と突き合わせ、その行の注文番号が
一致すれば更新を実行します。
データの更新
4-13
一様値を使用する更新
一様値を使用する更新
キーワード SET の後の代入式は、列に新しい値を指定します。その値は、更新する
どの行にも一様に適用されます。前の項の例では新しい値は定数でしたが、その列
の値自体をベースにした式も含め、どんな式でも割り当てることができます。メー
カーコード HRO がすべての価格を 5 パーセント上げたため、この値上げを反映す
るために、表 stock を更新しなければならないと仮定します。次のような文を使用
してください。
UPDATE stock
SET unit_price = unit_price * 1.05
WHERE manu_code = 'HRO'
式の一部に副問合せ文を使用することもできます。式の一部として副問合せ文を使
用する場合、その文は値を一つだけ戻すものでなければなりません。一つというの
は、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 内の
もっとも高い価格です。これは相関副問合せです。この文の WHERE 節には表
items の列 stock_num の値が指定されているため、この SELECT 文は表 items 内の更
新対象の各行ごとに実行されなければならないからです。
二つ目の SELECT 文は、未出荷の注文の注文番号を取り出します。この SELECT 文
は非相関副問合せ文のため、1 回実行されるのみです。
4-14
Informix Guide to SQL: Tutorial
更新の制限
更新の制限
データを更新する場合の副問合せ文の使用については、いくつかの制限がありま
す。特に重要なのは、更新されている表に対しては問合せができないことです。列
unit_price を 5% 増加させた例のように、列の現在の値を式の中で参照することはで
きます。表 stock を更新した例のように、副問合せ文の WHERE 節で列の値を参照
することもできます。この場合、表 items が更新され、items.stock_num が結合条件
式で使用されました。
AD/XP
Dynamic Server with AD and XP Options では、UPDATE 文の SET 節で副問合せを使用す
ることはできません。 ♦
適切に設計されたデータベースでは、同じ表に対する更新と問合せが同時に行われ
ることはほとんどありません。( データベース設計の詳細は、
『Informix Guide to
Database Design and Implementation』を参照してください )。しかし、データベース
を初めて設計するときには、データベースデザインを慎重に熟考する前に、更新と
問合せを同時に実行したいと考えるでしょう。一意でなければならない列の中に重
複値がある行が表内にいくつか誤って含まれているような場合に、典型的な問題が
発生します。この場合には、重複行を削除するか、重複行のみを更新する必要が生
じます。いずれの場合でも、重複行をテストするには、UPDATE 文または DELETE
文では許可されていない副問合せ文が変更したい同じ表内に必要になります。第 6
章「SQL プログラムによるデータの更新」で、このような更新を実行するための
UPDATE カーソルの使用方法について説明します。
選択値を使用する更新
二つ目のフォームの UPDATE 文は、一連の代入を一つの代入にまとめて置き換え
たものです。ここでは、列の並び順が値の並び順と等しくなるように設定してくだ
さい。次の例が示しているように、値が簡単な定数の場合には、このフォームはそ
の部分が再配置されている上記の例のフォームと大差がありません。
UPDATE customer
SET (fname, lname) = ('Barnaby', 'Dorfler')
WHERE customer_num = 103
文を前記のように記述しても利点はまったくありません。実際に、どの列にどの値
が代入されるかが明らかでないために、読みにくくなります。
データの更新
4-15
CASE 式を使用する列の更新
ただし、代入される値が一つの SELECT 文から得られるものであれば、このフォー
ムを使用する意味があります。次の例では、数人の顧客の住所を変更しています。
住所の変更があるたびに表 customer を更新せずに、新しい住所を newaddr という名
前の一時表にいったん格納してあると仮定します。この一時表は、表 customer の
customer_num と住所に関連するフィールドから構成されています。この一時表に格
納された新しい住所を、ある時点で一括して表 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)
複数の列の値が、単一の select 文によって作成されます。この例を、更新対象の各
列ごとに一つの代入文を使用するもう一つのフォームで書き直すには、更新する
個々の列ごとに一つずつ、合計で 5 つの SELECT 文を記述しなければなりません。
そのような文の記述は難しいだけではなく、実行時間も長くなります。
ヒント : SQL API プログラムでは、レコード変数やホスト変数を使用して値を更新
できます。詳細は第 5 章「SQL を使用したプログラミング」を参照してください。
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
4-16
Informix Guide to SQL: Tutorial
結合を使用する列の更新
CASE 式内に少なくとも 1 つの WHEN 節を含めなければなりません。後続する
WHEN 節と ELSE 節はオプションです。どの WHEN 条件も真と評価されない場合、
結果の値は NULL です。
AD/XP
結合を使用する列の更新
Dynamic Server with AD and XP Options により、表の結合を使用して、どの列を更新
するかを決定することができます。更新する列と行の値を指定するために、SET 節
の FROM 節に一覧表示されたどの表からも列を使用できます。
FROM 節を使用する場合、更新が実行される表の名前を含めなければなりません。
その他の場合は、エラーとなります。次の例は、FROM 節で UPDATE 文を使用で
きる方法を示しています。
UPDATE t SET a = t2.a FROM t, t2 WHERE t.b = t2.b
前の例のように文は、FROM 節が省略される場合と同じ処理を実行します。
UPDATE 文の FROM 節では 2 つ以上の表を指定することができます。しかし、表
を 1 つだけ指定する場合、表はターゲット表になります。
データベースでのアクセス権
次のデータベース アクセス権を使用して、データベースへのアクセスを制御できま
す。
■
データベース レベルのアクセス権
■
表レベルのアクセス権
■
列レベルのアクセス権
■
プロシジャ レベルのアクセス権
この節では、データベース レベルのアクセス権と表レベルのアクセス権について簡
潔に説明します。データベース アクセス権に関する詳細については、
『Informix
Guide to Database Design and Implementation』を参照してください。アクセス権の一
覧と GRANT 文および REVOKE 文の説明については、
『Informix Guide to SQL:
Syntax』を参照してください。
データの更新
4-17
データベースレベルのアクセス権
データベースレベルのアクセス権
データベースを作成する場合、作成者がデータベースの所有者またはデータベース
管理者 (DBA) として、他者にデータベースレベルアクセス権を付与するまでは、
データベースにアクセスできるのは作成者のみです。次に、データベースレベルア
クセス権を示します。
アクセス権
目的
接続
データベースのオープン、問合せの発行、および一時表の
インデックスの作成と配置を行うことができます。
リソース
永久表を作成することができます。
DBA( データベース
データベース管理者として、いくつかの追加機能を実行す
ることができます。
管理者 )
表レベルのアクセス権
ANSI 標準に準拠しないデータベースに表を作成すると、表の所有者が特定のユー
ザからの表レベルのアクセス権を取り消さない限り、すべてのユーザがその表への
アクセス権を持つことになります。次の表は、ユーザが表へアクセスする場合の 4
つのアクセス権を示しています。
アクセス権
目的
選択
表ごとに与えられる権限で、表から行を選択することがで
きます。このアクセス権は、表の特定の列のみに制限する
こともできます。
削除
行を削除することができます。
挿入
行を挿入することができます。
更新
既存の行を更新する、つまり行の内容を変更することがで
きます。
多くの場合、データベースと表を作成したユーザは、接続アクセス権および選択ア
クセス権をパブリックに与えて、すべてのユーザがそれらの権限を持てるようにし
ます。表に対して問合せができるということは、そのデータベースと表について少
なくとも接続アクセス権と選択アクセス権を持っていることになります。
4-18
Informix Guide to SQL: Tutorial
表アクセス権の表示
データを更新するには、その他の表レベルアクセス権が必要です。多くの場合、表
の所有者だけがこれらの権限を持っているか、または特定のユーザだけに付与され
ています。その結果、自由に問合せができる一部の表を更新できない場合がありま
す。
これらのアクセス権は表ごとに設定できるため、たとえばある表については挿入ア
クセス権だけを持ち、他の表については更新アクセス権のみを持っているというこ
ともあります。更新アクセス権は、表の特定の列だけに制限することもできます。
これらの表レベルアクセス権とその他の表レベルアクセス権についての詳細は、
『Informix Guide to Database Design and Implementation』を参照してください。
表アクセス権の表示
表の所有者、つまり作成者は、その表についてのすべてのアクセス権を持っていま
す。表の所有者でない場合は、システムカタログへの問合せによって、その表に対
して持っているアクセス権を調べることができます。システムカタログは、データ
ベース構造を記述するシステム表で構成されています。個々の表に対して付与され
たアクセス権は、システム表 systabauth に記録されています。これらのアクセス権
を表示するには、この表の一意な識別子番号を知っていなければなりません。この
番号は、システム表 systables に指定されています。表 order に対して付与されてい
るアクセス権を表示するには、次の SELECT 文を入力します。
SELECT * FROM systabauth
WHERE tabid = (SELECT tabid FROM systables
WHERE tabname = 'orders')
この問合せの出力は、次のようになります。
図 4-1
grantor
grantee
tabid
tfecit
tfecit
tfecit
mutator
101
procrustes 101
public
101
tabauth
su-i-x-s--idx-s--i-x--
grantor の欄に表示されるユーザは、アクセス権を付与する権限授与者です。通常、
権限授与者はその表の所有者ですが、権限授与者によって権限を与えられた他の
ユーザである可能性もあります。grantee の欄に表示されるユーザは、アクセス権を
付与された被権限授与者であり、grantee public とは、
「接続アクセス権を持つすべ
てのユーザ」です。ユーザ名がここに記載されていないユーザは、パブリックに与
えられたアクセス権以外は所有していません。
データの更新
4-19
データの整合性
tabauth の欄に表示される文字列は、付与されたアクセス権を示します。この欄の各
行に表示される文字は、アクセス権の名前の頭文字です。ただし、i は挿入、x はイ
ンデックスになります。この例では、パブリックには選択、挿入、およびインデッ
クスのアクセス権が与えられています。ユーザ mutator のみが更新アクセス権を
持っており、ユーザ procrustes だけが削除アクセス権を持っています。
ユーザが何らかの動作を起こす ( たとえば、DELELTE 文の実行など ) 場合、データ
ベースサーバは、その動作を実行する前に、この例のように問合せを行います。そ
のユーザがその表の所有者でない場合、またデータベースサーバがそのユーザ名に
対してもパブリックに対してもその表に対する必要なアクセス権を与えていない場
合は、その操作の実行は拒否されます。
データの整合性
INSERT 文、UPDATE 文、および DELETE 文は、既存のデータベースのデータを更
新します。既存のデータを更新するときは、常にデータの整合性への影響に注意し
てください。たとえば、存在しない製品への注文が表 orders に入力されていたり、
未出荷の注文がある顧客が表 customer から削除されていたり、表 orders で更新され
た注文番号が表 items では更新されていないというような可能性もあります。この
いずれの場合も、格納されているデータの整合性は失われています。
実際には、データ整合性は次の部分によって構成されています。
■
実体整合性
表の各行には、行を一意にする識別子が必要です。
■
意味整合性
列内のデータは、列が保持すべき情報を正しく反映するものでなければな
りません。
■
参照整合性
表と表の間の関係により強制される制約です。たとえば、存在しない行を
参照することはできません。
正しく設計されたデータベースでは、これらの原則が守られ、データを更新する際
にデータの整合性が失われないような構造になっています。
4-20
Informix Guide to SQL: Tutorial
実体整合性
実体整合性
実体とは、データベースに記録されるあらゆる人、場所、または物のことです。
個々の表は実体を表し、表の各行は実体の実現値を表します。たとえば、注文が実
体であれば、表 orders は注文の概念を表し、表の各行は特定の注文を表します。
表の各行を識別するには、表に主キーがなければなりません。主キーは各行を識別
するための一意な値です。主キーの存在に関する制約を実体整合性制約と呼びま
す。
たとえば、表 orders の主キーは order_num です。列 order_num はシステムによって
生成された、表内の各行を表す一意な番号を保持しています。表 orders のデータ行
にアクセスするには、次の SELECT 文を使用することができます。
SELECT * FROM orders WHERE order_num = 1001
注文番号の値が一意になっているため、WHERE 節でこの値を使用して簡単に特定
の行にアクセスすることができます。もし注文番号に重複が許されていると、この
表の他のすべての列に重複する値が存在していることになるため、一つの行に簡単
に、かつ確実にアクセスすることが非常に困難になります。
主キーや実体整合性についての詳細は、
『Informix Guide to Database Design and
Implementation』を参照してください。
意味整合性
意味整合性とは、ある行に入力されたデータが確実にその行の許容値を反映するよ
うにするためのものです。この値は、その列について、定義域内の値 ( つまり一連
の許容値 ) でなければなりません。たとえば、表 items の列 quantity では、数字だけ
が許されます。定義域外の値を列に入力できた場合には、そのデータの意味整合性
に違反することになります。
データの更新
4-21
参照整合性
意味整合性は、次の制約によって強制されます。
■
データ型
データ型は、列に格納することのできる値の型を定義します。たとえば、
小桁整数 (SMALLINT) 型の列には、-32,767 から 32,767 の値を入力するこ
とができます。
■
デフォルト値
デフォルト値は、明示的に値が指定されなかった場合に列に挿入される値
です。たとえば、表 cust_calls の列 user_id は、名前が入力されなかった場
合デフォルトのログイン名になります。
■
検査制約
検査制約は、列に挿入するデータの条件を指定します。表に挿入される各
行は、この条件を満たしていなければなりません。たとえば、表 items の
列 quantity では 1 以上の数量であるかを検査します。
データベースを設計する際の意味整合性の使用方法についての詳細は、
『Informix Guide to Database Design and Implementation』を参照してください。
参照整合性
参照整合性とは、表と表の間の関係を参照します。データベース内の各表には主
キーがなければならないので、他の表内のデータとの関係のために、この主キーが
他の表に現われる場合があります。ある表の主キーが他の表に現われる場合、これ
は外部キーと呼ばれます。
外部キーは表を結合し、表の間の依存性を確立します。表と表の依存性は、階層的
に形成することができます。ある表の行を変更または削除すると、他の表の行の意
味がなくなることがあります。たとえば、図 4-1 は、表 customer の列 customer_num
はその表の主キーであり、表 orders と cust_call tables の外部キーであることを示し
ています。顧客番号 106 の George Watson は、表 orders と表 cust_call の両方から参
照されています。顧客 106 が表 customer から削除されると、3 つの表のリンクとこ
の特定の顧客は意味を失います。
4-22
Informix Guide to SQL: Tutorial
参照整合性
図 4-2
データベース stores7 の参照整合性
表 customer
( 詳細 )
customer_num
fname
lname
103
Philip
Currie
106
George
Watson
表 orders
( 詳細 )
order_num
order_date
customer_num
1002
05/21/1998
101
1003
05/22/1998
104
1004
05/22/1998
106
表 cust_call
( 詳細 )
customer_num
call_dtime
user_id
106
1998-06-12 8:20
maryj
110
1998-07-07 10:24
richc
119
1998-07-01 15:00
richc
主キーを含んでいる行を削除したり、別の主キーで更新したりすると、その値を外
部キーとして含んでいる行の意味を破壊することになります。参照整合性とは、主
キーに対する外部キーの論理的依存性のことです。外部キーを含んでいる行の整合
性は、それが参照する行 ( つまり一致する主キーを含んでいる行 ) の整合性に依存
します。
データの更新
4-23
参照整合性
デフォルトでは、INFORMIX-Universal Server は参照整合性に違反することを許可し
ません。子表から行を削除する前に親表から行を削除しようとすると、エラーメッ
セージが表示されます。ただし、オプション ON DELETE CASCADE を使用すれば、
親表からのみ削除を実行し、子表の削除を実行しないことができます。4-24 ページ
の「オプション ON DELETE CASCADE の使用方法」を参照してください。
主キーと外部キー、そしてこの両者の関係を定義するには、CREATE TABLE 文と
『Informix Guide to
ALTER TABLE 文を使用します。これらの文についての詳細は、
SQL: Syntax』を参照してください。主キーと外部キーを使用したデータモデルの作
成については、
『Informix Guide to Database Design and Implementation』を参照してく
ださい。
オプション ON DELETE CASCADE の使用方法
表の主キーから行を削除するときに参照整合性を保持するには、CREATE TABLE
文と ALTER TABLE 文の REFERENCES 節のオプション ON DELETE CASCADE を
使用します。このオプションを使用すると、1 回の削除コマンドで、親表の行と対
応する子表の一致している行を削除することができます。
カスケード削除中のロック
削除の実行中に、親表および子表の修飾されている行がすべてロックされます。削
除を指定すると、親表から要求される削除は何らかの参照動作が実行される前に発
生します。
複数の子表に対する影響
一方の子にはカスケード削除が指定され、もう一方の子にはカスケード削除が指定
されていない二つの子側の制約を持つ親表があり、この両方の子表に適用されてい
る親表から行を削除しようとすると、DELETE 文は失敗し、親表からも子表からも
行は削除されません。
ログ機能をオンにする必要性
カスケード削除を実行するためには、現行データベースでログ機能をオンにしなけ
ればなりません。ログ機能とカスケード削除については、4-30 ページの「トランザ
クションログ機能」で説明します。
4-24
Informix Guide to SQL: Tutorial
参照整合性
カスケード削除の例
参照整合性規則が適用されている二つの表 ( 親表 account と子表 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));
表 account の主キーである列 acc_num colu はシリアル (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
データの更新
4-25
オブジェクトモードと違反の検出
カスケード削除に対する制約
自己参照型問合せおよび循環型問合せでの削除を含むほとんどの削除にカスケード
削除を使用することができます。唯一の例外は、相関副問合せです。相関副問合せ
とは、副問合せ文 ( または内部 SELECT 文 ) が生成する値が、その文自身が含まれ
ている外部 SELECT 文によって生成された値に依存していることです。カスケード
削除を実行した場合、相関副問合せ文で子表を使用する削除を記述することはでき
ません。相関副問合せ文から削除を実行しようとすると、エラーが発生します。
オブジェクトモードと違反の検出
AD/XP
Dynamic Server with AD and XP Options は違反表をサポートせず、オブジェクトモー
ドを有効化、無効化、またはフィルタします。 ♦
データベースのオブジェクトモード機能と違反の検出機能は、データの整合性の監
視に役立ちます。この二つの機能は、スキーマの変更中に両方の機能を組み合わせ
て使用したり、短期間に大量のデータに対して挿入、削除、更新などの操作が実行
されるときに使用したりすると特に効果的です。
オブジェクトモード機能を使用して、データベースオブジェクトのモードを変更す
ることができます。オブジェクトモード機能を説明する文中で使われているデータ
ベースオブジェクトは、制約、インデックス、およびトリガのことです。オブジェ
クトモード機能に関係のあるデータベースオブジェクトを、一般的な意味のデータ
ベースオブジェクトと混同しないでください。一般的なデータベースオブジェクト
は、表およびシノニムのようなものです。特にオブジェクトモードと関係のある
データベースオブジェクトは、制約、インデックス、およびトリガであり、これら
はすべて異なるモードを持っています。
オブジェクトモードの制約
制約は、有効化、無効化、またはフィルタすることができます。データベースマ
ネージャは、定義が依然としてシステムカタログ表にある場合でも、無効化された
制約を強制することはありません。有効化モードとフィルタモードの制約のみが強
制されます。しかし、制約がフィルタモードになっている場合には、データベース
マネージャはその特定の制約に対して基本表の整合性を保証します。有効化モード
とフィルタモードの違いは、制約の違反を提起する問合せに対するデータベースマ
ネージャの処理方法に明白に現われています。データベースマネージャは、制約違
反の処理に違反検出機能を使用します。
4-26
Informix Guide to SQL: Tutorial
オブジェクトモードと違反の検出
制約に違反する挿入文について考えてみます。制約のモードによって、データベー
スマネージャは挿入文を次のように扱います。
■
制約が有効化されている。
有効化されている制約に違反する挿入操作は、ターゲット表に挿入されま
せん。ユーザに制約違反エラーが返され、文の影響はロールバックされま
す。
■
制約が無効化されている。
無効化されている制約に違反する挿入操作は、ターゲット表には挿入され
ず、ユーザにエラーが返されることはありません。
■
制約がフィルタされている。
フィルタ制約に違反する挿入操作はターゲット表には挿入されず、違反表
に挿入されます。整合性違反に関する情報は、診断表と呼ばれるまったく
別の表に作成されて格納されます。挿入操作の影響は、ロールバックされ
ません。制約のモードをフィルタに切り替えると、制約違反が発生した後
にエラーが返されるか否かを決定することができます。
違反表と診断表の情報を分析すると、障害の原因を特定することができます。原因
の判明後、訂正処置をとるか、またはその操作をロールバックします。
オブジェクトモードの一意性インデックス
一意性インデックスもまた、有効化、無効化、フィルタの各モードを持っていま
す。フィルタモードの一意性インデックスは、フィルタモードの制約と同様に機能
します。しかし、重複エントリを回避しないインデックスは、有効化モードと無効
化モードのみを持っています。インデックスが無効化されると、そのインデックス
の基本表に対する挿入、削除または更新などの変更に従ってインデックスの内容が
更新されることはありません。インデックスの内容が最新ではないので、オプティ
マイザは、問合せ中に無効化インデックスを使用することはできません。
データの更新
4-27
中断された更新
オブジェクトモードのトリガ
トリガには制約および一意性インデックスとは異なり、二つのモードがあります。
従来までは、トリガが存在し、データベースマネージャによって適切なときに実行
されたか、もしくはトリガが存在しなかったために何も発生しませんでしたが、今
は、オブジェクトモードを使用して、既存のトリガを無効化することができます。
データベースマネージャは、無効化トリガのカタログ情報が最新に保たれている場
合でも、無効化モードのトリガを無視します。データベースマネージャは、有効化
モードのトリガは無視しません。トリガは、データベースに対するいかなる種類の
整合性指定も強制しないため、フィルタモードを持っていません。
AD/XP
Dynamic Server with AD and XP Options は SQL トリガをサポートしません。 ♦
SQL 文と例
詳細と例については、
『Informix Guide to SQL: Syntax』マニュアルの SET 文、
STARTVIOLATIONS 文、および STOP VIOLATIONS 文を参照してください。
中断された更新
どのソフトウェアにもエラーがなく、すべてのハードウェアが完全に信頼できる場
合でも、コンピュータ外部の環境から干渉を受ける場合があります。落雷による停
電で、UPDATE 文の実行中にコンピュータが停止する事態が起こらないとも限りま
せん。もっと可能性があるのは、ディスクがいっぱいになったり、ユーザが誤った
データを入力したりしたために、複数行の挿入がエラーのために早期に停止する場
合などです。いずれにしても、データの更新中には、予想外のイベントによって更
新が中断される可能性を考えなければなりません。
外部の原因によって更新が中断された場合は、どの段階まで操作が完了しているの
かわかりません。1 行を対象にした操作の場合でも、データがディスクに格納され
たか、またはインデックスが完全に更新されたかなどを確認することはできませ
ん。
4-28
Informix Guide to SQL: Tutorial
中断された更新
複数行の更新が問題となる場合は、複数文の更新はさらに大きな問題を発生させま
す。複数文は通常プログラムの中に埋め込まれているので、個々の SQL 文の実行
はユーザにはわかりません。たとえば、デモンストレーションデータベースに新し
い注文を入力するジョブでは、次の手順を実行する必要があります。
■
表 orders に行を挿入する。( この挿入は注文番号を生成します。)
■
注文された各品目について、表 items に行を挿入する。
注文入力アプリケーションのプログラミングには、2 通りの方法があります。その
一つは、プログラムが最初の行をただちに挿入し、その後オペレータがデータを入
力するたびに各品目を挿入するように、完全に対話型にする方法です。しかし、こ
のやり方では、多数のさらに予測不能な事態が発生するかもしれない状態に、この
操作を晒すことになります。顧客の電話が切れてしまった、オペレータが間違った
キーを押し、あるいはオペレータの端末やコンピュータの電源が切れたなどのハプ
ニングが考えられます。
適切な方法として、注文入力アプリケーションを以下の手順で処理するように作成
してください。
■
すべてのデータを対話的に受け入れる。
■
データの妥当性を検査し、表 stock や表 manufact のコードを参照するなどし
て必要な値を補う。
■
オペレータが確認できるように、情報を画面に表示する。
■
オペレータが最終的な確定操作を行うまで待つ。
■
挿入を迅速に実行する。
このような手順を踏んでも、予測不能な状況が発生して、注文は挿入したものの、
まだ項目の挿入が終わらないうちにプログラムが停止してしまう場合があります。
障害が発生した場合には、データベースの状態は予測できないものとなります。
データの整合性が損なわれている可能性もあります。
データの更新
4-29
トランザクション
トランザクション
これまで述べてきたような潜在的な問題すべてに対する解決策は、トランザクショ
ンと呼ばれています。トランザクションとは、完全に遂行されるか、あるいはまっ
たく遂行されないかのどちらか一連の更新のことです。データベースサーバは、ト
ランザクションの範囲内で実行された操作が、完全にディスクにコミットされた
か、またはデータベースがトランザクションが開始される前の状態に復元されたか
のいずれかを保証します。
トランザクションの役割は、予想外の障害からの保護だけではありません。プログ
ラムが論理エラーを検出したときのエスケープの方法も提供します。
トランザクションログ機能
データベースサーバは、トランザクションの実行中にデータベースに対して行われ
た個々の変更内容を記録することができます。トランザクションをキャンセルする
ようなイベントが発生すると、データベースサーバは自動的にその記録を使用して
変更前の状態に戻します。トランザクションの失敗には、多くの原因が考えられま
す。たとえば、SQL 文を発行するプログラムがクラッシュまたは途中終了すること
があります。トランザクションの失敗 ( この失敗は、コンピュータおよびデータ
ベースサーバが再起動された後にのみ発生する場合がある ) を検出すると、すぐに
データベースサーバはトランザクションのレコードを使用して、データベースを以
前と同じ状態に戻します。
トランザクションを記録するプロセスは、トランザクションログ機能あるいは単に
ログ機能と呼ばれています。ログレコードと呼ばれるトランザクションの記録は、
データベースとは別のディスク領域に格納されます。ログレコードがトランザク
ションの論理装置を表すため、この領域を論理ログと呼んでいます。
AD/XP
Dynamic Server with AD and XP Options のデータベースだけがトランザクションレ
コードを自動的に生成します。 ♦
多くの Informix データベースは、トランザクションレコードを自動的には生成しま
せん。データベース管理者が、データベースにトランザクションログ機能を使用す
るかどうか決定してください。トランザクションログ機能を使用しない場合、トラ
ンザクションをロールバックすることはできません。
4-30
Informix Guide to SQL: Tutorial
トランザクションログ機能
AD/XP
Informix Dynamic Server with AD and XP Options のトランザクション
ログ機能
論理ログ ファイルに加えて、Dynamic Server with AD and XP Options によりログスラ
イスを作成できます。ログスライスは、DB 領域を占めるログファイルのセットで
す。これらのログ ファイルは、DB 領域当たり 1 つのログファイルの割合で、複数
のコサーバが所有します。ログスライスは、1 セットのログ ファイルを単一のエン
ティティとして扱うため、ログ ファイルの追加と削除のプロセスを単純化します。
ログ スライスの詳細については、
『Administrator’s Guide』を参照してください。
Dynamic Server with AD and XP Options は、データベースに記録されなければならず、
ログ機能をオフにはできません。しかし、個々の表がログ付き表であるかログなし
表であるかを指定できます。ログ付き表とログなし表の両方のニーズに合致するた
め、Dynamic Server with AD and XP Options は、次のタイプの永続表と一時表をサ
ポートします。
■
ロウ永続表 ( ログなし )
■
静的永続表 ( ログなし )
■
操作永続表 ( ログ付き )
■
標準永続表 ( ログ付き )
■
スクラッチ一時表 ( ログなし )
■
Temp 一時表 ( ログ付き )
Dynamic Server with AD and XP Options がサポートする表型の詳細については、
『Informix Guide to Database Design and Implementation』を参照してください。
ログ機能とカスケード削除
カスケード削除を実行するためには、データベースでログ機能をオンにしなければ
なりません。これは、カスケード削除を指定すると、削除はまず親表の主キーで実
行されるからです。もし、親表の主キー行の削除が実行された後で、子表の外部
キー行を削除する前にシステムがクラッシュすると、参照整合性に違反します。ロ
グ機能を一時的にでもオフにすると、削除処理はカスケードされません。しかし、
ログ機能をオンに戻すと、再びカスケード削除にすることができます。
データの更新
4-31
トランザクションの指定
Dynamic Server では、CREATE DATABASE 文の WITH LOG 節でログ機能をオンにし
ます。 ♦
IDS
AD/XP
Dynamic Server with AD and XP Options で作成されるデータベースは、WITH LOG 節
を CREATE DATABASE 文に含める場合も含めない場合も、常にログ付きデータ
ベースです。 ♦
トランザクションの指定
SQL 文を使用してトランザクションの範囲を指定する方法は二つあります。最も一
般的な方法では、BEGIN WORK 文を実行することにより、複数文のトランザク
ションの開始を指定します。オプション MODE ANSI を使用して作成されたデータ
ベースでは、トランザクションの開始を指定する必要はありません。常にトランザ
クションが開始されている状態にあるため、個々のトランザクションの終了のみを
指定してください。
どちらの方法を使用する場合でも、成功したトランザクションの終了を指定するに
は、COMMIT WORK 文を実行します。この文は、すべてが完全に成功しなければ
ならない一連の文の終わりに達したことをデータベースサーバに伝えます。データ
ベースサーバは、すべての更新を正しく完了し、コミットされてディスクに格納さ
れるために、必要な操作をすべて行います。
また、プログラムは、ROLLBACK WORK 文を実行することによって、トランザク
ションを意図的にキャンセルすることもできます。この文は、現行のトランザク
ションをキャンセルし、すべての変更を取り消すようにデータベースサーバに指示
します。
注文入力アプリケーションは、新しい注文の作成時に次のような方法を使用してト
ランザクションを使用することができます。
4-32
■
すべてのデータを対話的に受け入れる。
■
妥当性を検査し、必要な値を補う。
■
オペレータが最終的な確定操作を行うまで待つ。
■
BEGIN WORK 文を実行する。
■
表 orders および表 items に行を挿入し、データベースサーバが返すエラー
コードを検査する。
■
エラーが発生しなかった場合は、COMMIT WORK 文を実行する。エラー
が発生した場合は、ROLLBACK WORK 文を実行する。
Informix Guide to SQL: Tutorial
Informix データベースサーバを使用したバックアップとログ
外部の障害によってトランザクションが完了できなかった場合でも、システムを再
起動すると、トランザクションの一部がロールバックされます。これによって、ど
のような場合でもデータベースの状態は予測可能です。すなわち、新しい注文が完
全に入力されたか、あるいはまったく入力されていないかのいずれかの状態がわか
ります。
Informix データベースサーバを使用したバック
アップとログ
トランザクションを使用することによって、データベースを常に一貫した状態に保
ち、更新内容を正しくディスクに記録することができます。しかし、ディスクその
ものは 100 パーセント安全というわけではありません。ディスクは、機械的な障害
や水害、火災、また地震などの影響を受けやすいものです。このような障害に対す
る唯一の安全措置は、データのコピーを複数作成し、保持することです。これらの
複数のコピーは、バックアップコピーと呼ばれます。
トランザクションログ ( 論理ログとも呼ぶ ) は、データベースのバックアップコ
ピーを補います。その内容は、最後にデータベースをバックアップしてから発生し
たすべての更新の履歴です。バックアップコピーからデータベースを復元する必要
が発生した場合は、トランザクションログを使用して、データベースを最新の状態
にロールフォワードすることができます。
データベース サーバには、バックアップ機能とログ機能をサポートする高性能機能
があります。ご使用のデータベース サーバのアーカイブとバックアップのガイドに
これらの機能について説明しています。
データベース サーバは、性能と信頼性について非常に強力な要件を持っています ( 例
えば、データベースが使用中に、バックアップ コピーの作成をサポートします )。
データベース サーバは、ログ機能専用の自分自身のディスク領域を管理します。
データベース サーバは、少数のログ ファイル セットを使用して、すべてのデータ
ベースのためにログ機能を同時に実行します。ログ ファイルは、トランザクション
が有効な間に ( バック アップされた ) 別の媒体にコピーできます。
これらの機能は、通常データベース サーバ管理者が中心格納場所から管理するた
め、データベース ユーザがこれらの機能と係わる必要は全くありません。
データの更新
4-33
並列度とロック
Dynamic Server では単一のデータベースまたは表の個人用バックアップコピーを作
成する場合は、onunload ユーティリティを使用して作成できます。このプログラム
は、表またはデータベースをテープにコピーします。出力は、データベースサーバ
で格納されたときのディスクページのバイナリイメージから構成されています。そ
の結果、コピーを非常に迅速に作成でき、対応するプログラム onload も、ファイル
をきわめて迅速に復元することができます。ただし、他のプログラムではこのデー
タフォーマットは無効です。♦
IDS
AD/XP
Dynamic Server with AD and XP Options は、
onload ユーティリティと onunload ユーティ
リティをサポートしません。データのロードまたはアンロードを行うために、デー
タベース サーバは外部表を使用します。データをロードするために外部表を使用す
る方法についての詳細は、
『Administrator’s Guide』を参照してください。 ♦
データベースサーバ管理者が ON-Bar を使用してバックアップを作成し、論理ログ
をバックアップしている場合は、一般ユーザも ON-Bar を使用して独自のバック
アップ コピーを作成できます。詳細は、
『Backup and Restore Guide』を参照してくだ
さい。
並列度とロック
データベースが単一ユーザのワークステーションに含まれており、ネットワークを
経由して接続されているコンピュータがない場合、並列度は問題にはなりません。
その他の場合には、ユーザのプログラムがデータを更新している間に、他のプログ
ラムが同じデータを読み込んだり更新したりしている可能性について考慮しなけれ
ばなりません。並列度は、同じデータを同時に複数独立して使用する場合に関係し
てきます。
高度な並列度は、複数のユーザによって使用されるデータベースシステムの性能向
上に不可欠です。ただし、データの使用を十分に管理しないと、並列度はさまざま
な弊害をもたらすおそれがあります。プログラムが古いデータを読み込んでしまっ
たり、正しく入力した更新内容が失われてしまったりすることもありえます。
この種のエラーを防止するために、データベースサーバはロックというシステムを
課しています。ロックは、データの各部に対するプログラムからの使用予約です。
データベースサーバは、ロックされているデータについては、他のプログラムがそ
のデータを更新できないようにします。他のプログラムがそのデータを要求した場
合は、ロックが解除されるまでそのプログラムを待機させるか、エラーメッセージ
を発行して、その要求を拒否します。
4-34
Informix Guide to SQL: Tutorial
データレプリケーション
ロックがデータアクセスに与える影響については、SET LOCK MODE 文と、SET
ISOLATION 文または SET TRANSACTION 文の組合せを使用して制御します。これ
らの文についての詳細は、プログラム内部からのカーソルの使用方法の説明を読み
終わると理解することができます。カーソルについては、第 5 章「SQL を使用した
プログラミング」と、第 6 章「SQL プログラムによるデータの更新」で説明しま
す。また、ロックと並列度についての詳細は、第 7 章「マルチユーザ環境のため
のプログラミング」も参照してください。
データレプリケーション
データレプリケーションとは、広義では、データベースオブジェクトが複数の異な
るサイトで複数の表現を持つことを言います。たとえば、元のデータベースを使用
しているクライアントアプリケーションを妨害せずに、データに対してレポートを
実行できるようにデータを複製する一つの方法として、データベースを別のコン
ピュータ上のデータベースサーバにコピーすることができます。
次に、データレプリケーションの利点について説明します。
AD/XP
■
複製されていない遠隔データではなく、複製されたデータにローカルにア
クセスするクライアントは、ネットワークサービスを使用する必要がない
ために性能が向上します。
■
どのサイトのクライアントでも、複製されたデータを使用すると可用性が
向上します。これは、ローカルの複製データが使用できない場合に、遠隔
からでもデータのコピーを使用することができるからです。
Dynamic Server with AD and XP Options は、データレプリケーションをサポートしま
せん。 ♦
これらの利点を得るためには、コストもかかります。データレプリケーションで
は、データを複製しない場合よりも複製データのためにより多くの記憶域が必要
となり、複製データの更新には、一つのオブジェクトの更新よりも多くの処理時
間がかかるためです。
データの更新
4-35
Informix データベースサーバによるデータレプリケーション
実際には、データレプリケーションは、データの位置または更新位置を明示的に指
定することにより、クライアントアプリケーションのプログラムロジックに実行す
ることができます。ただし、この方法によるデータレプリケーションのアーカイブ
にはコストがかかり、エラーも発生しやすく、管理が難しくなります。データレプ
リケーションの概念は、しばしばレプリケーションの透過性と結び付けられます。
レプリケーションの透過性は、データの複製の自動配置および保持の個々の処理を
行うために ( クライアントアプリケーションの代わりに ) データベースサーバに組
み込まれている機能です。
Informix データベースサーバによるデータレプリケーション
データレプリケーションの幅広い枠内で、Informix データベースサーバはデータベー
スサーバ全体のほとんど透過的なデータレプリケーションを実装します。一つ
の Informix データベースサーバによって管理されるすべてのデータは、通常遠隔サ
イトにある別の Informix データベースサーバ上で複製され、動的に更新されま
す。Informix データベースサーバのデータレプリケーションは、破局的な障害が発生
した場合に、すばやく使用できるデータベースサーバ全体のバックアップコピーを
保持する手段を提供するため、ホットサイトバックアップと呼ばれることもありま
す。
データベースサーバはレプリケーションの透過性を提供するので、通常はデータレ
プリケーションについて考慮する必要はありません。データベースサーバ管理者が
データレプリケーションを処理します。しかし、ユーザの組織がデータレプリケー
ションの採用を決定した場合は、データレプリケーション環境では、クライアント
アプリケーションに関して特殊なコネクティビティ問題があることを認識すべきで
す。これらの注意事項については、
『Administrator’s Guide』を参照してください。
Informix エンタプライズ レプリケーション機能はデータレプリケーションの別の手
段を提供します。この機能については『Guide to Informix Enterprise Replication』を参
照してください。
AD/XP
4-36
Dynamic Server with AD and XP Options は、エンタプライズ レプリケーション機能を
サポートしません。 ♦
Informix Guide to SQL: Tutorial
まとめ
まとめ
データベースに対するアクセスは、データベースの所有者が付与するアクセス権に
よって制限されます。データに対する問合せを行うためのアクセス権は、多くの場
合自動的に与えられますが、データを更新するための権利は、表ごとに特定の挿入
アクセス権、削除アクセス権、更新アクセス権を付与することによって制限されま
す。
データベースにデータ整合性制約がある場合、データを更新するための権限は、こ
れらの制約によって制限されます。データベースレベルおよび表レベルのアクセス
権は、データ制約とともに、データを更新する方法とそのタイミングを制御しま
す。
更に、データベースのオブジェクト モードと違反検出機能は、ユーザがデータを修
正する方法、およびユーザがデータの整合性の維持を支援する方法に影響を与えま
す。
DELETE 文を使用すると、表から一つまたは複数の行を削除することができます。
DELETE 文の WHERE 節で削除対象の行を選択します。同じ WHERE 節を持つ
SELECT 文を使用すると、削除対象の行を事前に確認できます。
INSERT 文を使用すると、行が表に追加されます。指定した列の値を含んでいる単
一の行を挿入することや、SELECT 文が生成する行のブロックを挿入することもで
きます。
UPDATE 文を使用すると、既存の行の内容を更新することができます。副問合せ文
を指定できる式で新しい内容を指定して、他の表や更新された表自体に基づくデー
タを使用することができます。この文には二つのフォームがあります。最初の
フォームでは、列ごとに新しい値を指定します。もう一つのフォームでは、
SELECT 文またはレコード変数が一連の新しい値を生成します。
表の間の関係を作成するには、CREATE TABLE 文および ALTER TABLE 文の
REFERENCES 節を使用します。REFERENCES 節のオプション ON
DELETECASCADE を使用すると、1 回の DELETE 文で親表とそれに関連した子表
から行を削除することができます。
データの更新
4-37
まとめ
トランザクションは、更新操作の実行中に予想外の障害が発生して、データベース
が不安定な状態になることを防止するために使用します。トランザクション内で更
新が実行され、エラーが発生した場合、それらの更新はロールバックされます。ま
た、トランザクションログは、定期的に作成されるデータベースのバックアップコ
ピーも適用します。これにより、データベースを復元しなければならない場合に、
最新の状態に戻すことができます。
ユーザに対して透過的に行われるデータレプリケーションは、致命的な障害からの
もう一つの保護対策です。
4-38
Informix Guide to SQL: Tutorial
第5章
SQL を使用したプログラミン
グ
プログラム中の SQL . . . . .
SQL API 中の SQL . . . .
アプリケーション言語の SQL
静的 SQL 文 . . . . .
動的 SQL 文 . . . . .
プログラム変数とホスト変数
.
.
.
.
.
.
.
.
.
.
.
.
データベースサーバの呼出し
SQL 通信領域 . . .
SQLCODE フィールド .
データの終り . .
負のコード . . .
SQLERRD 配列 . . .
SQLWARN 配列 . . .
SQLERRM 文字配列 .
SQLSTATE 値 . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
. . .
. . .
. . .
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5-4
5-4
5-5
5-5
5-5
5-6
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5-8
5-8
5-9
5-9
5-10
5-10
5-11
5-13
5-13
単一行の抽出 . . . . . . . . . . . . . .
データ型変換 . . . . . . . . . . . .
NULL データの処理. . . . . . . . . . .
エラーの処理 . . . . . . . . . . . .
データの終り . . . . . . . . . . .
ANSI 標準準拠でないデータベースのデータの終り
重大なエラー . . . . . . . . . . .
集計関数とデータの終り . . . . . . . .
デフォルト値の使用方法 . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5-14
5-15
5-16
5-17
5-17
5-18
5-18
5-18
5-19
複数行の抽出 . . . . . .
カーソルの宣言 . . . .
カーソルのオープン . .
行の取出し . . . . .
データの終りの検出 .
INTO 節の設定 . . .
カーソルによる取出し . .
カーソルのアクティブセット
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5-20
5-20
5-21
5-22
5-22
5-23
5-23
5-24
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
アクティブセットの作成 . . . . .
順カーソルのアクティブセット . . .
スクロールカーソルのアクティブセット.
アクティブセットと並列度. . . . .
カーソルの使用方法 : 部品爆発 . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5-24
5-25
5-25
5-26
5-27
動的 SQL . . . . . . . . . . . . . . . . .
文の PREPARE 文による処理 . . . . . . .
PREPARE 文で処理された SQL 文の実行 . . . .
動的なホスト変数 . . . . . . . . . .
PREPARE 文で処理された文が所有する記憶域の解放
実行の高速化 . . . . . . . . . . . .
.
.
.
.
.
.
. . . . .
. . . .
. . . .
. . . .
. . . .
. . . .
.
.
.
.
.
.
.
.
.
.
.
.
5-29
5-30
5-31
5-32
5-33
5-33
プログラム中のデータ定義文
5-2
.
.
.
.
.
.
.
.
.
.
. . .
. . .
. . .
. . .
. .
5-34
GRANT 文と REVOKE 文の埋込み . . .
. . .
. . .
. . .
. .
5-34
まとめ . . .
. . .
. . .
. . .
. .
5-37
. .
.
.
.
.
.
.
. . .
Informix Guide to SQL: Tutorial
. . .
これまでの章では、SQL を対話型のコンピュータ言語のように扱いました。つまり
ユーザが SELECT 文をデータベースサーバに対して直接入力し、それに対して検索
結果の行が一度に表示されると考えてきました。
実際はもう少し複雑です。ユーザとデータベースサーバの間には、何層ものソフト
ウェアが存在しています。データベースサーバはデータをバイナリ形式で保持して
いるため、表示の前にデータをフォーマットすることが必要です。また、データ
ベースサーバは、大量のデータを一度にユーザに返すのではありません。プログラ
ムの要求に応じて、1 行ずつ返します。
いくつかの方法でデータベースの情報にアクセスすることができます。
■
DB-Access またはリレーショナルオブジェクトマネージャを使用した対話
型アクセスをする方法
■
ESQL/CのようなSQL APIで書き込まれたアプリケーション プログラムを使
用する方法
■
ストアド プロシジャ言語 (SPL) のようなアプリケーション言語を使用する
方法
ほとんどのプログラムは、内部に SQL 文を埋め込んで、それを実行し、データ
ベースサーバからデータを抽出することができます。この章では、データベース操
作はどのように行われるか、また、データベース操作を行うプログラムはどのよう
に作成するかについて説明します。
この章では、さまざまな言語で使用する SQL プログラミングに共通する基本概念
について説明します。特定のプログラミング言語を使用して実用的なプログラムを
作成するには、まず、その言語をよく理解していることが必要です。プログラム作
成の詳細は各言語により異なります。詳細は、使用している言語の INFORMIXSQL API のマニュアルを参照してください。
SQL を使用したプログラミング
5-3
プログラム中の SQL
プログラム中の SQL
SQL をサポートするプログラミング言語を使用すると、SQL 文をその言語の通常の
文と同じように、プログラム中に組み込むことができます。これらの SQL 文はプ
ログラム中に埋め込まれ、埋込み SQL を含むプログラムは、Informix ではよく
ESQL と省略されます。
SQL API 中の SQL
ESQL は INFORMIX SQL API ( アプリケーション プログラミング インターフェイス )
製品です。Informix は、C 言語について SQL API を製品化しています。
図 5-1 に SQL API 製品の動作の概要を示します。まず SQL 文を実行可能コードと
して扱ってソースプログラムを作成します。このソースプログラムを処理するのが
埋込み SQL プリプロセッサです。ESQL プリプロセッサはソースプログラムに埋め
込まれた SQL 文を見つけ、特別のデータ構造を一連のプロシジャ呼出しに変換し
ます。
図 5-1
ESQL 文を含むプログラムの処理概要
ESQL ソース
プログラム
ESQL
プリプロセッサ
プロシジャ呼出しの
各言語のコンパイラ
入ったソースプログラム
実行可能プログラム
変換されたソースプログラムは、そのプログラミング言語のコンパイラへ送られま
す。コンパイラの出力は、SQL API プロシジャの静的ライブラリまたは動的ライブ
ラリとリンクされて、実行可能プログラムになります。実行可能プログラムの実行
時には、SQL API ライブラリ手続きが呼び出されます。呼び出された SQL API ライ
ブラリ手続きは SQL 操作を実行するために、データベースサーバとの通信を設定
します。
5-4
Informix Guide to SQL: Tutorial
アプリケーション言語の SQL
実行可能プログラムを、スレッドライブラリパッケージにリンクすると、ESQL/C
のマルチスレッドアプリケーションを開発することができます。マルチスレッドア
プリケーションは、制御スレッドを多く持つことができます。マルチスレッドアプ
リケーションは、プロセスを、それぞれ独立して実行することができる複数の実行
スレッドに分割します。マルチスレッドの ESQL/C アプリケーションの最大の利点
は、各スレッドがデータベースサーバに対して複数の実効接続を同時に確立できる
という点です。非スレッド ESQL/C アプリケーションが一つ以上のデータベースに
対して複数の接続を確立できるのに対して、複数スレッドのアプリケーションは一
度に一つの実効状態の接続のみ確立します。マルチスレッド ESQL/C アプリケー
ションは、スレッドあたり一つの実効状態の接続を確立でき、アプリケーションご
とに複数のスレッドを持つことができます。
マルチスレッドアプリケーションについての詳細は、
『INFORMIX-ESQL/C
Programmer’s Manual』を参照してください。
アプリケーション言語の SQL
SQL API 製品により SQL をホスト言語に埋め込むことができますが、言語の中には
SQL をその文セットの本来の部分として含めるものもあります。Informix ストアド
プロシジャ言語 (SPL) は、SQL をその文セットの本来の部分として使用します。
SPL API 製品を使用して、アプリケーション プログラムを書き込みます。データ
ベースで格納され、アプリケーション プログラムから呼び出されるプロシジャは、
SPL を使用して書き込みます。
静的 SQL 文
SQL 文は、静的な埋込みまたは動的な埋込みによりプログラム中に埋め込むことが
できます。静的な埋込みはより簡単で一般的な方法です。これは、SQL 文をソース
プログラムのテキスト中に記述することを意味しています。この SQL 文は、ソー
スプログラムの一部になり、そのままそこに固定されるため静的 SQL 文と呼ばれ
ます。静的な埋込みの方法についての詳細は、5-14 ページの「単一行の抽出」と、
5-20 ページの「複数行の抽出」を参照してください。
動的 SQL 文
アプリケーションの中には、ユーザの入力に応じて動的 SQL 文を作成する必要が
あるものがあります。ユーザからの入力に応じて異なる列を選択したり、異なる判
断基準を行に適用したりしなければならないプログラムがその例です。
SQL を使用したプログラミング
5-5
プログラム変数とホスト変数
動的 SQL 文を用いるプログラムは、SQL 文を文字列としてメモリ内に作成し、そ
の文字列をデータベースサーバに渡して実行します。動的 SQL 文は、ソースプロ
グラムのテキストの一部ではなく、プログラムを実行する時点でメモリ内に作成さ
れます。
動的 SQL 文の作成についての詳細は、5-29 ページの「動的 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 文がプログラムの内部では「ゲスト」と見なされる
ためです。
次に、INFORMIX-ESQL/C のソースプログラムに埋め込まれた DELETE 文の例を示
します。
EXEC SQL delete FROM items
WHERE order_num = :o-num
このプログラムには、第 4 章「データの更新」で説明している通常の DELETE 文が
あります。ESQL/C プログラムが実行されると、表 items の行が削除されます。複
数の行を削除することもできます。
この文には 1 つの新しい機能が含まれています。それは order_num 列を :onum と書
き込まれた項目と比較します。これはホスト変数の名前を表します。
5-6
Informix Guide to SQL: Tutorial
プログラム変数とホスト変数
SQL API 製品は、ホスト変数の名前が SQL 文のコンテキストに表示される場合、こ
れらを区切る方法を提供します。ESQL/C では、ホスト変数はドル記号 ($) または
コロン (:) で導入できます。コロンは、ANSI 標準に準拠するフォーマットです。こ
の例文は、注文番号が :onum という名前のホスト変数の現在の内容と等しい行を削
除するようにデータベース サーバに要求しています。この数値変数は、プログラム
内のこれよりも前の部分で宣言され、値を設定されています。
INFORMIX-ESQL/C では、SQL 文は、頭にドル記号 ($) を付けるか語 EXEC SQL の
どちらかで導入できます。
前の例で示されたように構文上の違いは些細なものにすぎず、本質的なポイント
は、SQL API と SPL の言語では次のタスクを実行できるということです。
■
SQL 文を、ホスト言語の実行可能文であるかのようにソースプログラムに
埋め込むことができる。
■
プログラム変数を、定数値を使用するのと同じように SQL 文で使用するこ
とができる。
プログラミング経験のある方なら、すぐにその可能性を知ることができます。例で
は、削除対象の行の注文番号はホスト変数 onum から渡されます。この値は、プロ
グラムからアクセス可能なソースなら、どのソースからでも持ってくることができ
ます。ファイルから読み込んだ値の場合もあります。プログラムが出したプロンプ
トに応じてユーザが入力した値の場合もあります。あるいは、データベースから読
み込んだ値の場合もあります。DELETE 文自体がサブルーチンの一部かもしれませ
ん。その場合は、onum はそのサブルーチンのパラメータになります。そのサブ
ルーチンは一度だけ呼び出されるかもしれませんし、繰り返し呼び出されるかもし
れません。
つまり、SQL 文をプログラムに埋め込むことにより、ホスト言語のすべての機能を
SQL 文に適用できるようになります。SQL の機能に対して、SQL 文を埋め込んだ
さまざまなインターフェイスを与えて、使用目的に適したアプリケーションを作る
ことができます。
SQL を使用したプログラミング
5-7
データベースサーバの呼出し
データベースサーバの呼出し
SQL 文を実行することは、基本的にはサブルーチンとしてデータベースサーバを呼
び出すことです。プログラムとデータベースサーバの間で情報の受渡しが必要で
す。
プログラムとデータベースサーバとの間の通信の一部はホスト変数を介して行われ
ます。文の内部に指定したホスト変数は、データベースサーバにアクセスするプロ
シジャ呼出しのパラメータと考えることができます。先の例では、ホスト変数は
WHERE 節のパラメータとして機能しています。5-20 ページの「複数行の抽出」で
説明しているように、ホスト変数はデータベースサーバが返すデータを受け取りま
す。
SQL 通信領域
データベースサーバは常に結果コードを返します。その操作に影響するその他の情
報も返すことがあります。これらの情報は、SQL 通信領域 (SQLCA) と呼ばれる
データ構造体に格納されます。データベースサーバがストアドプロシジャ内の SQL
文を実行するときには、呼び出しているアプリケーションプログラムの SQLCA 構
造体がストアドプロシジャ内で実行された SQL 文に対応する値を持ちます。
データベースサーバがストアドプロシジャ内の SQL 文を実行するときには、呼び
出しているアプリケーションプログラムの SQLCA 構造体がストアドプロシジャ内
で実行された SQL 文に対応する値を持ちます。
SQLCA の主なフィールドについては、図 5-2 から図 5-4 で説明します。SQLCA な
どのデータ構造体を説明するのに使用する構文や、そのデータ構造体のフィールド
を参照するのに使用する構文は、各プログラミング言語によって異なります。詳細
は、SQL API マニュアルを参照してください。
具体的には、SQLERRD 配列と SQLWARN 配列の 1 つの要素に名前をつける添字が
異なります。配列要素の番号は、INFORMIX-ESQL/C ではゼロから始まりますが、
他の言語では 1 から始まります。この説明では、3 番目の要素といった語でフィー
ルドの名前が付けられていますが、使用するプログラミング言語の構文に合うよう
に、これらの語を変えることが必要です。
GET DIAGNOSTICS 文の SQLSTATE 変数を使用して、エラーの検出、処理、診断
を行うこともできます。詳細は、5-13 ページの「SQLSTATE 値」を参照してくださ
い。
5-8
Informix Guide to SQL: Tutorial
SQLCODE フィールド
SQLCODE フィールド
SQLCODE フィールドは、データベースサーバから返される主なリターンコードで
す。各 SQL 文が実行されると、SQLCODE は図 5-2 に示されている整数値に設定さ
れます。0 は、SQL 文の実行が成功し、エラーがなかったことを示します。特に、
データをホスト変数に返す文の場合は、SQLCODE が 0 ならば、データがホスト変
数に返されていて使用可能なことを示します。0 以外のコードが返ったときは、ホ
スト変数に有効なデータは返されていません。
図 5-2
SQLCODE の値
戻り値
意味
値<0
エラー コードを指定する。
値=0
成功したことを示す。
0 < 値 < 100
DESCRIBE 文が実行された後で、記述される SQL 文のタイプを表す整数値。
100
行がなにも返されずに問合せが成功した後で、NOT FOUND 条件を示す。
NOT FOUND は、INSERT INTO/SELECT 文、UPDATE 文、DELETE 文、ま
たは SELECT...INTO TEMP 文が行へのアクセスに失敗した後では ANSI 互換
データベースでも発生することがある。
データの終り
文は正しく実行されたが行が 1 行も見つからなかった場合は、データベースサーバ
は SQLCODE を 100 に設定します。これには二つの状況が考えられます。
カーソルを使用する間合せについては、5-20 ページの「複数行の抽出」で説明して
います。
)このような問合せでは、FETCH 文により各値がアクティブセットからメ
モリ内に抽出されます。最後の行が抽出されると、以降の FETCH 文はデータを返
すことができません。この結果データベースサーバは SQLCODE を 100 に設定し、
データの最終行が見つかったことを示します。
SQL を使用したプログラミング
5-9
SQLERRD 配列
2 番目の状況には、カーソルを使用しない問合せが含まれます。この場合、問合せ
の条件を満たす行がないときに、データベース サーバは SQLCODE を 100 に設定
します。ANSI 標準準拠ではないデータベースでは、SELECT 文により 1 行も行が
返されなかった場合のみ、SQLCODE は 100 に設定されます。
ANSI
ANSI 標準準拠のデータベースでは、行が返されない場合、SELECT 文、DELETE 文、
UPDATE 文、INSERT 文はすべて SQLCODE を 100 に設定します。 ♦
負のコード
文の実行中に予期されなかった要素が発生して実行が失敗すると、データベース
サーバはエラーを示す負の番号を SQLCODE に返します。エラーコードの意味は、
『Informix Error Messages』マニュアルとオンラインエラーメッセージファイルで説
明されています。
SQLERRD 配列
SQLCODE に設定されるエラーコードの一部は一般的なエラーを示します。データ
ベースサーバは、SQLERRD の 2 番目のフィールドにより詳しいコードを設定しま
す。このフィールドは、データベース入出力ルーチンまたはオペレーティングシス
テムで発生したエラーを示します。
SQLERRD 配列を構成する整数型の要素は、実行された文に応じて、さまざまな値
に設定されます。この配列の 1 番目と 4 番目の要素は、INFORMIX-ESQL/C および
INFORMIX-ESQL/COBOL でのみ使用されます。これらのフィールドの使用方法は、
図 5-3 に示されています。
SQLERRD が与える補足的な詳細情報は、場合によっては非常に便利です。たとえ
ば、3 番目のフィールドの値を使用して、削除や更新された行が何行であったかを
報告できます。ユーザが入力した SQL 文をプログラムが PREPARE 文で処理してい
るときにエラーが見つかった場合は、5 番目のプログラムの値を使用するとエラー
の場所を正確にユーザに示せます。DB-Access やリレーショナルオブジェクトマ
ネージャは、エラーの後で文の変更をユーザが要求したとき、この機能を使用して
カーソルをエラーの箇所に移動させます。
5-10
Informix Guide to SQL: Tutorial
SQLWARN 配列
図 5-3
SQLERRD のフィールド
フィールド
意味
1 番目
SELECT 文、UPDATE 文、INSERT 文、または DELETE 文について PREPARE 文が成功した
後で、あるいは SELECT カーソルがオープンされた後では、このフィールドに、影響
を受けた行の概数が含まれる。
2 番目
SQLCODE にエラー コードが含まれている場合は、このフィールドに、ゼロもしくは
ISAM エラー コードと呼ばれる追加のエラー コードのどちらかが含まれる。これは、
主なエラーの原因を示す。
単一の行に対して挿入、更新、または削除操作が成功した後では、このフィールドに、
その行に対して生成されたあらゆる SERIAL 値の値が含まれる。
3 番目
複数行に対して挿入、更新、または削除操作が成功した後では、このフィールドに、
処理された行の数が含まれる。
複数行の挿入、更新、または削除操作がエラーで終了した後では、このフィールドに、
エラーが検出される前に正常に処理された行の数が含まれる。
4 番目
SELECT 文、UPDATE 文、INSERT 文、または DELETE 文について PREPARE 文が成功した
後で、あるいは SELECT カーソルがオープンされた後では、このフィールドに、ディ
スク アクセス回数の加重合計の概数と処理された行の総数が含まれる。
5 番目
PREPARE 文、EXECUTE IMMEDIATE 文、DECLARE 文、または静的 SQL 文も構文エラー
が発生した後では、このフィールドに、そのエラーが検出された文のテキスト内での
オフセットが含まれる。
6 番目
選択された行の取出しが成功したか、あるいは挿入、更新、または削除操作が成功し
た後では、このフィールドに、最後に処理された行の行識別子 ( 物理アドレス ) が含ま
れる。この行識別子の値が、データベース サーバがユーザに返す行に対応するものか
どうかは、データベース サーバが問合せ ( 特に SELECT 文についての問合せ ) をどのよ
うに処理するかによる。
SQLWARN 配列
SQLWARN 配列を構成する 8 つの文字型のフィールドは、空白文字か W のどちら
かに設定され、さまざまな状態を示します。これらの意味は直前に実行された文に
よって異なります。
SQLAWARN のフィールドに設定される警告フラグは、CONNECT 文、DATABASE
文、あるいは CREATE DATABASE 文が実行された後でデータベースがオープンし
たときに表示されます。これらのフラグはデータベース全体の特性を示します。
SQL を使用したプログラミング 5-11
SQLWARN 配列
警告フラグ以外のフラグは、上記以外のすべての文を実行した後に表示されます。
これらのフラグは、その文の実行中に発生した異常なイベントを示します。フラグ
により、SQLCODE だけでは十分に記述できないイベントを示す場合もあります。
図 5-4
SQLWARN のフィールド
フィールド
データベースに対してオープンまたは接
続する場合
その他すべての操作の場合
1 番目
他のいずれかの警告フィールドが W に設定されているときには W に設定される。この
フィールドが空白の場合は、他の要素を確認する必要はない。
2 番目
現在オープンしているデータベースがト
ランザクション ログを使用する場合は
W に設定される。
列の値が FETCH 文または SELECT...INTO 文を
使用して取り出されてホスト変数に入れられ
たときにその値が切り捨てられた場合は、W
に設定される。REVOKE ALL 文では、7 つの
表レベル アクセス権の一部だけが取り消さ
れるときは W に設定される。
3 番目
現在オープンしているデータベースが
ANSI 標準に準拠している場合は W に設
定される。
FETCH 文または SELECT 文が NULL である集
合関数 (SUM、AVG、MIN、MAX) 値を返すと
きは W に設定される。
4 番目
データベース サーバが
SELECT...INTO 文、FETCH...INTO 文、または
EXECUTE...INTO 文では、選択対象の並びの項
INFORMIX-Universal Server であるときは W
5 番目
に設定される。
目の数が、それら項目を受け取るために
INTO 節に与えられたホスト変数の数と同じ
でないときは W に設定される。GRANT ALL
文では、7 つの表レベル アクセス権の一部だ
けが付与されたときは W に設定される。
データベース サーバが FLOAT データ型
を DECIMAL 形式で格納する (FLOAT 型
に対するサポートがホスト システムに
ないときに行われます ) ときは W に設定
される。
PREPARE 文で処理された文に、DELETE 文ま
たは UPDATE 文が含まれ、WHERE 節がない
場合には、DESCRIBE 文の実行された後で W
に設定される。
(1/2)
5-12
Informix Guide to SQL: Tutorial
SQLERRM 文字配列
フィールド
データベースに対してオープンまたは接
続する場合
その他すべての操作の場合
6 番目
データベース サーバが FLOAT データ型を ANSI 標準 SQL 構文をもたない文の実行
DECIMAL 形式で格納する (FLOAT 型に対す (DBANSIWARN 環境変数が設定されている場
るサポートがホスト システムにないとき 合 ) の後では W に設定される。
に行われます ) ときは W に設定される。
7 番目
アプリケーションが副次モードで稼働し
ているデータベース サーバに接続してい
るときは W に設定される。このデータ
ベース サーバはデータ レプリケーション
ペアの副サーバである ( つまり、このサー
バは、読取り操作にのみ使用可能 )。
問合せ処理中にデータ フラグメント
(dbspace) がスキップされたとき (DATASKIP
機能がオンに設定されているとき ) は W に設
定される。
8 番目
クライアント DB_LOCALE がデータベー
ス ロケールに一致しないときは W に設
定される。詳細は、
『Guide to GLS
Functionality』を参照。
予約済み。
(2/2)
SQLERRM 文字配列
SQLERRM 文字配列は、表の名前などの変数を含む、71 文字の配列で、エラー メッ
セージに入っています。一部の、ネットワーク化されたアプリケーションの場合に
は、この配列に、ネットワーキング ソフトウェアによって生成されたエラー メッ
セージが含まれています。
SQLSTATE 値
INFORMIX-ESQL/C などの Informix 製品では、X/Open と ANSI SQL 標準準拠の
SQLSTATE 値がサポートされます。GET DIAGNOSTICS 文は、SQL 文が実行され
た後 SQLSTATE 値を読み込んで、エラーを診断します。データベース サーバは結
果コードを 5 文字の文字列で返し、この文字列は SQLSTATE 変数に格納されます。
SQLSTATE エラー コード、すなわち値は、最後に実行された SQL 文に関する次の
情報を示します。
■
文の実行は成功した。
■
文の実行は成功したが、警告が生成された。
■
文の実行は成功したが、データが生成されなかった。
■
文の実行が失敗した。
SQL を使用したプログラミング 5-13
単一行の抽出
GET DIAGNOSTICS 文、SQLSTATE 変数、SQLSTATE リターンコードの意味につ
いての詳細は、
『Informix Guide to SQL: Syntax』を参照してください。
ヒント : Informix 製品で GET DIAGNOSTICS と SQLSTATE がサポートされている場
合は、Informix は、エラーの検出、処理、診断のための主構造体としてこれらを使
用することをお薦めします。SQLSTATE の使用により、複数のエラーを検出でき
ます。SQLSTATE は ANSI 標準準拠です。
単一行の抽出
埋込み SELECT 文を使用すると、データベースから 1 行を抽出して、ホスト変数に
代入することができます。SELECT 文が 2 行以上のデータを返す場合は、プログラ
ムはもっと複雑な方法を使用して、一度に複数行を取り出さなければなりません。
複数行の選択に関する操作は、5-20 ページの「複数行の抽出」で説明します。
1 行のデータを抽出する場合は、SELECT 文をプログラム中に埋め込むだけで済み
ます。次の例は、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/94') );
この文が第 2 章「簡単な SELECT 文の作成」や第 3 章「高度な SELECT 文の作成」
の例と異なるのは、INTO 節が追加されている点です。INTO 節には、SQL 文から
のデータを受け取るホスト変数を指定します。
埋込み SELECT 文が実行されると、データベースサーバは問合せを実行します。こ
の例の SELECT 文は集計関数が返す値を結果とするため、生成されるデータは 1 行
です。この行は 1 列のみで構成され、列の値は avg_price という名前のホスト変数
に格納されます。この SELECT 文以降のプログラムソース内の行で、このホスト変
数の値を使用できます。
5-14
Informix Guide to SQL: Tutorial
データ型変換
この種の文を使用すると、単一行のデータを抽出してホスト変数に代入することが
できます。その単一行は、必要な数の列をもつことができます。問合せにより、複
数行のデータが生成された場合には、データベース サーバはデータを返すことがで
きません。代わりに、エラー コードを返します。
INTO 節に指定するホスト変数の数は、必ず選択対象の並びで指定する項目の数と
同じにしてください。ホスト変数の数と選択対象の並びの項目の数が一致しない場
合は、データベースサーバはできるだけ多くの値を返し、SQLWARN の 4 番目の
フィールドに警告フラグを設定します。
データ型変換
次の例は、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 文で使用されている各ホスト変数のデータ型は、その文と一緒にデータベース
サーバに渡されます。データベースサーバは、列の値をできるだけその受取り先の
ホスト変数のデータ型に変換します。可能な限りの変換が実行されますが、一部の
変換では精度が落ちます。この例の結果は、ホスト変数のデータ型によって、次の
ように変わります。
SQL を使用したプログラミング 5-15
NULL データの処理
データ型
結果
実数 (FLOAT) 型
データベースサーバは 10 進数 (DECIMAL) 型の結果を実数
(FLOAT) 型に変換します。その際に、端数の桁がいくつか
切り捨てられることがあります。
10 進数の値が実数型で表現可能な最大値を超える場合はエ
ラーが返されます。
整数 (INTEGER) 型
データベースサーバは結果を整数 (INTEGER) 型に変換しま
す。その際に、必要に応じて端数の桁を切り捨てます。
変換後の数値の整数部が大きすぎてホスト変数に収まらな
い場合はエラーが返されます。
文字 (CHARACTER) 型
データベースサーバは、10 進数値を文字列に変換します。
文字列が長すぎてホスト変数に収まらない場合は、文字列
の一部が切り捨てられます。SQLWARN の 2 番目のフィー
ルドが W に設定され、SQLSTATE 変数の値が 01004 にな
ります。
NULL データの処理
プログラムが抽出した値が NULL の場合はどうなるでしょうか。NULL はデータ
ベースに格納できますが、プログラミング言語がサポートするデータ型は NULL を
認識しません。プログラムは何らかの方法で NULL を識別して、NULL がデータと
して処理されるのを防がなければなりません。
SQL API で NULL の識別に使用されるのが標識変数です。標識変数は特別なホスト
変数で、NULL を受け取る可能性があるホスト変数と組み合わせて使用されます。
主変数にデータを入れるとき、データベースサーバはその変数が NULL かどうかを
示す特別な値を標識変数に入れます。次の INFORMIX-ESQL/C 例では、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);
5-16
Informix Guide to SQL: Tutorial
エラーの処理
その値が NULL の可能性があるため、op_d_ind という名前の標識変数がホスト変数
に関連付けられています。この標識変数は、プログラム内の任意の行で short int 型
として宣言されていなければなりません。
SELECT 文の実行後に、標識変数の値が負かどうかが検査されます。負の値 ( 通常
は -1) は主変数に抽出された値が NULL であることを示します。この変数が NULL
負の場合は、ESQL/C ライブラリ関数を使用して、ホスト変数にデフォルト値を割
り当てます。(rstrdate 関数は INFORMIX-ESQL/C 製品の一部です。)
標識変数をホスト変数に関連付ける構文は、プログラミング言語によって異なりま
すが、ここで説明した原理はどの言語でも同じです。
エラーの処理
データ型間の変換はデータベースサーバが自動的に処理しますが、SELECT 文には
問題が起こる可能性がまだいくつかあります。SQL プログラミングでは、他のプロ
グラムと同様に、このような状況に備えてエラーの発生を予測し、エラーに対し万
全の対策を講じる必要があります。
データの終り
よく起こることの一つに、問合せがまったく行を返さないことがあります。結果が
返らなかったことは、SELECT 文の実行後に SQLSTATE に 02000 が設定され、
SQL-CODE に 100 が設定されることから判断されます。このコードはエラーか単
に行が存在しないことを示します。どちらを示すかはアプリケーションによって判
断しなくてはなりません。たとえば、別の表から取り出したばかりのキー値を使用
して行を読み込んでいるときのように、行が存在しなければならないことがはっき
りしている場合、データの終わりを示すコードはプログラムの論理に重大な障害が
あることを示しています。これに対し、ユーザが入力した値や、プログラムより信
頼性の少ないソースを基に行を選択している場合、データがなくてもエラーではあ
りません。
SQL を使用したプログラミング 5-17
エラーの処理
ANSI 標準準拠でないデータベースのデータの終り
データベースが ANSI 標準に準拠していない場合、データの終りを示すリターン
コード 100 が SQLCODE に設定されるのは SELECT 文の実行後のみです。また、
(INSERT 文、UPDATE 文、DELETE 文
SQLSTATE の値は 02000 に設定されます。
などの SELECT 文以外の文の場合は、何行がその文の影響を受けたかが SQLERRD
の 3 番目の要素に設定されます。これについては、第 6 章「SQL プログラムによる
データの更新」で説明します。
)
重大なエラー
SQLCODE に負の値が設定されたり、SQLSTATE に 00、01、02 以外の値で始まる
値が設定されたときのエラーは、多くの場合重大なエラーです。こうしたエラー
が、開発したプログラムや製品上報告されたことはごく稀です。しかし、ごく稀な
ことだからといって、無視することはできません。
たとえば、
「指定された表がデータベースにない」という意味の -206 というエラー
コードが返ってきたとします。このエラーが発生するのは、プログラムが作成され
てから後に誰かが表を削除した場合、あるいは論理エラーもしくは入力ミスによ
り、プログラムが間違ったデータベースをオープンした場合です。
集計関数とデータの終り
SUM、MIN、または AVG などの集計関数を使用する SELECT 文は、WHERE 節の
条件を満たす行がない場合でも、最低データの 1 行を必ず正しく返します。条件を
満たす行がない場合の集計関数の値は NULL となりますが、NULL は値と見なされ
ます。
5-18
Informix Guide to SQL: Tutorial
エラーの処理
条件を満たす行が 1 行以上あり、それらすべての行に NULL が入っている場合も、
集計関数の値は NULL になります。条件を満たす行がない集計関数、および条件を
満たす行が 1 行以上あり、それらすべての行に NULL が入っている集計関数を区別
する場合には、SELECT 文に 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 */
この例は、状態に応じて次のように処理します。
■
NULL でない行が 1 行以上選択された場合は、正しい値が返されて、それが
使用されます。この結果はもっとも頻繁に発生すると思われます。
■
1 行も選択されなかった場合や、NULL が許されない列 total_price の値に
NULL の行だけが選択された場合は、標識変数が設定され、デフォルト値
が割り当てられます。
■
重大なエラーが発生した場合は、ホスト変数の値は最初に指定したデフォ
ルト値のまま変わりません。プログラムのこの箇所では、プログラマはこ
のようなエラーをトラップし、報告する必要はありません。
SQL を使用したプログラミング 5-19
複数行の抽出
複数行の抽出
問合せによって返される行が 2 行以上になる可能性がある場合は、プログラム中の
問合せの実行方法を変えなければなりません。複数行を返す問合せは 2 段階で処理
されます。まず、プログラムが問合せを開始します。
(すぐに返されるデータはあ
りません。
)次に、プログラムが一度に 1 行ずつデータを要求します。
これらの操作は、カーソルと呼ばれる特別のデータオブジェクトを使用して行われ
ます。カーソルは、問合せの現行状態を表すデータ構造体です。通常のプログラム
の操作の流れは、次のようになります。
1.
プログラムが、カーソルとそれに関連付けられた SELECT 文を宣言しま
す。この段階ではカーソルのための記憶域が割り当てられるのみです。
2.
プログラムがカーソルをオープンします。これにより、カーソルと関連付
けられた SELECT 文の実行が始まります。SELECT 文の実行中にエラーが
発生すればそれが報告されます。
3.
プログラムが、1 行のデータを取り出して、ホスト変数に代入して処理し
ます。
4.
最後の行が取り出された後で、プログラムがカーソルをクローズします。
5.
カーソルが不要になると、プログラムはカーソルを解放して、使用するリ
ソースを再度割り当てます。
これらの操作は DECLARE 文、OPEN 文、FETCH 文、CLOSE 文、および FREE 文
の 5 つの文によって実行されます。
カーソルの宣言
DECLARE 文はカーソルの宣言に使用します。DECLARE 文はカーソルを命名し、
その用途を指定し、カーソルを文と関連付けます。次に、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 文と関連付けてい
ます。( 第 6 章「SQL プログラムによるデータの更新」に、カーソルを INSERT 文
とも関連付ける方法が説明されています。)
5-20
Informix Guide to SQL: Tutorial
カーソルのオープン
この例の SELECT 文には INTO 節が含まれています。INTO 節は、データを受け取
る変数を指定します。5-23 ページの「INTO 節の設定」で説明しているように、値
を受け取る変数を指定するために FETCH 文を使用することもできます。
DECLARE 文は、データベースに対する操作を行うものではなく、カーソルの機能
を確立し、カーソルに記憶域を割り当てる文です。この例のカーソルを使用する
と、表 items の行を始めから終わりまで 1 回読み込むことができます。カーソルの
宣言方法によっては順方向にも逆方向にも読み込むことができます。詳細は、5-23
ページの「カーソルによる取出し」を参照してください。このカーソルは、
FORUPDATE 節を指定して宣言されていないため、おそらくデータの取出しにのみ
使用され、データの変更には使用されません。データの修正にカーソルを使用する
方法については、第 6 章「SQL プログラムによるデータの更新」で説明します。
カーソルのオープン
カーソルの使用準備がでると、カーソルをオープンします。OPEN 文がカーソルを
動作状態にします。このとき、カーソルに関連付けられた SELECT 文がデータベー
スサーバに渡され、データベースサーバは一致する行の探索を始めます。データ
ベースサーバは、表の最初の行が見つかるか構築されるまで問合せを処理します。
この問合せは実際にデータの行を返しませんが、SQL API について SQLSTATE に、
INFORMIX-4GL と SQL API について SQLCODE にリターンコードを設定します。
次の例は、ESQL/C での OPEN 文を示しています。
EXEC SQL OPEN the_item
OPEN 文が実行されるとき初めて、データベースサーバが問合せを認識するため、
OPEN 文の実行時にエラーが検出される可能性があります。カーソルをオープンし
た後に、必ず SQLSTATE または SQLCODE をチェックしてください。SQLSTATE
の値が 02000 より大きいか、SQLCODE に負の数が含まれている場合、カーソルを
使用できません。SELECT 文にエラーがあるか、あるいは他の問題が発生したため
にデータベースサーバが SELECT 文を実行できない状態になっています。
SQLSTATE の値が 0 であるか、SQLCODE に 0 が含まれている場合は、SELECT 文
の構文は有効で、カーソルは使用可能です。ただし、この時点ではカーソルが行を
生成するかどうかはわかりません。
SQL を使用したプログラミング 5-21
行の取出し
行の取出し
プログラムは FETCH 文を使用して、表の各行を抽出します。FETCH 文はカーソル
を命名し、データを受け取るホスト変数も命名します。次に、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 に設定された場合も、WHILE
節の条件によりループが停止します。ただし、SQLCODE の値は、ループの内部で
も検査されています。この検査が必要なのは、SELECT 文が有効でも一致する行が
見つからない場合があるからです。このとき、OPEN 文は 0 を返しますが、最初の
FETCH 文は 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
while(SQLCODE == 0)
{
printf("%d, %d, %d", o_num, i_num, s_num);
EXEC SQL FETCH the_item;
}
このように記述し直すと、返される行が存在しない場合が先に処理されるため、2
回目の SQLCA の検査を行う必要はありません。SQLCODE はループ内に存在しま
す。ただし、このように書き直しても、測定には現れない程度の性能の差しかあり
ません。SQLCODE の検査に要する時間コストは、FETCH 文のコストに比べごくわ
ずかに過ぎません。
5-22
Informix Guide to SQL: Tutorial
カーソルによる取出し
INTO 節の設定
INTO 節には、データベースサーバが返すデータを受け取るホスト変数を指定しま
す。INTO 節は、SELECT 文または FETCH 文のどちらかに指定しなければなりませ
ん。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);
}
このフォームによって、別々の行を別々の配置に取り出すことができます。たとえ
ば、このフォームを使用すると、連続する行を配列内の連続する要素に取り出すこ
とができます。
カーソルによる取出し
データの取出しのため、カーソルは順カーソルかスクロールカーソルとして動作し
ます。順カーソルが取り出すことができるのは、カーソルが置かれている位置の次
の行のみです。したがって、順カーソルはオープンされるたびに表を一回通して読
み込むことしかできません。スクロールカーソルは、次の行だけでなく、カーソル
より前にある任意の行を取り出すことができます。したがって、行を何回でも読み
込むことができます。次の例は、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;
順次取出しを行うたびに、新しい行が 1 行返されます。
SQL を使用したプログラミング 5-23
カーソルのアクティブセット
次の INFORMIX-ESQL/C の例で示しているように、スクロールカーソルの宣言は、
キーワード SCROLL CURSOR を使用して行います。
EXEC SQL DECLARE s_curs SCROLL CURSOR FOR
SELECT order_num, order_date FROM orders
WHERE customer_num > 104
スクロールカーソルを宣言した場合、FETCH 文のさまざまなオプションが使用で
きます。例えば ABSOLUTE オプションは、取り出す行の絶対位置を指定します。
EXEC SQL FETCH ABSOLUTE :numrow s_curs
INTO :nordr, :nodat
この文が取り出す行は、ホスト変数 numrow にその位置を指定されている行です。
いま取り出した行をもう一度取り出すこともでき、また、選択された複数の行を最
初の行から再び走査することもできます。ただし次の節で説明するように、これら
の機能を使用すると効率が低下します。スクロールカーソルに適用する追加オプ
ションについては、
『Informix Guide to SQL: Syntax』の FETCH 文の説明を参照して
ください。
カーソルのアクティブセット
オープンされたカーソルは、選択された一群の行を表します。問合せが生成する行
の集合は、カーソルのアクティブセットと呼ばれます。アクティブセットを特定の
条件を満たす行の集合、カーソルをその集合の 1 行を指すポインタと考えてくださ
い。同じデータを並行して変更するプログラムが他にない場合には、このようなモ
デル化は誤りではありません。
アクティブセットの作成
カーソルがオープンされるとデータベースサーバは、選択されたデータの最初の行
を見つけようとします。簡単に見つかるか、それともかなりの作業と時間を要する
かは問合せの種類やデータの状況により異なります。次のカーソルの宣言について
考えてみます。
EXEC SQL DECLARE easy CURSOR FOR
SELECT fname, lname FROM customer
WHERE state = 'NJ'
5-24
Informix Guide to SQL: Tutorial
カーソルのアクティブセット
このカーソルは、一つの表に対し簡単な問合せを行うものです。データベースサー
バは、問合せの条件を満たす行が存在するかどうかを非常に早く知ることができ、
最初の行をすぐに見つけます。この時点でデータベースサーバが見つける行は最初
の 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
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 行だけ保持
すれば解決します。データベースサーバは、FETCH 文が実行されるたびに現行行
の内容を返し、次の行を見つけます。
スクロールカーソルのアクティブセット
スクロールカーソルのアクティブセットの行は、カーソルがクローズされるまです
べて保持しておかなければなりません。すべての行を保持しておかなければならな
いのは、どの行をプログラムから要求されるか予測できないからです。
SQL を使用したプログラミング 5-25
カーソルのアクティブセット
データベースサーバは多くの場合、スクロールカーソルのアクティブセットを一時
表として実行します。ただし、問合せの処理のために一時表を作成する場合は別と
して、一時表をすぐに生成しないこともあります。通常はカーソルがオープンされ
るときに一時表が作成されます。データベースサーバは行を取り出すと、その行を
一時表にコピーし、プログラムに返します。同じ行が 2 度目に取り出されるときは
一時表からその行を取り出すことができます。この方法を用いると、すべての行を
取り出す前にプログラムが問合せを放棄した場合のリソースが最小になります。取
り出されない行が作成されたり、保存されたりすることはありません。
アクティブセットと並列度
データベースサーバにアクセスしているプログラムが一つのみの場合は、アクティ
ブセットを構成する行が変化してしまうことはありません。これは、ほとんどの
パーソナルコンピュータに当てはまるもっとも単純な状況です。しかし、多重プロ
グラミングシステム用に設計しなければならないプログラムもあります。多重プロ
グラミングシステムでは、数個あるいは数十個の異なるプログラムが、同じ表を同
時に処理することが考えられます。
あるプログラムのカーソルがオープンしているときに、他のプログラムがそのカー
ソルの表を更新する可能性がある場合には、アクティブセットの概念は信頼性が高
いとはいえません。表のすべての行が変化していても、プログラムが見ることがで
きるのは一度に一行のデータのみです。
アクティブセットの 1 行のみがデータベースサーバに保持されるような問合せの場
合、他の行は変更される可能性があります。また、プログラムが 1 行を取り出した
直後に、別のプログラムがその行を削除したり更新したりすると、その行はもはや
アクティブセットにはないかもしれません。
アクティブセットの全体、あるいはその一部が一時表に保存されている場合には、
データの失効という問題が起こります。アクティブセットの元となった表の行が変
更される可能性がある、という問題です。元の表が変わっても、アクティブセット
を構成している行のなかには、現在の表の内容が反映されないものもあります。
プログラムのデータを読み込みだけの場合、データの失効は問題になりません。ア
クティブセットは、一時点におけるデータの断片です。行の変更が翌日あるいはミ
リ秒後でも問題はありません。したがって、プログラムの実行中に発生した変化と
プログラムが終了する間際に適用される変化との間には実際的な差はありません。
5-26
Informix Guide to SQL: Tutorial
カーソルの使用方法 : 部品爆発
データの失効が問題になるのは、プログラムが入力データを使用して同じデータ
ベースを変更しようとする場合のみです。たとえば、銀行業務のアプリケーション
が勘定残高をデータベースから読み込んで変更し、変更済みのデータを同じデータ
ベースに書き込む場合がこれにあたります。データを変更するプログラムについて
は、第 6 章「SQL プログラムによるデータの更新」で説明します。
カーソルの使用方法 : 部品爆発
カーソルとプログラムロジックを組み合わせることにより、SQL だけでは解決でき
ない問題を解決できます。このような問題の一つが、材料目録処理とも呼ばれる部
品爆発です。この問題で重要となるのは、オブジェクト同士の再帰的関係です。再
帰的関係とは、オブジェクトは他のオブジェクトを含むことができ、そのオブジェ
クトもさらに他のオブジェクトを含むことができるという関係です。
例として、メーカーの在庫を取り上げます。さまざまな部品を製造している会社が
あると仮定します。部品には、それだけでできている独立した部品と、他の部品が
集まってできる組み立て品目があります。
これらの関係を一つの表に記述します。この表の名前が目録だとします。表目録の
列親部品には、組立て品 ( 親 ) の部品番号が格納されます。列子部品には、親の 1
要素である部品の部品番号が格納されます。部品番号が #123400 の部品が 9 個の部
品からなる組立て品の場合、最初の列には 123400、2 番目の列には子の部品番号が
格納された行が 9 行存在することになります。図 5-5 に、#123400 の部分を表す行
を示します。
図 5-5
部品爆発問題
表目録
親部品
子部品
FK NN
FK NN
123400
432100
432100
765899
SQL を使用したプログラミング 5-27
カーソルの使用方法 : 部品爆発
ここで部品爆発問題が発生します。一つの部品番号があると、この部品の構成要素
であるすべての部品のリストが作成されます。次に、INFORMIX-ESQL/C でのこの
問題の一つの解決策を示します。
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;
next_to_do += 1;
}
return (next_free - 1);
}
専門用語では、表 contains の各行は、方向をもつ非周期グラフ、つまりツリーの
ヘッド ノードです。関数は、ツリーの横方向優先探索を実行します。ツリーのルー
トは関数のパラメータとして渡される部品番号です。関数は、part_scan という名前
のカーソルを使用して、すべての行を、列 parent に特定の値が指定された状態で返
します。一番内側の while ループは part_scan カーソルをオープンして、選択セット
内の各行を取り出し、各コンポーネントの部品番号が抽出されたときにカーソルを
クローズします。
上記の関数は、部品爆発問題の核心部を処理しますが、完全な解決策ではありませ
ん。たとえば、ツリーの複数のレベルに現れるコンポーネントでは使用できませ
ん。さらに、実際の表目録には各親部品に使用されている子部品の数をカウントす
る列カウントもあります。各要素部品の総カウント数を返すプログラムは、さらに
複雑になります。
5-28
Informix Guide to SQL: Tutorial
動的 SQL
前述した繰返し処理型のアプローチは、部品爆発問題を解決する唯一の方法ではあ
りません。世代の数に一定の制限がある場合は、入れ子になった外部セルフ結合を
使用する SELECT 文を一つ使用すると、この問題を解決できます。
トップレベルの部品に最大で 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 節ではどの列を検査するのか、
選択対象の並びにはどの列を指定するのかをプログラム中に記述しなければなりま
せん。
事前に十分に定義された特定のタスクを実行するプログラムを作成するのなら、こ
れで十分です。しかし、事前に完全には定義できないデータベース操作を行うプロ
グラムもあります。特に、ユーザの要求に対話的に応えなければならないプログラ
ムの場合、ユーザからの入力に応じて SQL 文を作成することが必要になります。
SQL を使用したプログラミング 5-29
文の PREPARE 文による処理
動的 SQL の場合は、プログラムの実行中にを実行できるため、SQL 文の内容を
ユーザからの入力により決定できます。この動作は、次の手順で実行されます。
1.
プログラムは、SQL 文のテキストをプログラム変数に格納される文字列と
して作成する。
2.
プログラムは PREPARE 文を実行する。PREPARE 文はデータベースサー
バに対し、SQL 文のテキストを調べることと、そのテキストを実行できる
ように準備することを要求する。
3.
プログラムは、PREPARE 文で処理された SQL 文を、EXECUTE 文を使用
して実行する。
この方法を用いると、あらゆる種類のユーザ入力を基にして SQL 文を構築し実行
することができます。たとえば、SQL 文のファイルを読み込み、各 SQL 文を処理
して実行するプログラムが考えられます。
DB-Access は SQL を対話的に実行するユーティリティで、SQL 文の構築、処理、実
行を動的に行う INFORMIX-ESQL/C プログラムです。たとえば、DB-Access によっ
て、簡単な対話型メニューを使用して表の列を指定することができます。ユーザが
メニューの指定を終えると、DB-Access は必要な CREATE TABLE 文か ALTER
TABLE 文を動的に作成して、それを処理し実行します。
文の PREPARE 文による処理
動的 SQL 文も、構文的には静的 SQL 文とほとんど同じです。ただ一つの違いは、
動的 SQL 文にはホスト変数の名前を記述することができない点です。
動的 SQL 文によって次の二つの制限が生じます。第一に、動的 SQL 文が SELECT
文の場合、SELECT 文に INTO 節をインクルードすることができません。INTO 節
には列のデータを収めるホスト変数を指定しますが、ホスト変数の使用は、動的文
では許可されていません。第二に、式の内部でホスト変数の名前を使用する場所に
は、位置指定子として疑問符 (?) を記述しなければなりません。
このフォームの文を PREPARE 文で処理する例を次に示します。この例は、
INFORMIX-ESQL/C で記述されています。
EXEC SQL prepare query_2 from
'select * from orders
where customer_num = ? and
order_date > ?';
5-30
Informix Guide to SQL: Tutorial
PREPARE 文で処理された SQL 文の実行
この例の二つの疑問符は、文が実行されると、ホスト変数の値がこれらの二つの場
所で使用されることを示しています。
ほとんどの SQL 文は、PREPARE 文で動的に処理できます。PREPARE 文で処理で
きない SQL 文は、PREPARE 文自体や OPEN 文などの、動的 SQL やカーソル管理
に直接関係する文だけです。UPDATE 文や DELETE 文を PREPARE 文で処理した
後は、SQLWARN の 5 番目のフィールドを検査して、WHERE 節を使用したかどう
かを調べてください。5-11 ページの「SQLWARN 配列」を参照してください。
SQL 文を PREPARE 文で処理した結果は、その文を表すデータ構造体になります。
このデータ構造体は、その文を生成した文字列と同じではありません。PREPARE
文の内部でデータ構造体に名前を付けます。前の例の場合は query_2 がデータ構造
体の名前です。この名前は、PREPARE 文によって処理された SQL 文を EXECUTE
文で実行するときに使用されます。
PREPARE 文で処理する文字列には、複数の SQL 文を含めることができます。複数
の SQL 文を並べる場合は、セミコロン (;) で区切ります。次に、
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 文以外の SQL 文と 1 行だけ返す SELECT 文は、EXECUTE 文を使用して実
行します。
次の INFORMIX-ESQL/C のコードは、銀行の帳簿を更新する複数の SQL 文を処理
し実行する 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);
SQL を使用したプログラミング 5-31
動的なホスト変数
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 文 ( あるいは EXECUTE PROCEDURE 文 ) が 1 行のみを返す場合、
EXECUTE 文の INTO 節を使用して値を受け取るホスト変数を指定できます。
動的なホスト変数
動的に割り当てられたデータオブジェクトをサポートする SQL API では、動的文を
もう 1 段高いレベルで使用することができます。これによって、列データを受け取
るホスト変数を動的に割り当てることができます。
変数の動的割当てによって、任意の SELECT 文をプログラム入力から取り出して、
この SELECT 文が生成する値の個数とデータ型を判断して、これらのデータを保持
する適切なデータ型のホスト変数を割り当てることができます。
このようなことを実現するために中心的な役割を果たすのが DESCRIBE 文です。
DESCRIBE 文は、PREPARE 文によって処理された文の名前を受け取り、その文に
関する情報を返します。また、SQLCODE を設定して、その文がどの動詞で始まっ
ているかを示します。PREPARE 文によって処理された文が SELECT 文の場合には
DESCRIBE 文は選択された出力データに関する情報も返します。PREPARE 文に
よって処理された文が INSERT 文の場合には、DESCRIBE 文は入力パラメータに関
する情報を返します。DESCRIBE 文によって情報を返されるデータ構造体は、この
目的のために割り当てられ、システム記述子領域として知られている、あらかじめ
定義されたデータ構造体です。INFORMIX-ESQL/C を使用している場合は、システ
ム記述子領域あるいは sqlda 構造体を使用することができます。
5-32
Informix Guide to SQL: Tutorial
PREPARE 文で処理された文が所有する記憶域の解放
DESCRIBE 文が SELECT 文に対し返すか参照するデータ構造体には、構造体の配列
が含まれています。各構造体は、SELECT 文の選択対象の並びの各項目に対し、返
されるデータに関する情報を提供します。たとえば、プログラムはこの一連の構造
体を調べ、返されるデータが 10 進数値とある長さの文字値、そして整数からなる
ことを知ることができます。
この情報を使用すると、プログラムは抽出された値を格納するための記憶域をメモ
リに割り当て、データベースサーバに送るデータ構造体に記憶域を指すポインタを
設定することができます。
PREPARE 文で処理された文が所有する記憶域の解放
PREPARE 文によって処理された SQL 文はメモリ内の領域を占有します。一部の
データベースサーバでは、この SQL 文がプログラム側の領域だけでなく、データ
ベースサーバの領域も占有することがあります。SQL 文が占有する領域は、プログ
ラムが終了するときに解放されますが、終了時よりも前に解放することが必要にな
る場合があります。
この領域を解放するには FREE 文を使用します。FREE 文には文の名前か、文に対
して宣言されたカーソルの名前を指定し、FREE 文は PREPARE 文で処理された文
に割り当てられた領域を解放します。一つの文に複数のカーソルが定義されている
場合、文を解放してもカーソルは解放されません。
実行の高速化
カーソルやホスト変数を必要としない単純な文の場合は、PREPARE 文、EXECUTE
文、FREE 文の処理をまとめて 1 回で行うことができます。次の例は、EXECUTE
IMMEDIATE 文が一つの操作で文字列を取り、PREPARE 文で処理して実行し、記
憶域を解放する方法を示しています。
EXEC SQL execute immediate 'drop index my_temp_index';
EXECUTE IMMEDIATE 文には、単純な SQL 操作は簡単に書くことができますが、
USING 節は使用できません。このため、SELECT 文に対しては EXECUTE
IMMEDIATE 文は使用できません。
SQL を使用したプログラミング 5-33
プログラム中のデータ定義文
プログラム中のデータ定義文
データベースの作成や表の定義の変更を行うような SQL 文、すなわちデータ定義
文は通常、プログラム中には記述されません。プログラム中に記述することがほと
んどないのは、データ定義文はまれにしか実行されないためですが、問合せやデー
タの変更は何回も行われます。データベースは 1 回作成されますが、問合せや更新
は何回も行われます。
データベースとその表の作成は、通常は、DB-Access やリレーショナルオブジェク
トマネージャを使用して対話的に行われます。これらのツールには SQL 文の入っ
たファイルが含まれているため、データベースの作成をオペレーティングシステム
のコマンド一つで行うことが可能です。データ定義文については、
『Informix Guide
to SQL: Syntax』と『Informix Guide to Database Design and Implementation』に記載して
あります。
GRANT 文と REVOKE 文の埋込み
データ定義に関する作業で、アクセス権の付与と取消しは比較的頻繁に行われる作
業です。アクセス権の付与と取消は繰り返し行われる作業で、SQL に不慣れな人が
行う可能性もあります。このため、GRANT 文と REVOKE 文をプログラムにパッ
ケージしたほうがユーザにとっては使用しやすくなります。
GRANT 文と REVOKE 文は、動的 SQL としての扱いに特に適しています。どちら
の文も、次のようなパラメータを取ります。
■
アクセス権の並び
■
表名
■
ユーザ名
これらの値の一部はユーザやコマンド行パラメータ、あるいはファイルなどのプロ
グラムへの入力を基に指定することが必要になります。しかし、これらの値はどれ
も、ホスト変数の形式で指定することはできません。GRANT 文と REVOKE 文の構
文ではホスト変数が使用できません。
ホスト変数を使用することができないため、方法は一つしかありません。文の各部
分を集めて文字列として文をアセンブルし、その文を PREPARE 文で処理して実行
する方法です。プログラム入力は、PREPARE 文で処理する文に文字列として組み
込むことがでます。
5-34
Informix Guide to SQL: Tutorial
GRANT 文と REVOKE 文の埋込み
次の INFORMIX-ESQL/C 関数は、関数パラメータから GRANT 文をアセンブルし、
PREPARE 文で処理して EXECUTE 文で実行します。
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;
SQL を使用したプログラミング 5-35
GRANT 文と REVOKE 文の埋込み
次の例に示されているとおり、GRANT 文は、その定数部分と関数パラメータを連
結して作成されます。
sprintf(grant_stmt, " GRANT %s ON %s TO %s",priv_to_grant, table_name, user_id);
この文は、次の 6 個の文字列を連結しています。
■
'GRANT'
■
付与されるアクセス権を指定するパラメータ
■
'ON'
■
表名を指定するパラメータ
■
'TO'
■
ユーザを指定するパラメータ
この結果、一部がプログラム入力で構成された、完全な 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 文が
実行されます。
5-36
Informix Guide to SQL: Tutorial
まとめ
まとめ
SQL 文をプログラミング言語の通常の文と同じように扱って、プログラム中に埋め
込むことができます。プログラム変数を WHERE 節で使用したり、データベースか
ら取り出したデータをプログラム変数に代入したりすることができます。プリプロ
セッサは、SQL コードをプロシジャ呼出しとデータ構造体に変換します。
データを返さない文や 1 行のデータしか返さない問合せは、プログラミング言語の
通常の文と同じように書くことができます。複数の行を返す可能性のある問合せ
は、現行行のデータを表すカーソルと関連付けられます。プログラムはカーソルを
使用して、必要なデータを 1 行ずつ取り出すことができます。
静的 SQL 文は、プログラムのテキストとして書き込まれます。プログラムの実行
時に SQL 文を動的に生成して実行することも可能です。さらに、問合せがどのよ
うなデータ型の列をいくつ返すかを調べ、それらを格納するためのメモリ領域を動
的に割り当てることができます。
SQL を使用したプログラミング 5-37
第6章
SQL プログラムによるデータ
の更新
DELETE 文の使用方法 . . . . . . .
直接的な削除 . . . . . . . .
直接的な削除の途中で発生するエラー
トランザクションログ機能の使用方法
一元化された削除 . . . . . .
カーソルを使用した削除 . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6-3
6-4
6-4
6-5
6-6
6-7
INSERT カーソルの使用方法 . . . . . . .
INSERT カーソルの使用方法 . . . . . .
INSERT カーソルの宣言 . . . . . .
カーソルを使用した挿入 . . . . . .
PUT 文と FLUSH 文の実行後の状態コード .
定数だけで構成される行の挿入 . . . . .
挿入の例 . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6-9
6-9
6-9
6-10
6-11
6-12
6-12
UPDATE 文の使用方法 . . . . . . . .
UPDATE カーソルの使用方法 . . . . .
キーワード UPDATE の目的 . . . .
特定の列の更新. . . . . . . .
キーワード UPDATE は常に必要ではない
表の仕上げ . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6-15
6-15
6-16
6-16
6-16
6-17
. .
6-18
まとめ . . .
. . .
. .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
. . .
. . .
. . .
6-2
Informix Guide to SQL: Tutorial
第 5 章では、SQL 文、特に SELECT 文を他の言語で書いたプログラムに埋め込むと
いう考え方を説明しました。SELECT 文を内部に埋め込むと、プログラムはデータ
ベースからデータを抽出することができるようになります。
この章では、プログラムの内部に埋め込んだ SQL 文で、表の行を削除、挿入、更
新してデータベースを変更する際に発生する問題を説明します。第 5 章「SQL を使
用したプログラミング」の場合と同様、この章では、Informix の埋込み言語のマニュ
アルを読めるようにします。
INSERT 文、UPDATE 文および DELETE 文の一般的な使用方法は、第 4 章「データ
の更新」で説明しました。この章では、これらの文をプログラム内部で使用する方
法を説明します。これらの文をプログラムの内部に埋め込むこと自体は簡単です
が、エラーを処理したり、複数のプログラムから同時に実行されるデータ変更操作
を扱ったりするのは、場合によっては非常に複雑になります。
DELETE 文の使用方法
表内の行を削除するために、プログラムは DELETE 文を実行します。DELETE 文に
よって、WHERE 節の条件を満たす行を削除したり、カーソルを使用して取り出さ
れた現行の行を削除したりすることができます。
行を削除するときはつねに、その行に依存している行が他の表にないかを確認しな
ければなりません。削除する行と関係を持つ行が他の表にある場合の問題は、第 4
章「データの更新」で説明しました。この問題は、プログラムの内部から削除を行
う場合にも起こります。
SQL プログラムによるデータの更新
6-3
直接的な削除
直接的な削除
プログラムの内部に DELETE 文をそのまま埋め込むことができます。次の例は、
INFORMIX-ESQL/C を使用しています。
EXEC SQL delete from items
where order_num = :onum;
これと同じ書式の文を動的に処理し、実行することもできます。どちらの場合も、
文はデータベースに直接作用して、表の何行かに影響を与えます。
この例の DELETE 文の WHERE 節では、onum というホスト変数の値を使用してい
ます。削除が終わると、結果が普通に SQLSTATE と sqlca 構造体に設定されます。
配列 SQLERRD の 3 番目の要素の値は、エラーが発生した場合も削除した行の数を
示しています。SQLCODE の値は、処理が成功したかどうかを示しています。この
値が負ではない場合は、エラーは発生していません。この場合、SQLERRD の 3 番
目の要素の値は、WHERE 節の条件を満たして削除された行の総数を示しています。
直接的な削除の途中で発生するエラー
エラーが発生すると、DELETE 文は途中で終了します。エラーの原因と削除された
行数は、SQLSTATE と SQLCODE の値および SQLERRD の 2 番目の要素の値から
わかります。多くのエラーでは、データベースサーバが処理を開始する前にエラー
が検出されるため、SQLERRD の 2 番目の要素の値はゼロ (0) です。たとえば、存在
しない表を指定した場合や、WHERE 節で指定した列の名前が変更されているよう
な場合は削除はまったく行われません。
削除が始まって何行かが処理されてから見つかるエラーもあります。このようなエ
ラーでもっとも一般的なのが、ロックの競合です。行を削除する場合、データベー
スサーバはその行に対し排他ロックを設定しないと削除できません。他のプログラ
ムが操作の対象となる表を使用している場合は、データベースサーバはその行を
ロックできません。ロックの問題はあらゆる種類の変更操作に影響するため、第 7
章「マルチユーザ環境のためのプログラミング」で詳しく説明します。
削除が始まってから発生するエラーには、この他に、データベースを更新している
ときに起こるハードウェアのエラーがあります。
6-4
Informix Guide to SQL: Tutorial
直接的な削除
トランザクションログ機能の使用方法
変更中に発生するあらゆる種類のエラーに対処するには、トランザクションログ機
能を使用します。トランザクションログ機能を使用すると、エラーが発生した場合
でも、データベースを変更した直前の状態に戻せます。次の例は、6-4 ページの
「直接的な削除」の節で示した例に、トランザクションログを追加したものです。
EXEC SQL begin work; /* start the transaction*/
EXEC SQL delete from items
where order_num = :onum;
del_result = sqlca.sqlcode; /* save two error */
del_isamno = sqlca.sqlerrd[1]; /* ...code numbers */
del_rowcnt = sqlca.sqlerrd[2]; /* ...and count of rows */
if (del_result < 0) /* some problem, */
EXEC SQL rollback work; /* ...put everything back */
else
/* everything worked OK, */
EXEC SQL commit work; /* ...finish transaction */
この例で重要なのは、トランザクションを終了する前に、プログラムが SQLCA の
重要な戻り値を保存していることです。これは、ROLLBACK WORK 文も COMMIT
WORK 文も、すべての SQL 文と同様に、リターンコードを sqlca 構造体に設定する
ためです。このため、エラーの発生後に ROLLBACK WORK 文を実行すると、エ
ラーコードが消去されてしまいます。エラーコードを別に保存しておかなければ、
エラーコードをプログラムのユーザに報告することができません。
トランザクションを使用する利点は、何か問題が発生しても、データベースは不安
定な状態にならないことです。どこまで変更が終了したのかが不明になることはあ
りません。すべての操作が完全に終了したか、あるいはまったく行われなかったの
かのいずれになります。
ログ機能を使用するデータベースでは、ユーザが明示的なトランザクションを開始
しない場合には、データベース サーバは文の実行の前に内部トランザクションを開
始し、実行が完了または失敗した後トランザクションを終了します。文の実行に成
功すると、内部トランザクションは確定されます。文が失敗すると、ロール バック
されます。
SQL プログラムによるデータの更新
6-5
直接的な削除
一元化された削除
トランザクションログ機能は、複数の表を削除する場合に特に役立ちます。たとえ
ばデモンストレーションデータベースから注文を 1 件削除する問題を考えてみま
しょう。二つの表 orders と item から行を削除する場合を、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;
if (SQLCODE >= 0)
EXEC SQL COMMIT WORK;
else
{
printf("Error %d on DELETE", SQLCODE);
EXEC SQL ROLLBACK WORK;
}
}
このプログラムの論理は、トランザクションの使用あるいは不使用でもほとんど変
わりません。しかし、トランザクションを使用しない場合、エラーメッセージを見
たユーザが行う決定が困難になってしまいます。トランザクションを使用しない場
合、いつエラーが発生したかによって状況は次のように変わります。
■
削除はまったく行われなかった。この注文番号のすべての行は、データ
ベースに残っている。
■
表 items の行が一部のみ削除された。いくつかの品目 ( いくつかは不明 ) を含
む注文レコードが残っている。
■
表 items のすべての行は削除されたが、表 orders の行は残っている。
■
すべての行が削除された。
2 番目と 3 番目の場合、データベースの一部が壊れてしまっています。データベー
スには部分的な情報が入っているため、問合せに対しては間違った結果を返すこと
があります。この場合、慎重な処理を行って、情報を一貫性のある状態に戻さなけ
ればなりません。トランザクションを使用していれば、このような不明確な状態に
なることはありません。
6-6
Informix Guide to SQL: Tutorial
カーソルを使用した削除
カーソルを使用した削除
カーソルを使用して、取り出した最後の行を削除するように、DELETE 文を記述す
ることもできます。この方法で行を削除すると、次の例に示すように、WHERE 節
で検査できない条件に基づいて削除をプログラムすることができます。次の例は、
トランザクションの始まりと終わりがセット アップされる方法のため、ANSI 標準
準拠ではないデータベースにのみ適用されます。
警告 : この例の ESQL/C 関数の設計では、プログラムがいつでも完全に動作すると
は限りません。この関数が正しく働くかどうかは、現在の排他レベルに依存してい
ます。排他レベルについては後述します。排他レベルについての詳細は、第 7 章
「マルチユーザ環境のためのプログラミング」を参照してください。前の例は、た
とえ意図したとおりに関数が動作しても、その影響は表内の行の物理的な順序に依
存するのでよい設計とは言えません。
int delDupOrder()
{
int ord_num;
int dup_cnt, ret_code;
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);
}
SQL プログラムによるデータの更新
6-7
カーソルを使用した削除
この関数の目的は、重複した注文番号を含む行を削除することです。デモンスト
レーションデータベースでは、orders.order_num の列番号に一意性インデックスが
付いているため、注文番号が重複した行ができる可能性はありません。しかし、同
じような関数がありふれた列名を使用している別のデータベースのために書かれて
いる可能性はあります。
この関数は、表 orders のすべての行を走査するカーソルとして、scan_ord を宣言し
ています。このカーソルは FOR UPDATE 節で宣言されていますが、これは、カー
ソルがデータの変更に使用できることを示しています。カーソルが正しくオープン
した場合は、この関数はトランザクションを開始し、表の各行を反復処理します。
この関数は、表の各行について、埋め込まれた SELECT 文を使用して、FETCH 文
で取り出した行と注文番号が同じ行が表に何行あるかを調べます。
(第 7 章「マル
チユーザ環境のためのプログラミング」で説明するように、これは排他レベルが正
しくないと失敗します。)
デモンストレーションデータベースでは、この表に一意性インデックスが付いてい
るので、dup_cnt に返されるカウント、つまり重複行の数は常に 1 です。この値が 1
よりも大きい場合は、この関数は表の現行行を削除して、カウント数を 1 減らしま
す。
このような目的で使用される関数は、この例より高度な設計を必要とします。この
関数は、データベースサーバが返す最後の重複行以外のすべての重複行を削除しま
す。この順番は、行の内容や意味とはまったく関係がありません。前出の例の関数
は、カーソル宣言に ORDER BY 節を追加することで改善することができます。残
念ながら、ORDER BY 節を FOR UPDATE 節と一緒に使用することはできません。
この関数を改善する方法については、6-12 ページの「挿入の例」で説明します。
6-8
Informix Guide to SQL: Tutorial
INSERT カーソルの使用方法
INSERT カーソルの使用方法
INSERT 文をプログラムに埋め込んで使用することができます。その構文と使用方
法は第 4 章「データの更新」で説明した INSERT 文と同じですが、この場合は、
VALUES 節と WHERE 節の両方でホスト変数を式で使用することができます。さら
にプログラムに INSERT 文を埋め込むと、カーソルを使用して行を挿入することも
できます。
INSERT カーソルの使用方法
DECLARE CURSOR 文には多くの種類があります。その大部分は、データに対して
さまざまな走査を行うカーソルを作成するためのものですが、INSERT カーソルと
いう特別な種類のカーソルを作成するものがあります。INSERT カーソルを PUT 文
と FLUSH 文で使用すると、複数の行を一括して効率よく表に挿入できます。
INSERT カーソルの宣言
INSERT カーソルを作成するには、SELECT 文の変わりに INSERT 文についてカー
ソルを宣言します。このように宣言したカーソルは、行の取り出しには使用できま
せん。行の挿入だけに使用できます。以下は、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 行の挿入データが入る大きさに作成されます。バッ
ファの最小サイズより行が十分に短い場合は、バッファには複数の行が格納されま
す。
SQL プログラムによるデータの更新
6-9
INSERT カーソルの使用方法
カーソルを使用した挿入
前出のサンプルプログラムは、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) /* if no problem with PUT */
{
EXEC SQL FLUSH new_custs; /* write any rows left */
if(SQLCODE == 0) /* if no problem with FLUSH */
EXEC SQL COMMIT WORK; /* commit changes */
}
else
EXEC SQL ROLLBACK WORK; /* else undo changes */
この例のコードは next_cust を繰り返し呼び出しています。next_cust が NULL でな
いデータを返すと、PUT 文はそのデータを行バッファへ送ります。バッファがいっ
ぱいになると、バッファ内の行は自動的にデータベースサーバへ送られます。
WHILE ループは、next_cust が返すデータがなくなると正常終了します。ループか
ら抜けた後、FLUSH 文がバッファ内に残っている行を表に書き込み、それが終わ
ると、このトランザクションは終了します。
6-9 ページの INSERT 文をもう一度調べます。この INSERT 文自体は、カーソル定
義の一部ではなく、表 custom に 1 行を挿入します。実際、この例から INSERT
カーソルを指定する部分を削除して、INSERT 文を PUT 文がある位置に書くことも
できます。その違いは、INSERT カーソルのほうがプログラムの実行速度が多少速
いという点です。
6-10
Informix Guide to SQL: Tutorial
INSERT カーソルの使用方法
PUT 文と FLUSH 文の実行後の状態コード
PUT 文を実行する場合、プログラムは行が実際にバッファに格納されたかどうかを
検査する必要があります。新しい行がバッファに入った場合、PUT 文が行う操作は
その行をバッファにコピーすることのみです。この場合、エラーが発生する可能性
はありません。しかし、新しい行がバッファに入りきらない場合は、バッファの中
身全体がデータベースサーバに渡されて表に挿入されるので、このときにエラーが
発生する可能性があります。
SQL 通信領域 (SQLCA) に返される値が、プログラムに PUT 文実行の結果を調べる
ための情報を示します。SQLCODE と SQLSTATE は、PUT 文を実行するたびに、
エラーが発生しなかった場合はゼロに、エラーが発生した場合は負のエラーコード
に、それぞれ設定されます。
SQLERRD の 3 番目の要素は、表に実際に挿入された行の数に設定されます。した
がって、この要素は、新しい行がバッファにコピーされただけの場合はゼロになり
ます。バッファの中身がエラーを起こさずに表に挿入された場合は、バッファに
入っていた行数が SQLERRD の 3 番目の要素に設定されます。挿入中にエラーが発
生した場合は、それまでに挿入された行数が設定されます。
コードを再度読んで、SQLCODE をどのように使用しているか確認してください
( 前出の例を参照してください )。まず、OPEN 文の実行時にエラーが発生した場合
は、WHILE 節の条件が偽となるため、ループは実行されず、FLUSH 文も実行され
ずにトランザクションはロールバックします。次に、PUT 文がエラーを返した場合
は、WHILE 節の条件が偽となるためループは終了し、FLUSH 文は実行されず、ト
ランザクションはロールバックします。これが起こるのは、バッファを少なくとも
1 回はいっぱいにするだけの数の行がループによって生成された場合のみです。そ
の他の場合は、PUT 文の実行でエラーが発生することはありません。
行がバッファにまだ残っているのに、場合によっては、1 行も挿入していないのに
ループが終了することがあります。いずれの場合も、SQL の値がゼロなので、
FLUSH 文が実行されます。FLUSH 文の実行でエラーが発生した場合、トランザク
ションはロールバックします。トランザクションがコミットするのは、すべての行
が完全に成功したときのみです。
SQL プログラムによるデータの更新
6-11
定数だけで構成される行の挿入
定数だけで構成される行の挿入
INSERT カーソルを使用すると高い効率が簡単に得られる特殊な場合が一つありま
す。それは、INSERT 文の VALUE 節で指定した値が定数、つまり、式やホスト変
数が示されてなく、具体的な定数値と文字列である場合です。このような INSERT
文は、何回実行しても同じ行を生成します。行が同じである場合、コピーし、バッ
ファに入れ、転送することはありません。
このような INSERT 文では、PUT 文はカウンタの値を増加するだけで他に何もしま
せん。最後に FLUSH 文が実行されるときに、行のコピー一つと挿入の回数がデー
タベースサーバへ渡されます。データベースサーバは渡された情報を基に、必要な
数の行を生成して 1 回の操作で挿入します。
多くの同じ行を挿入することは、めったにありません。ただし、データベースを作
成したばかりのときに、大規模な表を NULL データで埋める場合には、この操作を
行うことになるかもしれません。
挿入の例
6-7 ページの「カーソルを使用した削除」では、重複行を表から探し出して削除す
ることを目的とする、DELETE 文の例を説明しました。不要な行を削除するのでは
なく必要な行を選択したほうが、このタスクをうまく行えます。次に
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);
6-12
Informix Guide to SQL: Tutorial
挿入の例
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;
else
EXEC SQL COMMIT WORK;
EXEC SQL CLOSE ins_row;
EXEC SQL CLOSE dup_row;
この例は、通常の INSERT 文で始まります。この INSERT 文は、重複していない行
を表から見つけ、別の表に挿入します。挿入先の表は、このプログラムの開始前に
作成されている必要があります。この操作を行うと、重複している行のみが残りま
す。( デモンストレーションデータベースの表 orders には、一意性インデックスが
付いているので、行が重複する可能性はありません。この例では、デモンストレー
ションデータベース以外のデータベースを取り上げています。)
前出のサンプルコードは、その後二つのカーソルを宣言します。最初の dup_row と
いうカーソルは、表の重複行を取り出します。dup_row は入力専用なので、ORDER
BY 節を使用して重複行をソートすることができます。6-7 ページの例で示したよう
に、意味のない物理的順序で行がソートされることはありません。この例では、重
複行は日付の順にソートされています。これは、最も古い日付の行が格納されるよ
うにするためです。目的に応じて、他の順序でソートすることも可能です。
2 番目のカーソル、ins_row は INSERT カーソルです。このカーソルは、C 構造体、
ord_row を使用できるという利点を生かして、その行のすべての列に値を与えます。
SQL プログラムによるデータの更新
6-13
挿入の例
コードの残りの部分は、dup_row から取り出した行を調べます。重複行の各グルー
プから最初の 1 行だけを選んで表に挿入し、残りの行は無視します。
簡潔さのために、前出の例では、最も単純な種類のエラー処理を使用しています。
すべての行が処理される前にエラーが発生した場合には、サンプル コードは実行中
だったトランザクションにロールバックします。
影響を受ける行の数
カーソルを使用して行を選択するプログラムでは、SQLCODE のリターンコードが
データの終わりを示す 100 かどうか (SQLSTATE では 02000) を調べることができ
ます。このコードは、問合せ条件を満たす行が存在しないか、またはこれ以上存在
しないかを示すために設定されます。ANSI 標準に準拠していないデータベースで
はデータの終わりを示すリターンコードが設定されるのは、SELECT 文の後の
SQLCODE や SQLSTATE のみです。この値は DELETE 文、INSERT 文、UPDATE
文の実行後には使用されません。ANSI 標準に準拠したデータベースでは、
UPDATE 文、DELETE 文、INSERT 文では、プログラム操作の影響を受ける行が
まったくなくても 100 に設定されます。
データを取り出さなかった SELECT 文は、成功したとはみなされません。これに対
して、UPDATE 文と DELETE 文では、1 行も更新または削除を行わなくても成功し
たものと見なされます。これは、UPDATE 文と DELETE 文が WHERE 節の条件を
満たす行の集合を更新または削除しましたが、その集合が空だったということにす
ぎません。
INSERT 文の場合も同様です。挿入対象の行が SELECT 文の結果で、その SELECT
文が 1 行も選択しなかった場合でも、データの終わりを示すリターンコードは設定
されません。この場合、INSERT 文は成功したと見なされます。指定された数の行、
この場合はゼロ行を挿入しているからです。
挿入、更新、削除された行が何行かは、SQLERRD の 3 番目の要素を調べるとわか
ります。SQLCODE の値が何であっても、この要素の値は、挿入、更新、削除され
た行数を示しています。行数がゼロや負の値であっても、その値が示されます。
6-14
Informix Guide to SQL: Tutorial
UPDATE 文の使用方法
UPDATE 文の使用方法
UPDATE 文をプログラムに埋め込んで使用することができます。第 4 章「データの
更新」で説明した、どちらの書式の UPDATE 文でも埋め込むことができます。プ
ログラムに埋め込む UPDATE 文では、式でホスト変数を指定できます。SET 節と
WHERE 節で使用する式でもホスト変数を指定できます。さらに、プログラムに埋
め込んだ UPDATE 文では、カーソルを使用して行を更新することができます。
UPDATE カーソルの使用方法
UPDATE カーソルは、現行行の削除や更新を目的とするカーソルです。現行行とは
最後に取り出された行のことです。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 )
{
UPDATE customer
SET fname = 'Midori', lname = 'Tokugawa'
WHERE CURRENT OF names;
}
この UPDATE 文の WHERE 節では、通常の条件式の代わりにキーワード
CURRENT OF に names というカーソル名を指定しています。これ以外は、この
UPDATE 文は通常の UPDATE 文と同じです。この文に指定されている表名は、
カーソル名から間接的にわかりますが、指定しなければなりません。
SQL プログラムによるデータの更新
6-15
UPDATE カーソルの使用方法
キーワード UPDATE の目的
キーワード UPDATE を使用して UPDATE カーソルを宣言するのは、取り出された
行が更新または削除される可能性があることをデータベースサーバに知らせるため
です。データベースサーバは、UPDATE カーソルによって取り出された行に厳しい
ロックを設定し、このキーワードが宣言されていないカーソルによって取り出され
た行にはあまり厳しくないロックを設定します。これにより、通常のカーソルにつ
いては効率が向上し、多重プロセッシングシステムでは並列度が高まります。
( ロックと並列度については、第 7 章「マルチユーザ環境のためのプログラミング」
で説明します。)
特定の列の更新
次の例は、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 のみです。次のよう
な UPDATE 文は、エラーと見なされるため実行できません。
EXEC SQL
UPDATE customer
SET company = 'Siemens'
WHERE CURRENT OF namesEND-EXEC.
このような UPDATE 文がプログラムに含まれていると、エラーコードが返されて、
更新は行われません。WHERE 節にキーワード CURRENT OF を指定した DELETE
文も実行できません。削除はすべての列に影響すると考えられるためです。
キーワード UPDATE は常に必要ではない
ANSI( 米国規格協会 ) 標準の SQL は、カーソル定義での FOR UPDATE 節を提供し
ていません。ANSI 標準準拠のデータベースを使用するプログラムは、任意のカー
ソルを使用して更新や削除を実行できます。
6-16
Informix Guide to SQL: Tutorial
表の仕上げ
表の仕上げ
UPDATE カーソルの使用例をもう一つ示します。この問題も、完成したデータベー
スでは絶対に起こりませんが、アプリケーションの初期設計段階で起こる問題で
す。
この例では、target という大きな表が構築、移植されています。datcol という名前の
文字 (CHAR) 型列に誤って NULL がいくつか入ってしまいました。これらの列は削
除しなければなりません。さらに、表の作成後に、ALTER TABLE 文を使用して
serials という名前の新しい列を追加しました。この列には、一意の整数値を割り当
てる必要があります。次の例では、このタスクを実行するために使用する
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;
SQL プログラムによるデータの更新
6-17
まとめ
まとめ
第 4 章「データの更新」で説明した INSERT 文、DELETE 文、UPDATE 文は、プロ
グラム中に埋め込んで使用することもできます。カーソルを使用して表を走査し、
選択された行を更新したり削除したりすることができます。また、行の挿入にも
カーソルを使用することができます。これには、行がいったんバッファに格納され
てから、一括してデータベースサーバに送られるという利点があります。
このような操作を行う場合、エラーを検出し、エラーが発生した場合にはデータ
ベースを復元するようなプログラムを作成する必要があります。この復元処理で最
も重要なのは、トランザクションです。プログラムでトランザクションログ機能を
使用しないと、エラーからの復旧が困難になります。
6-18
Informix Guide to SQL: Tutorial
第7章
マルチユーザ環境のための
プログラミング
並列度と性能 .
. . .
. .
. . .
. . .
. . .
. . .
. .
7-3
ロックと整合性 . . .
. .
. . .
. . .
. . .
. . .
. .
7-3
ロックと性能 .
. . .
. .
. . .
. . .
. . .
. . .
. .
7-4
並列度に関する問題 . .
. .
. . .
. . .
. . .
. . .
. .
7-4
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7-6
7-7
7-7
7-8
7-8
. . . . . .
. . . . . .
. . . . . .
. . . . . .
7-9
7-10
7-11
7-11
ロックの動作 . . . . . . . . . . . . . .
ロックの種類 . . . . . . . . . . . .
ロック範囲 . . . . . . . . . . . . .
データベースに対するロック. . . . . . .
表に対するロック . . . . . . . . . .
Informix Dynamic Server with AD and XP Options の
TABLE ロック モード . . . . . .
ページ、行、キーに対するロック . . . . .
ロックの継続期間 . . . . . . . . . . .
データ修正中のロック . . . . . . . . . .
.
.
.
.
.
. . .
. .
7-17
アクセスモードによるデータ変更の制御 .
. . .
. . .
. . .
. .
7-18
ロックモードの設定 . . . .
ロックの解除を待つ . .
ロックの解除を待たない .
一定時間ロックの解除を待つ
デッドロックの処理 . .
外部デッドロックの処理 .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7-19
7-19
7-19
7-20
7-20
7-21
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
排他レベルの設定 . . . . . . . . . . . . .
SET TRANSACTION 文の SET ISOLATION 文との比較 .
不確定読込み (ANSI) と単純読込み (INFORMIX) . . . .
確定読込み (ANSI) と確定読込み (INFORMIX) . . . . .
排他レベルのカーソル安定性 (INFORMIX) . . . . . .
繰返し読込み (ANSI)、直列化可能 (ANSI)、および繰返し
読込み (INFORMIX) 排他レベル . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
. .
. .
. .
. .
.
.
.
.
.
.
.
.
. .
. .
. .
.
.
.
.
.
.
7-12
7-12
7-14
7-14
7-15
7-2
単純な並列度 .
. .
. . .
. . .
. . .
. . .
. . .
. .
7-21
HOLD カーソル
. .
. . .
. . .
. . .
. . .
. . .
. .
7-21
まとめ . . .
. .
. . .
. . .
. . .
. . .
. . .
. .
7-23
Informix Guide to SQL: Tutorial
データベースが置かれているコンピュータがシングルユーザ用のワークステーショ
ンで、ネットワークを介して他のコンピュータと接続されていなければ、プログラ
ムはそのデータベースのデータを自由に変更できます。しかし、これ以外では、あ
るプログラムがデータを変更しているときに、他のプログラムが同じデータを読み
込んだり変更したりする可能性があります。これをプロセス処理の並列度と呼びま
す。つまり、同じデータを複数のプログラムが同時に使用することを指します。こ
の章では、並列度、ロックおよび排他レベルについて説明します。
並列度と性能
並列度は、複数プログラミングシステムの性能向上に不可欠なものです。一度に 1
本のプログラムのデータのみを使用するようにデータベースへのアクセスを直列化
すると、処理速度は大幅に低下してしまいます。
ロックと整合性
データへのアクセスを適切に制御しない場合と、並列度はさまざまな弊害をもたら
す恐れがあります。プログラムが、失効したデータを読み込んだリ、成功したよう
に思われた変更操作の結果が失われるかもしれません。
データベースサーバは、ロックを系統的に設定することによって、このようなエ
ラーを防止します。ロックは、データの各部に対するプログラムからの使用予約で
す。データベースサーバは、ロックされているデータについては、他のプログラム
がそのデータを更新できないようにします。他のプログラムがそのデータを要求し
た場合は、ロックが解除されるまでそのプログラムを待機させるか、あるいはエ
ラーメッセージを発行してその要求を拒否します。
マルチユーザ環境のためのプログラミング
7-3
ロックと性能
ロックと性能
ロックは一つのデータに対するアクセスを直列化するため、並列度は低下します
ロックされているデータにアクセスしたいプログラムは待機しなければなりませ
ん。データベースサーバは単一の行、複数の行を持つディスクページ、表全体、ま
たはデータベース全体をロックすることができます。データベースサーバが設定す
るロックの数が多いほど、また、ロック対象のオブジェクトが大きいほど、並列度
は低下します。ロックの数が少なくオブジェクトが小さいほど、並列度と性能は高
まります。
ここでは、どうすればプログラムが次の 2 つの目標を達成できるかについて説明し
ます。
■
データ整合性を維持するために必要なロックを、すべて設定する。
■
一つめの目標を達成できる範囲内で、ロックの数とロック対象のデータの
サイズをできるだけ減らす。
並列度に関する問題
並列度の弊害を理解するには、それぞれが独自の速度で動作する複数のプログラム
が実行されている状況を考える必要があります。たとえば、あるアプリケーション
プログラムは、次のように宣言されたカーソルを使用して行を取り出すとします。
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';
7-4
Imformix Guide to SQL: Tutorial
並列度に関する問題
二つのプログラムは、同じ表にアクセスすることになり、一方はある行を取り出し
もう一方はその行を更新します。この場合、次の結果が考えられます。
1.
作成したプログラムが最初の行を取り出すときには、他のプログラムは更
新をすでに終了している。
この場合、作成したプログラムが取り出すのは更新後の行です。
2.
作成したプログラムは、他のどのプログラムが変更するよりも早く表の行
を取り出す。
この場合、作成したプログラムが取り出すのは更新前の古い行です。
3.
作成したプログラムが更新前の行を何行か取り出した後で、他のプログラ
ムが追いつき、ユーザのプログラムがまだ取り出していない行を更新して
しまう。更新が終了すると、他のプログラムは COMMIT WORK 文を実行
する。
この場合、作成したプログラムが取り出すのは、一部は更新前の行、残り
は更新後の行です。
4.
表の更新が終了すると、他のプログラムが ROLLBACK WORK 文を発行す
る以外は、3 番目の場合と同じ。
この場合も、作成したプログラムが取り出すのは、一部は更新前の行、残
りは更新後の行ですが、更新後の行はすでにデータベースに存在しませ
ん。
最初の 2 つの可能性は、深刻な事態を招きません。一つ目の結果の場合、他のプロ
グラムによる更新は、作成したプログラムが問合せを始める前に完了しています。
完了したのがマイクロ秒前であっても 1 週間前であっても、違いはありません。
二つ目の結果の場合は、作成したプログラムの問合せは、他のプログラムが更新を
始める前に完了した場合と実質的に変わりません。他のプログラムは、作成したプ
ログラムより 1 行ずつ遅れて更新するかもしれませんし、翌日の夜にならないと
更新を始めないかもしれませんが、それを知る必要はありません。
マルチユーザ環境のためのプログラミング
7-5
ロックの動作
これに対し、残りの二つの可能性は、アプリケーションによっては非常に深刻な事
態を招くことがあります。3 つ目の結果の場合は、問合せは更新前のデータと更
新後のデータを混ぜて返します。アプリケーションによっては、これが問題になる
ことがあります。しかし、たとえばすべての価格の平均を求めるようなアプリ
ケーションの場合は、まったく問題にならないかもしれません。
4 つ目の結果の場合は、トランザクションが取り消されたために表にもう存在しな
くなった行をプログラムが返します。
作成したプログラムが、最後に取り出した行の更新あるいは削除ができるカーソル
を使用している場合は、別の問題が起こります。次の一連のイベントが行われた場
合には、その結果は誤ったものになります。
■
作成したプログラムが行を取り出す。
■
他のプログラムがその行を更新あるいは削除する。
■
作成したプログラムが、WHERE 節にキーワード CURRENT OF が指定され
たカーソルを用いてその行を更新あるいは削除する。
このような並行するイベントを制御するには、データベースサーバのロックと排他
レベルの機能を使用します。
ロックの動作
Informix データベースサーバは、ここで説明する精密で柔軟な一群のロック機能を
サポートします。ロック機能の要約については、
『Getting Started』を参照してくだ
さい。
7-6
Imformix Guide to SQL: Tutorial
ロックの種類
ロックの種類
次の表に、Informix データベースサーバがサポートする、状況に応じて使い分けられ
るロックの種類を示します。
ロックの種類
使用方法
共有ロック
共有ロックを設定すると、オブジェクトは読込み専用になります。
共有ロックが設定されている間は、オブジェクトの変更はできませ
ん。同じオブジェクトに対し、複数のプログラムが共有ロックを設
定できます。
排他ロック
排他ロックを設定すると、オブジェクトは単一プログラム専用に使
用されるようになります。このロックは、このプログラムがオブ
ジェクトを変更しようとすると使用されます。
他の種類のロックが設定されているオブジェクトに対しては、排他
ロックを設定できません。また、排他ロックを設定すると、そのオ
ブジェクトに対しては他のロックを設定できなくなります。
増進可能な
ロック
増進可能なロック増進可能なロックは更新の意図を明確にします。
このロックは、他の増進可能なロックや排他ロックが設定されてい
ないオブジェクトに対してしか設定できません。しかし、共有ロッ
クが設定されているレコードに対しては、増進可能なロックを設定
できます。ロックされたオブジェクトをプログラムが変更しようと
すると、増進可能なロックは排他ロックに対して増進した状態にな
ります。しかしこれも増進可能なロックから排他ロックに変わると
きに、共有メモリを含む他のロックがレコードに対して設定されて
いない場合に限ります。増進可能なロックを設定したときに、共有
ロックがレコードにあった場合には、増進可能なロックが排他ロッ
クに増進する前に、共有ロックを削除する必要があります。
ロック範囲
ロックは、データベース全体や表全体に対し、あるいは個々のディスクページ、行
単位、インデックスキー値に対し設定できます。ロックされるオブジェクトのサイ
ズを、ロック範囲、またはロックの細分度と呼びます。一般に、ロック範囲が広く
なるほど並列度は低下しますが、プログラミングは簡単になります。
マルチユーザ環境のためのプログラミング
7-7
ロック範囲
データベースに対するロック
データベース全体をロックできます。データベースを DATABASE 文、CONNECT
文、または CREATE DATABASE 文でオープンすると、そのデータベースに対し共
有ロックが自動的に設定されます。データベースが、あるプログラムによってオー
プンされている場合、そのデータベースに共有ロックが設定されているため、他の
プログラムはそのデータベースを削除したり、そのデータベースに対し排他的ロッ
クを設定したりすることはできません。
データベース全体に排他的ロックを設定するには、次の構文を使用します。
DATABASE < データベース名 > EXCLUSIVE
そのデータベースが他のプログラムによりオープンされていなければ、この文は成
功します。排他ロックが設定されると、他のプログラムはそのデータベースをオー
プンできなくなります。読込みが目的の場合でも共有ロックはできないので、オー
プンできません。
データベースのロックが解除されるのは、データベースがクローズされるときのみ
です。DISCONNECT 文または CLOSE DATABASE 文を使用して明示的に、また他
の DATABASE 文を実行して暗黙的にデータベースをクローズできます。
データベースをロックすると、そのデータベースの並列度がゼロになるため、並列
度の影響は出ず、プログラミングは非常に簡単になります。しかし、データベース
のロックは、そのデータベースにアクセスすることが必要なプログラムが他にない
場合にのみ行うようにしてください。データベースのロックが行われるのは、デー
タベースがあまり利用されていない時間帯に、データベースのデータを大規摸に更
新する場合などです。
表に対するロック
表全体をロックできます。表全体のロックは自動的に行われることもあります。
データベースサーバでは、次の文の実行中は常に表全体がロックされます。
7-8
✮
ALTER FRAGMENT 文
✮
ALTER INDEX 文
✮
ALTER TABLE 文
■
CREATE INDEX 文
✮
DROP INDEX 文
■
RENAME COLUMN 文
■
RENAME TABLE 文
Imformix Guide to SQL: Tutorial
ロック範囲
AD/XP
Dynamic Server with AD and XP Options は、ALTER INDEX 文をサポートしません。♦
文の実行が終了すると、またはトランザクションが終了すると、ロックは自動的に
解除されます。後述するように、特定の問合せが実行されているときに、表全体が
自動的にロックされることもあります。
LOCK TABLE 文を使用すると、表全体を明示的にロックできます。この文を使用す
ると、共有ロックか排他ロックを表全体に設定できます。
表に対して共有ロックを設定すると、プログラムがその表を読み込んでいる間は、
他のプログラムはその表を更新できません。データベースサーバは、次の項で説明
するように、排他レベルを設定することにより同程度の保護を実行します。排他レ
ベルによって、共有表ロックを使用するよりも並列度は大きくなります。LOCK
TABLE 文はすべての Informix データベースサーバでサポートされています。
表に対し排他ロックを設定すると、その表を複数のプログラムで同時に使用するこ
とがまったくできなくなります。したがって、多くのプログラムがその表の使用を
要求している場合は、性能に重大な影響を与えることがあります。表に対する排他
ロックは、データベースに対する排他ロックと同様に、データベースがあまり利用
されていない時間帯に大規模な更新を適用する場合などに使用されます。たとえば
あるアプリケーションは、利用がピークの時間帯には表の更新を行いません。これ
らのアプリケーションは、更新内容を更新日誌に書き込んでおき、利用がピークで
ない時間帯にこの更新日誌を読み込んで、更新を一括して行います。
AD/XP
Informix Dynamic Server with AD and XP Options の
TABLE ロック モード
Dynamic Server with AD and XP Options では、LOCK TABLE 文または LOCK MODE
節の TABLE ロック モードのいずれかで表をロックできます。トランザクションの
排他レベルがトランザクションのロック獲得を必要とする場合、ロック モードが
TABLE に設定されている表をアクセスするすべてのトランザクションは、その表
のために表ロックを獲得します。
あるロック モードから他のロック モード (TABLE、PAGE または ROW) に表を切り
替えるには、ALTER TABLE 文を使用してください。
CREATE TABLE 文または ALTER TABLE 文の LOCK MODE 節に TABLE ロック
モードを指定しても、表ロックを獲得するために LOCK TABLE 文を使用しても、
その効果は同じです。
マルチユーザ環境のためのプログラミング
7-9
ロック範囲
TABLE ロック モードは、ページ レベル ロックまたは行レベル ロックを獲得する
( または排他レベルに準じて獲得しようとする ) 代わりに、トランザクションが表
ロックを獲得するので、問合せが効果的に増加するデータ ウェアハウス環境で特に
有用です。これは、ロック要求の数を著しく減少させます。表ロックの不利な点と
しては、更新の同時実行性を急激に減少することですが、このことはデータ ウェア
ハウス環境では一般に問題ではありません。
ページ、行、キーに対するロック
ロック可能な最小のオブジェクトは、表の 1 行です。プログラムは 1 行あるいは複
数の行をロックすることができ、他のプログラムは、その表のロックされていない
行を継続して処理することができます。
データベース サーバでは、データはディスク ページと呼ばれる単位で格納されま
す。各ディスク ページには 1 つ以上の行が含まれます。場合によっては、ディス
ク ページの個々の行をロックするよりも、そのディスク ページをロックする方が
性能が上がります。データベース サーバのディスク格納方式については、
『Administrator’s Guide』で説明されています。ディスク格納に関する表の最適化に
ついては『Performance Guide』にヒントがあります。
行単位でロックするかそれともページ単位でロックするかは、表を作成するときに
決定されます。データベースサーバがサポートする LOCK MODE 節を使用すると、
ページロックと行ロックのどちらかを指定できます。ロックモードは CREATE
TABLE 文で指定し、後で ALTER TABLE 文で変更することもできます。
ページロックと行ロックは、まったく同じ目的に使用されます。ある行をロックす
ることが必要になると、データベースサーバは、その表に設定されているロック
モードによって、その行自体かその行が格納されているページをロックします。
データベースサーバが、存在しない行をロックしなければならない場合もありま
す。この場合は、その行が存在したときに、占有したであろう表内の場所をロック
することになります。これは、インデックスキー値にロックを設定することによっ
て行います。キーに対するロックは、行ロックとまったく同じ働きをします。行単
位でロックされる表では、キーロックは仮想的な行に対するロックとして実現され
ます。ページ単位でロックされる表では、キーロックはキーを含むインデックス
ページか、存在するならば含むであろうキーを含むインデックスページに設定され
ます。
7-10
Imformix Guide to SQL: Tutorial
ロックの継続期間
ロックの継続期間
データベースに対するロックの継続期間はプログラムが管理します。データベース
ロックは、そのデータベースがクローズされると解除されます。
表に対するロックの継続期間は、データベースがトランザクションを使用している
かどうかで変わります。トランザクションを使用していない場合、すなわちトラン
ザクションログがなく COMMIT WORK 文が使用されていない場合は、表ロックは
UNLOCK TABLE 文によって解除されるまで続きます。
表、行、インデックスに対するロックの継続期間は、使用している SQL 文の種類
と、トランザクションが使用されているかどうかによって変わります。
トランザクションが使用されている場合は、トランザクションが終了すると表、
行、ページ、インデックスに対するロックはすべて解除されます。
データ修正中のロック
UPDATE カーソルを使用して行を取り出す場合、データベースサーバは取り出され
た行に対して増進可能なロックを設定します。この設定により、他のプログラムは
その行を変更できなくなります。増進可能なロックは排他ロックとは異なり、ロッ
ク中も他のプログラムはその行を引き続き読み込むことができます。この結果、そ
の行を取り出したプログラムが UPDATE 文か DELETE 文を実行するまでに少し時
間がかかるときでも、他のプログラムは待機する必要がなくなったり、次の行を取
り出したりすることができるため、並列度が高まり、性能が向上します。
行の更新が必要になると、データベースサーバはその行に対し排他ロックを設定し
ます。その行に増進可能なロックがすでに設定されている場合は、データベース
サーバは増進可能なロックを排他ロックに変更します。
行に対する排他ロックの継続期間は、トランザクションが使用されているかどうか
によって異なります。トランザクションが使用されていない場合は、変更された行
がディスクに書き込まれると排他ロックはすぐに解除されます。トランザクション
が使用されている場合は、トランザクションが終了するまで排他ロックが続きま
す。したがって、ロールバックされる可能性のある行を他のプログラムが使用する
ことはありません。
マルチユーザ環境のためのプログラミング
7-11
排他レベルの設定
トランザクションが使用されている場合、行が削除されるときは、インデックス
キーに対するロックが常に使用されます。これは、次のようなエラーの発生を防止
するためです。
■
プログラム A が行を削除する。
■
プログラム B が、その行と同じキーを持つ行を挿入する。
■
プログラム A がトランザクションをロールバックして、削除した行を復元
する。
この場合、プログラム B によって挿入された行を処理しようとするので、
エラーが発生します。
インデックスをロックすれば、プログラム A がそのトランザクションを確定するま
では、プログラム B が行を挿入することはできなくなります。
読込みに設定されたロックは、現在の排他レベルに従って管理されます。これにつ
いては、次の節で説明します。
排他レベルの設定
排他レベルとは、あるプロセスが他のプロセスの並列動作から分離する程度を意味
します。データベースサーバでは、排他レベルを選択できます。これらの排他レベ
ルは、プログラムが読み込んでいる間のロックの使用方法に関するさまざまな規則
を設定することによって、実現されています (UPDATE カーソルで実行されている
読込みには適用されません )。
排他レベルは SET ISOLATION 文、または SET TRANSACTION 文を使用して設定し
ます。SET TRANSACTION 文では、アクセスモードも設定することができます。ア
クセスモードの詳細については、7-18 ページの「アクセスモードによるデータ変更
の制御」を参照してください。
SET TRANSACTION 文の SET ISOLATION 文との比較
SET TRANSACTION 文は ANSI SQL-92 に標準準拠しています。この文は Informix の
SET ISOLATION 文に似ていますが、SET ISOLATION 文は ANSI 標準準拠の文では
ないため、アクセスモードを提供していません。
7-12
Imformix Guide to SQL: Tutorial
SET TRANSACTION 文の SET ISOLATION 文との比較
SET TRANSACTION 文に設定可能な排他レベルは、次の表に示すように、SET
ISOLATION 文に設定可能な排他レベルと比較できます。
SET TRANSACTION
SET ISOLATION
不確定読込み
単純読込み
確定読込み
確定読込み
サポートなし
カーソル安定性
(ANSI) 繰り返し読込み
直列化可能
(INFORMIX) 繰り返し読込み
(INFORMIX) 繰り返し読込み
SET TRANSACTION 文と SET ISOLATION 文の主な違いは、トランザクションにお
ける排他レベルの動作です。SET TRANSACTION 文は 1 回のトランザクションに対
して 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
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: SET TRANSACTION 文を実効状態のトランザクションで一回以上出す
ことはできません。
マルチユーザ環境のためのプログラミング
7-13
不確定読込み (ANSI) と単純読込み (INFORMIX)
不確定読込み (ANSI) と単純読込み (INFORMIX)
不確定読込み (ANSI) と単純読込み (INFORMIX) はもっとも単純な排他レベルで、
実際には排他性を設定していないのと同じです。行を取り出すとき、プログラムは
ロックをまったく設定せず、他のプログラムによるロックも認識しません。データ
ベースの行をコピーするのみで、他のプログラムがどのような操作をしているかに
ついては考慮しません。
プログラムは常に、完全な行を受け取ります。排他レベルの設定が不確定読込み
(ANSI)、または単純読込み (INFORMIX) であっても、一部の列のみが更新されてい
る行をプログラムが読み込むことは絶対にありません。しかし、あるプログラムが
行を更新するトランザクションを終了する前に、排他レベルとして不確定読込み
(ANSI) または単純読込み (INFORMIX) を設定してある別のプログラムが、更新後
の行を読み込むことはあり得ます。この場合、更新しているプログラムが後でその
トランザクションをロールバックすると、読込みプログラムは実際には存在しな
かったデータを処理したことになります (7-5 ページの「表の更新が終了すると、他
のプログラムが ROLLBACK WORK 文を発行する以外は、3 番目の場合と同じ」の
並列度に関する問題の 4 に該当します )。
不確定読込み (ANSI) または単純読込み (INFORMIX) は、並列度の性能がもっとも高
い排他レベルです。プログラムが読込みのために待つことはなく、他のプログラムを
待たせることもありません。この排他レベルは、次のような場合によく使用されます。
■
どの表も静的な場合。すなわち、並列的に実行されるプログラムはデータ
を読み込むだけで、データを変更することは絶対にない場合
■
表に対し排他ロックが設定されている場合
■
表を使用しているプログラムが一つのみであることが確実な場合
確定読込み (ANSI) と確定読込み (INFORMIX)
排他レベルに確定読込み (ANSI) と確定読込み (INFORMIX) を設定した場合、デー
タベースサーバでは、確定がまだ済んでいない行は絶対に返されないようになりま
す。これにより、確定が済んでいないデータを読み込んだ後で、そのデータがロー
ルバックされる問題は防止されます。
確定読込み (ANSI) と確定読込み (INFORMIX) は、非常に簡単に実行されます。行
を取り出す前に、データベースサーバは、更新中のプロセスがその行にロックを設
定したかどうかを検査します。ロックが設定されていなければ、データベースサー
バはその行を返します。更新は済んだが確定はまだ行われていない行にはロックが
設定されているため、この検査を行うことにより、不確定なデータをプログラムが
読むことはありません。
7-14
Imformix Guide to SQL: Tutorial
排他レベルのカーソル安定性 (INFORMIX)
確定読込み (ANSI) または確定読込み (INFORMIX) は、取り出された行に実際に
ロックを設定するわけではないので、この排他レベルは、不確定読込み (ANSI) ま
たは単純読込み (INFORMIX) とほとんど同じくらい効率的です。この排他レベル
は、各行のデータが、他の行 ( 同じ表、または他の表の ) を参照しない、独立した
単位として処理される場合に適しています。
排他レベルのカーソル安定性 (INFORMIX)
次のレベルであるカーソル安定性は、INFORMIX SQL 文の SET ISOLATION 文での
み設定できます。
IDS
排他レベルにカーソル安定性を設定した場合、データベースサーバは取り出された
最新の行のみにロックを設定します。通常のカーソルについては共有ロック、
UPDATE カーソルについては増進可能なロックを設定します。一度にロックされ
るのは、1 行のみです。つまり、1 行取り出されるたびに、前の行に設定されてい
たロックは解除されます。ただし、前の行が更新された行である場合は、この行の
ロックはトランザクションが終了するまで解除されません。 ♦
AD/XP
カーソル安定性が有効になっている場合、Informix Dynamic Server with AD and XP
Options は 2 行以上にロックを設定します。通常のカーソルについては共有ロック、
UPDATE カーソルについては増進可能なロックを設定します。ISOLATION_LOCKS
構成パラメータを使用して、所定のスキャンで所定の時にロックされる最大行数を
指定します。データベース サーバには、現在ロックされている行セットにユーザの
現在行が含まれます。次の行がカーソルから読み込まれるので、前の行が解除され
る場合も解除されない場合もあります。どの行がロックされ、これらの行がいつ解
除されるかは制御できません。データベース サーバは、最大 n 行が所定のカーソル
について所定の時にロックされること、および現在の行が現在ロックされている行
セットにあることのみを保証します。( デフォルト値は 1 行です。) パラメータ
『Performance Guide』および
ISOLATION_LOCKS の詳細については、
『Administrator’s Guide』を参照してください。 ♦
カーソル安定性は、プログラムが行を調べている最中に、その行が変化しないこと
を保証します。このことが重要になるのは、その行から読み込んだデータを基に、
プログラムが他の表を更新する場合です。排他レベルにカーソル安定性が設定され
ていれば、更新は必ず現在の情報を基に行われます。失効データが使用されること
はありません。
マルチユーザ環境のためのプログラミング
7-15
排他レベルのカーソル安定性 (INFORMIX)
次に排他レベルのカーソル安定性の効果的な使用方法を示します。プログラム A
は、デモンストレーションデータベースの表 stock に、ヒーロースポーツ社 (HRO)
の新しい取扱品目を一つ挿入しようとしています。それと同時に、プログラム B
は、ヒーロースポーツ社に関する情報と、このメーカーに関係するすべての取扱品
目を削除しようとしています。この場合、次のような一連の事体が起こる可能性が
あります。
1.
排他レベルにカーソル安定性を使用するプログラム A が、メーカーコード
を見つけるために表 manufact からヒーロースポーツ社の行を取り出しま
す。これにより、この行には共有ロックが設定されます。
2.
プログラム B が、同じ行に対し DELETE 文を実行します。この行には
ロックが設定されているため、データベースサーバはプログラム B を待機
させます。
3.
プログラム A が、表 manufact から取り出したメーカーコードを使用して、
表 stock に新しい行を挿入します。
4.
プログラム A が、表 manufact に対するそのカーソルをクローズ、あるい
は表 manufact の別の行を読み、そのロックを解除します。
5.
待機状態でなくなったプログラム B が、表 manufact からヒーロースポー
ツ社の行を削除し、さらにメーカーコードが HRO の行を表 stock から削
除します。プログラム A が表 stock にいま挿入した行も削除します。
もしプログラム A が使用する排他レベルがカーソル安定性よりも低い場合には、次
のような一連のイベントが起こる可能性があります。
1.
プログラム A が、メーカーコードを見つけるために表 manufact からヒー
ロースポーツ社の行を読み込みます。ロックは設定されません。
2.
プログラム B が、同じ行に対し DELETE 文を実行します。実行は成功します。
3.
プログラム B が、メーカーコードが HRO のすべての行を表 stock から削
除します。
4.
プログラム B が終了します。
5.
読み込んだヒーロースポーツ社の行が無効になったことを知らないプログラ
ム A が、メーカーコード HRO を使用し表 stock に新しい行を挿入します。
6.
プログラム A が終了します。
プログラム A が終了した時点では、メーカーコードが表 manufact にない行が表
stock に 1 行存在するという結果になります。さらに、プログラム B にはバグがあ
るかのように見えます。つまり、プログラム B が削除すべき行を削除しなかった
ことになります。プログラム A が排他レベルとしてカーソル安定性を使用すれば、
このような結果にはなりません。
7-16
Imformix Guide to SQL: Tutorial
繰返し読込み (ANSI)、直列化可能 (ANSI)、および繰返し 読込み (INFORMIX) 排他
排他レベルとしてカーソル安定性が使用されていてもエラーが発生するように、こ
の例の順序を並べ替えることもできます。プログラム A とは逆の順番でプログラム
B が表を操作するように並べ替えればいいのです。たとえば、プログラム B が表
manufact を削除する前に、表 stock の行を削除した場合、どのレベルの排他を行っ
てもエラーの発生を防止できません。このようなエラーが発生する可能性がある場
合は、関係するすべてのプログラムが同じ順番で表にアクセスするようにすること
が必要です。
カーソル安定性では、一度にロックされる行の数は、Dynamic Server の場合は 1 行、
Dynamic Server with AD and XP Options の場合は指定された数だけのため、表やデー
タベースに対するロックの場合よりも並列度が上がります。
繰返し読込み (ANSI)、直列化可能 (ANSI)、および繰返し
読込み (INFORMIX) 排他レベル
繰返し読込み (ANSI)、直列化可能 (ANSI)、および繰返し読込み (INFORMIX) 排他
レベルの定義はすべて同じです。
繰返し読込み (REPEATABLE READ) の排他レベルでは、データベースサーバは、
プログラムが検査し、取り出すすべての行にロックを設定します。通常のカーソル
については共有ロック、UPDATE カーソルについては増進可能なロックが設定され
ます。各行が検査される際、ロックは個別に設定されます。カーソルがクローズさ
れるかトランザクションが終了するまで、ロックは解除されません。
排他レベルに繰返し読込みを設定すると、スクロールカーソルを使用するプログラ
ムは、一度読み込んだ行を再び読み込むまでの間に、行が更新されたり削除された
りしていないことを確かめるために、選択された行を何度でも繰り返し読み込むこ
とができます。( スクロールカーソルについては、第 5 章「SQL を使用したプログ
ラミング」に記述されています。) この排他レベルより低いレベルでは、次に読み
込まれるまでの間に、行の削除や更新が行われていないことは保証しません。
繰り返し読込みとして設定されるロックは、ロックされる行数の点でも継続期間の
点でも、他の排他レベルよりも高いレベルになります。したがって、排他レベルと
して繰り返し読込みを設定すると並列度がもっとも低下する可能性があります。プ
ログラムがこの排他レベルを使用する場合は、設定されるロックの数、継続期間、
他のプログラムに対する影響について慎重に検討することが必要です。
マルチユーザ環境のためのプログラミング
7-17
アクセスモードによるデータ変更の制御
ロックの数が多いことは、並列度に影響するだけでなく、困難な状況をもたらすこ
とがあります。データベースサーバは各プログラムのロック数をロック表に記録し
ます。ロック数が最大数を超えるとロック表はいっぱいになり、データベースサー
バはそれ以上ロックを設定できなくなり、エラーを返します。Informix データベース
サーバ システムの管理者は、このロック表を監視し、表の使用頻度に注意してくだ
さい。
ANSI 標準準拠のデータベースでは、排他レベルが自動的に直列化可能に設定され
ます。これは、操作を確実に ANSI 標準の SQL に準拠した形で行うのに、直列化可
能の排他レベルが必要なためです。
アクセスモードによるデータ変更の制御
Informix データベースサーバはアクセスモードをサポートしています。アクセス
モードは SET TRANSACTION 文で設定され、トランザクション中の行の読込みと
書込みの並列度に影響を与えます。アクセスモードを使用して共有ファイル間の
データ更新を制御できます。
トランザクションはデフォルトでは読込みと書込みが可能です。トランザクション
を読込み専用に指定すると、そのトランザクションでは次のタスクは実行できませ
ん。
■
行の挿入、削除、または更新
■
スキーマ、表、一時表、インデックス、またはストアドプロシジャなどの
データベースオブジェクトの作成、変更、削除
■
アクセス権の付与と取消し
■
統計情報の更新
■
列名および行名の変更
読込み専用アクセスモードは更新を禁止します。
プロシジャが制限付きの文を実行しようとしない限り、ストアドプロシジャは読込
み専用トランザクションで実行できます。
7-18
Imformix Guide to SQL: Tutorial
ロックモードの設定
ロックモードの設定
ロックモードにより、プログラムが操作しようとするデータがロックされている場
合のプログラムの動作が制御されます。ロックされている行をプログラムが取り出
そうとしたり、変更したりしようとした場合は、次の 3 つの結果のいずれかになり
ます。
■
データベースサーバは、プログラムに対して SQLCODE または SQLSTATE
にただちにエラーコードを返します。
■
データベースサーバは、ロックを設定されたプログラムがロックを解除す
るまで、このプログラムをサスペンドします。
■
データベースサーバは、しばらくの間プログラムをサスペンドし、その後
ロックが解除されない場合、このプログラムはデータベースサーバからエ
ラーリターンコードを受け取ります。
どの結果を選ぶかは、SET LOCK MODE コマンドで指定します。
ロックの解除を待つ
ロックが解除されるまで待ちたい場合 ( これは多くのアプリケーションで最良の選
択です ) は、次のコマンドを実行します。
SET LOCK MODE TO WAIT
このロックモードが設定されたプログラムでは、同時に実行される他のプログラム
の存在を、通常は無視できます。他のプログラムがロックした行にアクセスしなけ
ればならない事態になった場合は、このプログラムはロックが解除されるまで待機
し、解除されてからアクセスします。この待機による遅れは、通常は問題とならな
いほど少ないものです。
ロックの解除を待たない
ロックの解除を待つ場合の欠点として、待機時間が長くなることがあげられます。
長時間の遅れを許容できない場合は、次のコマンドを実行することができます。
SET LOCK MODE TO NOT WAIT
マルチユーザ環境のためのプログラミング
7-19
一定時間ロックの解除を待つ
このモードが設定されると、ロックされている行にプログラムがアクセスした場合
はすぐに、行がロックされていることを示す -107 などのエラー番号がプログラムに
返され、実行中の SQL 文は終了します。プログラムは現行トランザクションを
ロールバックして、操作を再度試みる必要がります。
デフォルトのモードは、NOT WAIT です。SQL を対話的に使用していて、ロックに
関連するエラーが表示された場合は、ロックモードを WAIT モードに設定してくだ
さい。プログラムを作成している場合は、プログラムに埋め込む最初の SQL 文の
一つに、キーワード TO WAIT を指定した SET LOCK MODE 文を検討してくださ
い。
一定時間ロックの解除を待つ
待機時間の上限を設定するようにデータベースサーバに要求することができます。
次の文を発行することができます。
SET LOCK MODE TO WAIT 17
この文は、待機時間の上限を 17 秒に設定します。この時間が経過するまでにロッ
クが解除されない場合は、エラーが返されます。
デッドロックの処理
デッドロックとは、複数のプログラムが互いに他の実行を妨害しあう状態のことで
す。プログラム同士は、相手のプログラムがアクセスしたいオブジェクトにロック
を設定しています。デッドロックが検出される可能性があるのは、関係するすべて
のプログラムがそのロックモードを WAIT モードに設定している場合のみです。
Informix データベースサーバでは、デッドロックが単一のネットワークサーバの
データのみに関係する場合は、すぐにデッドロックを検出できます。2 番目にロッ
クを要求したプログラムにエラー ( エラー -143 ISAM エラー : デッドロックが発見
されました ) を返すことによって、デッドロックの発生を防止します。このエラー
は、そのプログラムがロックモードを NOT WAIT モードに設定した場合に受け取
るはずのエラーです。したがって、プログラムがロックモードを WAIT モードに設
定したにもかかわらず、ロックに関連するエラー番号を受け取った場合は、デッド
ロックの発生が事前に検出されたことがわかります。
7-20
Imformix Guide to SQL: Tutorial
外部デッドロックの処理
外部デッドロックの処理
異なったデータベースサーバ上のプログラムの間でも、デッドロックが検出される
ことがあります。この場合、データベースサーバはデッドロックをすぐには検出で
きません。( ネットワーク上のすべてのデータベースサーバ間で膨大な量の通信を
行わない場合は、デッドロックを完全には検出できません。) そのかわり、各デー
タベースサーバは、異なるデータベースサーバのロックされたデータを得るまでに
プログラムが待機できる時間の上限を設定します。その制限時間が経過した場合
は、データベースサーバはデッドロックが原因だったと想定し、ロックに関連する
エラー番号を返します。
すなわち、外部データベースが関係する場合は、どのプログラムも、そのロックの
最大待機時間が設定された状態で実行されます。この最大待機時間はデータベース
サーバについて設定されるもので、データベースサーバ管理者によって変更するこ
とができます。
単純な並列度
ロックと並列度に関する設定に自信がない場合、アプリケーションが単純なものな
ら、次の簡単な基準を使用できます。起動の際、すなわち最初の DATABASE 文の
直後で、次の文をプログラムに実行させるのです。
SET LOCK MODE TO WAIT
SET ISOLATION TO REPEATABLE READ
これらの文が返すリターンコードは無視してください。他のプログラムは存在しな
いものとして、実行を続けてください。これで性能に関する問題が発生しなければ
設定を検討し直す必要はありません。
HOLD カーソル
トランザクション ログ機能が使用されている場合は、(Informix Dynamic Server with
AD and XP Options 以外の ) すべてのデータベース サーバは、トランザクション内部
で行われた操作はすべてトランザクションの終了時にロール バックできることを保
証します。トランザクションを確実に扱うために、データベース サーバには、通常
次の規則が適用されます。
■
トランザクションが終了するとき、すべてのカーソルがクローズされる。
■
トランザクションが終了するとき、すべてのロックが解除される。
マルチユーザ環境のためのプログラミング
7-21
HOLD カーソル
AD/XP
InformixDynamic Server with AD and XP Options では、ロックはトランザクションの終
了時に解除されない場合もあります。表ロックを獲得する方法を示すために、デー
タベース サーバが表の一部を格納するすべてのコサーバのロックを獲得するとしま
す。トランザクションがまず SHARED モード表ロックを獲得し、EXCLUSIVE モー
ド表ロックにアップグレードしようとする場合、ロックはトランザクションの終了
時に解除されない場合もあります。トランザクションが SELECT を実行し、次いで
ロック モード TABLE で表の INSERT を実行する場合に、これが起こることがあり
ます。この場合、コサーバによってはアップグレードに成功するものもしないもの
もあります。成功したアップグレードにはロール バックの試みは行われません。こ
れは、いくつかのコサーバについては、トランザクションが表の EXCLUSIVE ロッ
クで終了する場合があることを意味します。 ♦
トランザクションを確実に処理するこれらの規則は、トランザクションをサポート
するデータベースシステムでは通常の規則です。そしてほとんどのアプリケーショ
ンでは問題の原因になりません。しかし、カーソルとともに標準トランザクション
を使用できない場合があります。たとえば、次のコードはトランザクションがなく
ても正常に動作します。しかし、トランザクションが追加されると、二つのカーソ
ルを並行して使用していることにより、カーソルのクローズで衝突が生じます。
EXEC SQL DECLARE master CURSOR FOR . . .
EXEC SQL DECLARE detail CURSOR FOR . . . FOR UPDATE
EXEC SQL OPEN master;
while(SQLCODE == 0)
{
EXEC SQL FETCH master INTO . . .
if(SQLCODE == 0)
{
EXEC SQL BEGIN WORK;
EXEC SQL OPEN detail USING . . .
EXEC SQL FETCH detail . . .
EXEC SQL UPDATE . . . WHERE CURRENT OF detail
EXEC SQL COMMIT WORK;
}
}
EXEC SQL CLOSE master;
この設計では、カーソルの 1 つは表の走査に使用されます。表から取り出された
レコードを基にして、別の表が更新されます。問題は、前述の例の疑似コードに示
したとおり、各更新が個別のトランザクションとして扱われるとき、UPDATE 文に
続く COMMIT WORK 文が主カーソルを含むすべてのカーソルをクローズすること
です。
7-22
Imformix Guide to SQL: Tutorial
まとめ
この問題に対するもっとも簡単な解決策は、主表全体に対する走査が一つの大きな
トランザクションになるように、COMMIT WORK 文と BEGIN WORK 文がそれぞ
れ最後と最初の文になるようにすることです。主表に対する走査を一つの大きなト
ランザクションとして扱える場合もありますが、更新すべき行が非常に多いと実際
的でなくなります。ロックの数が多くなりすぎます。しかも、これらのロックはプ
ログラムの実行が終わるまで保持されるものです。
この問題の解決策として、Informix データベースサーバでは、主カーソルの宣言に
キーワード WITH HOLD を追加できます。このキーワードを付けて宣言されたカー
ソルは HOLD カーソルと呼ばれ、トランザクションが終了してもクローズされませ
ん。その他のすべてのカーソルはクローズされ、ロックもすべて解除されますが、
HOLD カーソルは明示的にクローズされるまでオープンされた状態を保ちます。
HOLD カーソルを使用する場合は、その前に、ここで説明したロック機能をしっか
り理解するとともに、並行して実行される他のプログラムについても十分理解して
ください。ロックと並列度に関する理解が必要になるのは、COMMIT WORK 文を実
行すると、ロックがすべて解除されてしまうからです。HOLD カーソルを使用して
取り出された行に設定されていたロックも、解除されてしまいます。
カーソルが、表全体を順方向に 1 回走査する目的に使用される場合には、HOLD
カーソルを宣言してもあまり意味はありません。しかし、キーワード WITH HOLD
を、UPDATE カーソル、スクロールカーソルを含むどのようなカーソルにも指定す
ることができます。このことを実行する前に、表全体のロックを含むすべてのロッ
クが、トランザクションの終了時に解放されることを理解してください。
まとめ
複数のプログラムが並行してデータベースにアクセスしている場合 ( そのうち一つ
でもデータを変更することができる場合 )、すべてのプログラムは他のプログラム
が、仮にデータを読み込むだけであっても、データを変更できる可能性のあること
を理解しなければなりません。データベースサーバは、プログラムがあたかもデー
タを占有しているかのように実行することを許す、ロックと排他レベルの機構を提
供します。
マルチユーザ環境のためのプログラミング
7-23
セクション II
高度な SQL の使用
第8章
ストアド プロシジャの作成と
使用
ストアド プロシジャと SPL の紹介 . .
ストアド プロシジャの機能 . . .
SQL とストアド プロシジャの関係 .
. . .
. . .
. . .
. .
. .
. .
8-3
8-4
8-4
Dynamic Server with AD and XP Options のストアド プロシジャ動作 . .
. .
8-5
ストアド プロシジャの作成と使用. . . . . . . . . . . .
プロシジャの作成 . . . . . . . . . . . . . . .
プログラム内のプロシジャの作成 . . . . . . . . . .
プロシジャのコメント作成とドキュメント化 . . . . . . .
コンパイル時エラーの診断 . . . . . . . . . . . .
DB-Access を使用してプロシジャ内の構文エラーを見つける方法
SQL API を使用してプロシジャ内の構文エラーを見つける方法.
コンパイル時警告の確認 . . . . . . . . . . . . .
リスト ファイルの格納位置 . . . . . . . . . . .
リスト ファイルの表示 . . . . . . . . . . . .
テキストまたはドキュメントの生成 . . . . . . . . . .
プロシジャテキストの確認 . . . . . . . . . . .
プロシジャ ドキュメントの確認 . . . . . . . . . .
プロシジャの実行 . . . . . . . . . . . . . . .
ストアド プロシジャの動的実行 . . . . . . . . . . .
プロシジャのデバッグ . . . . . . . . . . . . . .
プロシジャの再作成 . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8-6
8-6
8-7
8-8
8-8
8-8
8-9
8-10
8-10
8-10
8-11
8-11
8-11
8-12
8-14
8-14
8-16
ストアド プロシジャに対するアクセス権.
作成に必要なアクセス権 . . . .
実行に必要なアクセス権 . . . .
所有者アクセス権付きプロシジャ
DBA アクセス権付きプロシジャ .
アクセス権と入れ子のプロシジャ
アクセス権の取消し . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8-17
8-18
8-18
8-18
8-19
8-19
8-20
. . .
. . .
. . .
. . .
8-20
8-20
8-20
8-21
変数と式 . . . .
SPL 変数 . . .
ローカル変数
広域変数. .
. . . . .
. . . . .
. . . . .
. . . . .
. . .
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
. . .
. . .
. . .
.
.
.
.
.
.
.
. . .
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
. . .
. . .
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
. . .
. . .
. . .
.
.
.
.
.
.
.
変数のフォーマット. . . .
変数の定義 . . . . . .
変数のデータ型 . . . . .
変数でのサブスクリプトの使用
変数の有効範囲 . . . . .
変数とキーワードの混同 . .
SPL 式 . . . . . . . . .
変数への値の割当て. . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8-21
8-21
8-22
8-22
8-22
8-23
8-25
8-25
プログラムの流れの制御 . . . . . . . . . . . . . .
分岐 . . . . . . . . . . . . . . . . . .
ループ . . . . . . . . . . . . . . . . . .
関数の処理 . . . . . . . . . . . . . . . .
プロシジャ内でのプロシジャの呼出し . . . . . . .
プロシジャからのオペレーティング システム コマンドの実行
プロシジャの再帰的呼出し. . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8-26
8-26
8-27
8-28
8-28
8-28
8-29
プロシジャとの情報の受渡し . . . . . .
結果の返戻 . . . . . . . . . .
戻りデータ型の指定. . . . . . .
値の返戻 . . . . . . . . . .
プロシジャからの複数の値セットの返戻.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8-29
8-30
8-30
8-30
8-31
例外処理 . . . . . . . . . . . . . . . . .
エラーのトラップと回復 . . . . . . . . . . .
ON EXCEPTION 文の制御の有効範囲 . . . . . . . .
ユーザ生成の例外 . . . . . . . . . . . . .
SQL エラーのシミュレート . . . . . . . . .
入れ子コードを終了するための RAISE EXCEPTION の使用
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8-32
8-32
8-33
8-34
8-34
8-35
. .
8-36
Informix Guide to SQL: Tutorial
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
まとめ . . .
8-2
.
.
.
.
.
.
.
.
. . .
. . .
SQL や、ストアド プロシジャ言語 (SPL) に属するその他の文を使用して、プロシ
ジャを作成しデータベース内に格納できます。これらのストアド プロシジャは、
SQL 動作を制御するのに有効なツールです。この章では、ストアド プロシジャの作
成方法を説明します。分かりやすくするため、実際のストアド プロシジャ例も示し
ます。
『Informix Guide to SQL: Syntax』を参照してください。
SPL 文の構文については、
SPL 文の説明や文の使用方法を示す例も説明しています。
ストアド プロシジャと SPL の紹介
SQL では、ストアド プロシジャはユーザ定義機能です。データベースに対してアク
セス権 RESOURCE を持つユーザならば誰でもストアド プロシジャを作成できま
す。作成したストアド プロシジャは、データベース オブジェクトとして実行形式
でデータベースに格納されます。ストアド プロシジャを使用すると、SQL だけを使
用して実行できる範囲が拡張されるだけでなく、SQL で実行できるすべての機能を
使用できます。
ストアド プロシジャを作成するには、SQL 文と SPL 文を使用します。SPL 文は
CREATE PROCEDURE 文と CREATE PROCEDURE FROM 文内でのみ使用できます。
CREATE PROCEDURE 文は、DB-Access およびリレーショナルオブジェクトマネー
ジャと一緒に使用できます。INFORMIX-ESQL/C などの SQL API では、CREATE
PROCEDURE 文と CREATE PROCEDURE FROM 文のどちらも使用できます。
ストアド プロシジャの作成と使用
8-3
ストアド プロシジャの機能
ストアド プロシジャの機能
ストアド プロシジャを使用すると、データベースの性能の向上、アプリケーション
作成の簡略化、データ アクセスの制限または監視など、広範囲におよぶ目的を実現
できます。
ストアド プロシジャは実行形式で格納されるので、実行頻度が高いタスクに使用す
ると性能を改善できます。それは、単なる SQL コードではなくストアド プロシ
ジャを実行すると、解析、妥当性チェック、問合せの最適化を繰り返し実行しない
で済むからです。
ストアド プロシジャはデータベース内のオブジェクトなので、データベース上で実
行するどのアプリケーションでも利用できます。複数のアプリケーションで同じス
トアド プロシジャを使用すれば、アプリケーションの開発時間を短縮できます。
DBA アクセス権を持たないユーザが、DBA アクセス権付きで実行するストアド プ
ロシジャも作成できます。この機能を使用すると、データベース内のデータへのア
クセスを制限、および管理できます。また、ストアド プロシジャが特定のテーブル
またはデータにアクセスするユーザを監視することもできます。ストアド プロシ
ジャを使用してデータへのアクセスを管理する方法の詳細については、
『Informix
Guide to Database Design and Implementation』を参照してください。
SQL とストアド プロシジャの関係
SQL データ操作文でプロシジャを呼び出し、プロシジャ内で SQL 文を発行するこ
とができます。SQL データ操作文の全一覧については、『Informix Guide to SQL:
Syntax』を参照してください。
SQL データ操作文中でストアド プロシジャを使用して、その文に値を指定できま
す。たとえば、プロシジャを使用して、次の動作を実行できます。
■
表に挿入する値の指定
■
SELECT 文、DELETE 文、または UPDATE 文の条件節の一部分を構成する
値の指定
これらの動作は、データ操作文でプロシジャを使用する方法の一例です。実際に
は、SQL データ操作文内のどの式でもプロシジャ呼出しを構成できます。
8-4
Informix Guide to SQL: Tutorial
Dynamic Server with AD and XP Options のストアド プロシジャ動作
ストアド プロシジャで SQL 文を発行し、これらの SQL 文をデータベース ユーザか
ら隠すこともできます。すべてのユーザが SQL の使用方法を理解しなくても、一
人の熟練の SQL ユーザが SQL 動作をカプセル化するストアド プロシジャを作成
し、そのプロシジャがデータベース内に格納されていることをほかのユーザに知ら
せればすべてのユーザが SQL 動作を実行できます。
AD/XP
Dynamic Server with AD and XP Options のストア
ド プロシジャ動作
Informix Dynamic Server with Advanced Decision Support and Extended Parallel Options の
ストアド プロシジャの場合、次の機能はほかの Informix データベース サーバの場合
と異なる動作をします。
■
システム カタログ表 SYSPROCPLAN
すべての Informix データベース サーバは、ストアド プロシジャが作成され
ると必ずシステム カタログ表 SYSPROCPLAN を変更します。Dynamic
Server with AD and XP Options を除いたすべてのデータベース サーバの場
合、ストアド プロシジャが実行中に新しい問合せ実行計画を生成すると、
ストアド プロシジャの実行中にシステム カタログ表 SYSPROCPLAN が変
更されます。しかし、Dynamic Server with AD and XP Options は、ストアド
プロシジャの実行により新しい問合せ計画が生成されても表
SYSPROCPLAN を変更しません。たとえば、システム カタログ表
SYSPROCPLAN から計画が削除され、コサーバからプロシジャが実行され
た場合、SYSPROCPLAN 内ではその計画は復元されません。ただし、コ
サーバから実行される UPDATE STATISTICS FOR PROCEDURE 文は
SYSPROCPLAN の計画を更新します。
■
プロシジャ呼出し
プロシジャ呼出しは、現行データベースと現行データベース サーバ内のプ
ロシジャに対してだけ行うことができます。
ストアド プロシジャの作成と使用
8-5
ストアド プロシジャの作成と使用
ストアド プロシジャの作成と使用
ストアド プロシジャを作成するには、プロシジャ内で実行する SQL 文を CREATE
PROCEDURE 文の文ブロックに入れます。SPL 文を使用すると、プロシジャ内の操
作の流れを制御できます。SPL 文には、IF 文、FOR 文などがあります。詳細につい
ては『Informix Guide to SQL: Syntax』を参照してください。CREATE PROCEDURE
文と CREATE PROCEDURE FROM 文についても『Informix Guide to SQL: Syntax』を
参照してください。
プロシジャの作成
DB-Access または Relational Object Manager を使用してストアド プロシジャを作成す
るには、CREATE PROCEDURE 文を発行し、プロシジャを構成するすべての文を文
ブロック内に入れます。たとえば、顧客の住所を読み出すプロシジャを作成するに
は、次のような文を使用します。
CREATE PROCEDURE 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
procedure 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 PROCEDURE
8-6
Informix Guide to SQL: Tutorial
プログラム内のプロシジャの作成
DOCUMENT 'This procedure 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 procedure read_address
プログラム内のプロシジャの作成
SQL API を使用してストアド プロシジャを作成するには、CREATE PROCEDURE
文のテキストをファイル内に格納します。CREATE PROCEDURE FROM 文を使用
し、このファイルを参照してプロシジャをコンパイルします。たとえば、顧客名を
読み出すプロシジャを作成するには、前の例に示すような文を使用し、その文を
ファイルに格納します。ファイル名が read_add_source の場合、次の文はプロシジャ
read_address をコンパイルします。
CREATE PROCEDURE FROM ’read_add_source’;
次の例は、この SQL 文が ESQL/C プログラムではどうなるかを示しています。
/* This program creates whatever procedure 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 procedure from the pwd */
main()
{
EXEC SQL database play;
EXEC SQL create procedure from 'read_add_source';
}
ストアド プロシジャの作成と使用
8-7
プロシジャのコメント作成とドキュメント化
プロシジャのコメント作成とドキュメント化
前の例のプロシジャ read_address にはコメントと DOCUMENT 節があることを確認
してください。このように、プログラマはプロシジャ テキストにコメントを組み込
むことができます。二重ハイフン (--) の後ろの文字は、コメントとみなされます。
二重ハイフンはプログラム行のどこででも使用できます。
DOCUMENT 節のテキストは、プロシジャの要約とします。このテキストを取り出
すには、システム カタログ表 sysprocbody に問い合わせます。DOCUMENT 節を呼
び出す方法については、8-11 ページの「プロシジャ ドキュメントの確認」を参照し
てください。
コンパイル時エラーの診断
CREATE PROCEDURE 文または CREATE PROCEDURE FROM 文を発行したときに、
プロシジャ本体で構文エラーが発生すると、文は失敗します。データベース サーバ
はプロシジャ テキストの処理を停止し、エラー位置を返します。
DB-Access を使用してプロシジャ内の構文エラーを見つける方法
DB-Access またはリレーショナルオブジェクトマネージャを使用して作成したプロ
シジャに構文エラーがある場合、メニュー [SQL] のオプション [Modify] を選択する
と構文エラーがある行にカーソルが移動します。
8-8
Informix Guide to SQL: Tutorial
コンパイル時エラーの診断
SQL API を使用してプロシジャ内の構文エラーを見つける方法
SQL API を使用して作成したプロシジャに構文エラーがある場合、CREATE
PROCEDURE 文は失敗し、SQLCA 値と SQLSTATE 値が設定されます。データベー
ス サーバは SQLCA のフィールド SQLCODE に負の値を設定し、SQLERRD 配列の
5 番目の要素にファイルへの文字オフセットを設定します。ESQL/C 用の SQLCA の
特殊なフィールドを次に示します。
■
sqlca.sqlcode (SQLCODE)
■
sqlca.sqlerrd[4]
構文エラーの場合、データベース サーバは SQLSTATE を 42000 に設定します。
次の例は、プロシジャを作成するときに構文エラーをトラップする方法を示してい
ます。エラーが発生した場合にメッセージとエラー文字位置を表示する方法も示し
ています。
#include <stdio.h>
EXEC SQL include sqlca;
EXEC SQL include sqlda;
EXEC SQL include datetime;
/* Program to create a procedure from procfile in pwd */
main()
{
long char_num;
EXEC SQL database play;
EXEC SQL create procedure from ' procfile ' ;
if (sqlca.sqlcode != 0 )
{
printf( " ¥nsqlca.sqlcode = %ld¥n " , sqlca.sqlcode);
char_num = sqlca.sqlerrd[4];
printf( " ¥nError in creating read_address. Check
character position %ld¥n " , char_num);
}
.
.
.
この例では、CREATE PROCEDURE FROM 文が失敗した場合、構文エラーが発生し
た文字位置のほかにメッセージも表示されます。
ストアド プロシジャの作成と使用
8-9
コンパイル時警告の確認
コンパイル時警告の確認
データベース サーバが問題が発生する可能性を検出したがプロシジャの構文は正し
い場合、データベース サーバは警告を生成し、それをリスト ファイルに格納しま
す。プロシジャを実行する前に、このファイルを調べて問題が生じる可能性がない
か確認できます。
プロシジャについてのコンパイル時警告リストを取り出すには、次の例に示すよう
に CREATE PROCEDURE 文で WITH LISTING IN 節を使用します。
CREATE PROCEDURE read_address (lastname CHAR(15)) -- one argument
RETURNING CHAR(15), CHAR(15), CHAR(20), CHAR(15), CHAR(2), CHAR(5); -- 6 items
.
.
.
WITH LISTING IN 'pathname' -- modify this pathname according to the conventions
-- that your operating system requires
--compile-time warnings go here
; -- end of the procedure read_address
リスト ファイルの格納位置
ネットワーク環境にある場合、リスト ファイルはデータベースがあるコンピュータ
上に作成されます。リスト ファイルに絶対パス名とファイル名を指定すると、指定
した位置にファイルが作成されます。
UNIX
リスト ファイルに相対パス名を指定した場合、データベースがあるコンピュータ上
のユーザーのホーム ディレクトリにファイルが作成されます ( ホーム ディレクトリ
がない場合、ファイルはルート ディレクトリに作成されます )。 ♦
WIN NT
リスト ファイルに相対パス名を指定した場合、データベースがローカル コン
ピュータ上にあれば、デフォルト ディレクトリは現行の作業ディレクトリになりま
す。データベースがローカル コンピュータ上にない場合、デフォルト ディレクト
リは %INFORMIXDIR%¥bin になります。 ♦
リスト ファイルの表示
プロシジャを作成した後、WITH LISTING 節で指定したファイルを表示し、警告を
確認できます。
8-10
Informix Guide to SQL: Tutorial
テキストまたはドキュメントの生成
テキストまたはドキュメントの生成
プロシジャは作成された後、システム カタログ表 sysprocbody に格納されます。シ
ステム カタログ表 sysprocbody には、元の CREATE PROCEDURE 文のテキストとド
キュメント テキストのほかに実行可能プロシジャも入っています。
プロシジャテキストの確認
プロシジャ テキストを生成するには、システム カタログ表 sysprocbody のデータ列
を選択します。次の SELECT 文は 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')
プロシジャ ドキュメントの確認
プロシジャのドキュメント テキストだけを表示する場合、次の SELECT 文を使用
してドキュメント文字列を読み出します。次の例で検索されるドキュメント行は、
CREATE PROCEDURE 文の DOCUMENT 節にあります。
SELECT data FROM informix.sysprocbody
WHERE datakey = 'D' -- find documentation lines
AND
procid = (SELECT procid FROM informix.sysprocedures
WHERE informix.sysprocedures.procname = 'read_address')
ストアド プロシジャの作成と使用
8-11
プロシジャの実行
プロシジャの実行
プロシジャを実行する方法はいろいろあります。SQL 文 EXECUTE PROCEDURE を
使用することも、SPL 文 LET や CALL を使用することもできます。8-14 ページの
「ストアド プロシジャの動的実行」で説明するようにプロシジャを動的に実行する
こともできます。
プロシジャ read_address は、顧客のフルネームと住所を返します。EXECUTE
PROCEDURE で Putnum という顧客に対して read_address を実行するには、次の文
を入力します。
EXECUTE PROCEDURE read_address (’Putnum’);
プロシジャ read_address が値を返します。SQL API または別のプロシジャでこのプ
ロシジャを実行している場合は、データを受け取るため、INTO 節を使用してホス
ト変数を指定する必要があります。たとえば、ESQL/C プログラムでプロシジャ
read_address を実行する場合、次の例に示すコード セグメントで実行されます。
#include <stdio.h>
EXEC SQL include sqlca;
EXEC SQL include sqlda;
EXEC SQL include datetime;
/* Program to execute a procedure in the database named ' play ' */
main()
{
EXEC SQL BEGIN DECLARE SECTION;
char lname[16], fname[16], address[21];
char city[16], state[3], zip[6];
EXEC SQL END DECLARE SECTION;
EXEC SQL connect to 'play';
EXEC SQL EXECUTE PROCEDURE read_address ('Putnum')
INTO :lname, :fname, :address, :city, :state, :zip;
if (sqlca.sqlcode != 0 )
printf("¥nFailure on execute");
}
8-12
Informix Guide to SQL: Tutorial
プロシジャの実行
別のプロシジャでプロシジャを実行している場合、SPL 文 CALL または LET を使
用してプロシジャを実行できます。CALL 文を使用してプロシジャ read_address を
実行する場合、次の例に示すコードを使用できます。
CREATE PROCEDURE address_list ()
DEFINE p_lname, p_fname, p_city CHAR(15);
DEFINE p_add CHAR(20);
DEFINE p_state CHAR(2);
DEFINE p_zip CHAR(5);
.
.
.
CALL read_address ('Putnum') RETURNING p_fname, p_lname,
p_add, p_city, p_state, p_zip;
.
.
.
-- use the returned data some way
END PROCEDURE;
次の例は、LET 文を使用して、プロシジャを呼び出してプロシジャ変数に値を割り
当てる方法を示しています。
CREATE PROCEDURE address_list ()
DEFINE p_lname, p_fname, p_city CHAR(15);
DEFINE p_add CHAR(20);
DEFINE p_state CHAR(2);
DEFINE p_zip CHAR(5);
.
.
.
LET p_fname, p_lname,p_add, p_city, p_state, p_zip = read_address
('Putnum');
.
.
.
-- use the returned data some way
END PROCEDURE;
AD/XP
Dynamic Server with AD and XP Options を使用すると、現行データベースと現行デー
タベース サーバのプロシジャにだけプロシジャ呼出しを行うことができます。 ♦
ストアド プロシジャの作成と使用
8-13
ストアド プロシジャの動的実行
ストアド プロシジャの動的実行
ESQL/C プログラムの ALLOCATE DESCRIPTOR 文と GET DESCRIPTOR 文を使用
しても、EXECUTE PROCEDURE 文を作成できます。パラメータをストアド プロシ
ジャに渡す方法は SELECT 文を使用する場合と同じです。パラメータは実行時でも
コンパイル時でも渡すことができます。ストアド プロシジャを動的に実行する例に
ついては、
『INFORMIX-ESQL/C Programmer’s Manual』を参照してください。動的
SQL についての説明と作成してある SELECT 文の使用方法については、第 5 章
「SQL を使用したプログラミング」を参照してください。
プロシジャのデバッグ
プロシジャを作成し実行できても、論理エラーが検出されることがあります。プロ
シジャに論理エラーが含まれている場合、TRACE 文を使用してエラーを検索する
ことができます。次のプロシジャ実体の値のトレースができます。
■
変数
■
プロシジャ引数
■
戻り値
■
SQL エラー コード
■
ISAM エラー コード
トレース結果一覧を生成するには、最初に SQL 文の SET DEBUG FILE を使用して
トレースの出力先ファイルを命名します。プロシジャを作成するときに、その
フォームのいずれかに TRACE 文を入れます。
TRACE 出力フォームは次の方法で指定します。
8-14
文
動作
TRACE ON
SQL 文を除きすべての文をトレースします。文を使用
する前に変数の内容が出力されます。プロシジャ呼出
しと戻り値のトレースが行われます。
TRACE PROCEDURE
プロシジャ呼出しと戻り値のトレースだけを行います。
TRACE < 式 >
リテラルまたは式を出力します。必要な場合、式の値
を計算してからファイルに出力します。
Informix Guide to SQL: Tutorial
プロシジャのデバッグ
次の例は、プロシジャ read_address で TRACE 文を使用する方法を示しています。
この例にはこれまでに触れていない SPL 文が含まれていますが、TRACE 文を使用
してプロシジャの実行を監視する方法が示されています。
CREATE PROCEDURE 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; -- Every expression will be traced from here on
TRACE 'Foreach starts'; -- A 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 PROCEDURE;
トレース機能付きプロシジャを実行するたびに、SET DEBUG FILE 文を使用して指
定したファイルにエントリが追加されます。デバッグ エントリを調べるには、任意
のテキスト エディタを使用して出力ファイルを表示します。
ストアド プロシジャの作成と使用
8-15
プロシジャのデバッグ
次の表に、前の例に示したプロシジャが生成する出力例を示します。トレースの文
ごとにトレース結果を説明しています。
文
動作
TRACE ON
TRACE ON 文をエコーイングします。
TRACE Foreach
starts
式、この場合はリテラル文字列 Foreach starts のトレー
スを行います。
start select cursor
FOREACH ループを処理するためカーソルがオープンさ
れたことを通知します。
select cursor iteration
選択カーソルの繰返しを開始するたびに通知します。
expression: (+lcount, 1) 検出した式 (1count+1) を評価して 2 を出力します。
let lcount = 2
LET 文ごとに値と一緒にエコーイングします。
プロシジャの再作成
プロシジャがデータベース内にある場合、同じ名前で別のプロシジャを作成するに
は、DROP PROCEDURE 文を使用して既存のプロシジャを明示的に削除する必要が
あります。プロシジャをデバッグし、同じプロシジャ名で CREATE PROCEDURE
文の使用を試みた場合、既存のプロシジャをデータベースから先に削除している場
合を除いて使用できません。
8-16
Informix Guide to SQL: Tutorial
ストアド プロシジャに対するアクセス権
ストアド プロシジャに対するアクセス権
ストアド プロシジャは、それが作成されたデータベース内にあります。ほかのデー
タベース オブジェクトの場合と同様に、ストアド プロシジャを作成するには適切
なアクセス権が必要です。ストアド プロシジャを実行するにも適切なアクセス権が
必要です。
データベースには 2 種類のストアド プロシジャ、DBA アクセス権付きプロシジャ
と所有者アクセス権付きプロシジャがあります。プロシジャを作成するときに、ど
ちらかの種類にするか指定します。作成および実行するプロシジャの種類により、
異なるアクセス権が必要です。DBA アクセス権付きプロシジャと所有者アクセス
権付きプロシジャの相違点を次の表にまとめてあります。詳細は以降の節を参照し
てください。
DBA アクセス権付きプ
ロシジャ
作成できるユーザ
所有者アクセス権付きプロシジャ
DBA アクセス権を持つ 少なくとも Resource アクセス権を持つ任意の
ユーザ
任意のユーザ
デフォルトで Execute アクセ DBA アクセス権を持つ ANSI 標準に準拠していない場合。
ス権を持つユーザ
任意のユーザ
Public(Connect データベース アクセス権を持つ任
意のユーザ )
ANSI 標準準拠の場合。プロシジャ所有者と、
DBA アクセス権を持つ任意のユーザ
ほかのユーザがプロシジャ
を実行できるようにするた
め、プロシジャの所有者ま
たは WITH 節がそのユーザ
に付与しなければならない
アクセス権
Execute アクセス権
Execute アクセス権のほかに、関連したオブジェ
クトに対するアクセス権
関連したオブジェクトに対して所有者が GRANT
WITH オプション付きのアクセス権を持ってい
る場合、Execute アクセス権だけ必要です。
ストアド プロシジャの作成と使用
8-17
作成に必要なアクセス権
作成に必要なアクセス権
DBA アクセス権付きプロシジャを作成できるのは DBA アクセス権を持っている
ユーザだけです。所有者アクセス権付きプロシジャを作成するには、少なくとも
Resource アクセス権を持っている必要があります。データベースへのアクセス権を
付与または制限する方法についての詳細は、
『Informix Guide to Database Design and
Implementation』を参照してください。
実行に必要なアクセス権
プロシジャを実行するには、そのプロシジャに対する Execute アクセス権または
DBA データベース アクセス権が必要です。データベース サーバはプロシジャが
DBA モードのプロシジャかどうかおよびデータベースが ANSI 標準準拠かどうかに
基づいて、ユーザにアクセス権を暗黙に付与します。
所有者アクセス権付きプロシジャの場合、データベース サーバは Public に対して
Execute アクセス権を付与します。データベースが ANSI 標準準拠の場合、データ
ベース サーバは所有者と、DBA ステータスを持つユーザに Execute アクセス権だけ
を付与します。
DBA アクセス権付きプロシジャの場合、データベース サーバは DBA アクセス権を
持つすべてのユーザに Execute アクセス権を付与します。
所有者アクセス権付きプロシジャ
所有者アクセス権付きプロシジャを実行する場合、データベース サーバは、参照さ
れるオブジェクトが存在するかどうか確認します。参照されるオブジェクトに対し
て必要なアクセス権を持っているかどうかも確認します。
所有しているオブジェクトだけを参照しているプロシジャを実行する場合は、アク
セス権の矛盾は発生しません。参照されるオブジェクトを所有していない場合に、
SELECT 文が入っているプロシジャを実行すると、矛盾が発生する可能性がありま
す。
所有者が必要なアクセス権を持っており、WITH GRANT オプションを使用する場
合、所有者が GRANT EXECUTE 文を発行すると、これらのアクセス権はユーザに
自動的に付与されます。
8-18
Informix Guide to SQL: Tutorial
実行に必要なアクセス権
プロシジャを実行するユーザは、プロシジャの実行中に作成された非修飾オブジェ
クトを所有しません。プロシジャの所有者が非修飾オブジェクトを所有します。次
の例は、2 つの表を作成する所有者アクセス権付きストアド プロシジャのある行を
示しています。このプロシジャの所有者が tony で、プロシジャを実行するユーザが
marty の場合、最初の表 gargantuan は tony が所有します。2 番目の表 tiny は libby が
所有します。表 gargantuan は非修飾名なので、tony が所有します。表 tiny は所有者
libby によって修飾されているので、libby が所有します。
CREATE PROCEDURE tryit()
.
.
.
CREATE TABLE gargantuan (col1 INT, col2 INT, col3 INT);
CREATE TABLE libby.tiny (col1 INT, col2 INT, col3 INT);
END PROCEDURE;
DBA アクセス権付きプロシジャ
DBA アクセス権付きプロシジャを実行する場合、プロシジャの実行中は DBA アク
セス権を所有していると想定されます。DBA アクセス権付きプロシジャは、プロ
シジャを実行するユーザに最初に DBA アクセス権が付与され、プロシジャ内の各
文を手動で実行し、最後に DBA アクセス権を取り消したかのように動作します。
DBA プロシジャの実行中に作成されたオブジェクトは、プロシジャ内のデータ定
義文で別の所有者の名前を明示的に指定している場合を除いて、プロシジャを実行
しているユーザが所有します。
アクセス権と入れ子のプロシジャ
DBA アクセス権付きの状態は、呼び出されたプロシジャには継承されません。た
とえば、DBA アクセス権付きプロシジャが所有者アクセス権付きプロシジャを実
行する場合、所有者アクセス権付きプロシジャは DBA プロシジャとしては動作し
ません。所有者アクセス権付きプロシジャが DBA アクセス権付きプロシジャを呼
び出す場合は、DBA アクセス権付きプロシジャ内の文は、通常の DBA アクセス権
付きプロシジャにあるときと同様に実行されます。
ストアド プロシジャの作成と使用
8-19
アクセス権の取消し
アクセス権の取消し
プロシジャの所有者は、ユーザに付与した Execute アクセス権を取り消すことがで
きます。ユーザがプロシジャに対して Execute アクセス権を失うと、そのユーザが
Execute アクセス権を付与したすべてのユーザについても Execute アクセス権が取り
消されます。
変数と式
ここでは、SPL で変数を定義および使用する方法について説明します。SPL 式と
SQL 式の相違についても触れます。
SPL 変数
ストアド プロシジャの変数にはいろいろな使用方法があります。定数が予想される
データベース問合せやその他の SQL 文で変数を使用できます。値を割り当てて計
算したり、問合せから返された行数を追跡したり、ほかのタスクと同様にループを
実行したりするために、SPL 文で変数を使用することもできます。
変数の値はメモリに保持されます。変数はデータベース オブジェクトではありませ
ん。したがって、トランザクションをロールバックしてもプロシジャ変数の値は復
元されません。
変数はローカル変数または広域変数として定義できます。デフォルトの場合、ロー
カル変数です。以降の節では、この 2 種類の変数の相違について説明します。
ローカル変数
ローカル変数は、それを定義しているプロシジャ内でだけ使用できます。ローカル
変数の場合、コンパイル時にデフォルト値を割り当てることはできません。
8-20
Informix Guide to SQL: Tutorial
SPL 変数
広域変数
広域変数は、同じデータベース内の同じユーザ セッションが実行するプロシジャで
あればどのプロシジャでも使用できます。広域変数の値はメモリ内に格納されま
す。広域環境は、所定のデータベース サーバ上の所定のセッション内で実行される
すべてのプロシジャ (SQL API が実行するすべてのプロシジャ、または DB-Access
セッションまたはリレーショナルオブジェクトマネージャセッション内のすべての
プロシジャなど ) が使用するメモリです。変数の値は、セッションの終了時に消失
します。
広域変数の場合、コンパイル時にデフォルト値を割り当てる必要があります。
広域変数の最初の定義では、変数を広域環境に入れます。同じ変数を別のプロシ
ジャで以降に定義する場合は、変数を広域環境にバインドするだけです。
ストアド プロシジャで定義する広域変数は、同じセッションで実行されるそれ以外
のすべてのプロシジャでアクセスできます。複数のストアド プロシジャが 1 つの広
域変数を変更する場合、データベース サーバは一度に 1 つのストアド プロシジャ
だけが変数を変更するようにします。
IDS
AD/XP
Dynamic Server は、広域変数が連続して一貫するようにしています。 ♦
Dynamic Server with AD and XP Options は、連続した一貫性を保証しません。ストア
ド プロシジャが実行される順番を予想することはできません。 ♦
変数のフォーマット
変数は SQL 識別子の規則に従います。SQL 識別子についての詳細は、『Informix
Guide to SQL: Syntax』を参照してください。変数を定義したら、プロシジャ内のど
こででも使用できます。
SQL API を使用している場合は、(SQL API でホスト変数を使用する場合と違って )
特殊な記号を使用して変数を区切る必要はありません。
変数の定義
変数を定義するには、DEFINE 文を使用します。プロシジャの引数リストに変数を
記載すると、その変数は暗黙に定義されるので、DEFINE 文を使用して明示的に定
義する必要はありません。変数を使用するには、事前に値を割り当てる必要があり
ます。値は NULL でもかまいません。DEFINE 文についての詳細は、『Informix
Guide to SQL: Syntax』を参照してください。
ストアド プロシジャの作成と使用
8-21
SPL 変数
変数のデータ型
変数のデータ型は、表内の列が使用できる型ならばどれにでも定義できます。ただ
しシリアル (SERIAL) 型として定義することはできません。次は、プロシジャ変数
の定義例を示しています。
DEFINE x INT;
DEFINE name CHAR(15);
DEFINE this_day DATETIME YEAR TO DAY ;
テキスト (TEXT) 型またはバイト (BYTE) 型の変数を定義する場合、変数には実際
にはデータが入りません。その代わりに、変数はデータへのポインタの役割をしま
す。しかし、このプロシジャ変数は、ほかのプロシジャ変数と使用方法は変わりま
せん。テキスト (TEXT) 型またはバイト (BYTE) 型変数を定義する場合、これらの
変数はデータを持っていずデータを参照しているだけであることを強調するために
REFERENCES という語を使用する必要があります。次の例は、テキスト (TEXT) 型
変数とバイト (BYTE) 型変数の定義を示しています。
DEFINE ttt REFERENCES TEXT;
DEFINE bbb REFERENCES BYTE;
変数でのサブスクリプトの使用
SQL 列名の場合と同様に、文字 (CHAR) 型、可変長文字 (VARCHAR) 型、各国語文
字 (NCHAR) 型、各国語可変長 (NVARCHAR) 型、バイト (BYTE) 型、またはテキス
ト (TEXT) 型の変数と一緒にサブスクリプトを使用できます。サブスクリプトは変
数文字の開始位置と終了位置を示します。サブスクリプトは常に定数である必要が
あります。変数をサブスクリプトとして使用することはできません。次の例はサブ
スクリプトの使用方法を示しています。
DEFINE name CHAR(15);
LET name[4,7] = 'Ream';
SELECT fname[1,3] INTO name[1,3] FROM customer
WHERE lname = 'Ream';
2 つのサブスクリプトで区切られた変数の定数部分を、副文字列といいます。
変数の有効範囲
変数は、変数が定義された文ブロック内だけで有効です。同じ名前の変数の再定義
によりマスクされている場合を除いて、その文ブロック内に入れ子にされている文
ブロック内でも有効です。
8-22
Informix Guide to SQL: Tutorial
SPL 変数
次に示すプロシジャの最初で、整数の変数 x、y、z が定義され、初期化されていま
す。BEGIN 文と END 文は入れ子になっている文ブロックの開始と終了を示しま
す。入れ子になっている文ブロック内では、文字 (CHAR) 型変数 z だけでなく、整
数変数 x と q が定義されています。また、入れ子のブロック内では、再定義変数 x
が元の変数 x をマスクしています。入れ子ブロックの終了をマークしている END
文の後では、x の元の値に再度アクセスできます。
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;
変数とキーワードの混同
変数をキーワードとして定義する場合、混同する可能性があります。識別子に関す
る次の規則に従うと、変数、プロシジャ名、システム関数名が混同して使用される
のを避けることができます。
■
定義済み変数の優先順位を最も高くします。
■
DEFINE 文などで定義したプロシジャの優先順位を SQL 関数の優先順位よ
り高くします。
■
SQL 関数の優先順位を、DEFINE 文内にあるがプロシジャとして識別され
ていないプロシジャの優先順位より高くします。
場合によっては、変数名を変更しなければならないことがあります。たとえば、
count や max は集計関数名なので、変数名として定義することはできません。混同
して使用される可能性があるキーワードの一覧は、
『Informix Guide to SQL: Syntax』
の識別子の部分を参照してください。
ストアド プロシジャの作成と使用
8-23
SPL 変数
変数と列名
プロシジャ変数に対して、列名で使用するのと同じ識別子を使用すると、データ
ベース サーバは識別子の各インスタンスを変数として想定します。識別子を列名と
して使用するには、列名に表名を付けて修飾します。次の例では、プロシジャ変数
lname が列名と同じです。次の SELECT 文で、customer.lname は列名、lname は変数
名です。
CREATE PROCEDURE table_test()
DEFINE lname CHAR(15);
LET lname = 'Miller';
.
.
.
SELECT customer.lname FROM customer INTO lname
WHERE customer_num = 502;
.
.
.
変数と SQL 関数
プロシジャ変数に対して、SQL 関数で使用するのと同じ識別子を使用すると、デー
タベース サーバは、識別子のインスタンスは変数と想定し、SQL 関数を使用できな
くします。変数が定義されているコード ブロック内では SQL 関数を使用できませ
ん。次の例では、変数 user が定義されているプロシジャ内のブロックを示していま
す。この定義では、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
8-24
Informix Guide to SQL: Tutorial
SPL 式
プロシジャ名と SQL 関数
プロシジャ名と SQL 関数名の混同については、
『Informix Guide to SQL: Syntax』を
参照してください。
SPL 式
ストアド プロシジャでは、集計式を除いてすべての SQL 式を使用できます。SQL
式の完全な構文と説明については、
『Informix Guide to SQL: Syntax』を参照してくだ
さい。
次の例は、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)
変数への値の割当て
プロシジャ変数に値を割り当てる方法は次のとおりです。
■
LET 文の使用
■
SELECT...INTO 文の使用
■
RETURNING 節があるプロシジャでの CALL 文の使用
■
EXECUTE PROCEDURE...INTO 文の使用
1 つまたは複数の変数に値を割り当てるには、LET 文を使用します。次の例は、
LET 文のいろいろな形を示しています。
LET a = b + a;
LET a, b = c, d;
LET a, b = (SELECT fname, lname FROM customer
WHERE customer_num = 101);
LET a, b = read_name(101);
ストアド プロシジャの作成と使用
8-25
プログラムの流れの制御
データベースの値を直接変数に割り当てるには、SELECT 文を使用します。次の例
に示す文は、前の例の 3 番目の LET 文と同じ役割をはたします。
SELECT fname, lname into a, b FROM customer
WHERE customer_num = 101
プロシジャが返した値を 1 つまたは複数のプロシジャ変数に割り当てるには、
CALL 文または EXECUTE PROCEDURE 文を使用します。次の例の文はどちらもプ
ロシジャ read_address から完全な住所データを指定されたプロシジャ変数に返しま
す。
EXECUTE PROCEDURE 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;
プログラムの流れの制御
ストアド プロシジャ言語 (SPL) には、ストアド プロシジャの流れを制御し実行時に
取り出したデータに基づいて意思決定するための文がいくつかあります。ここで
は、プログラムの流れを制御する文について簡単に説明します。これらの文の構文
と詳細については、
『Informix Guide to SQL: Syntax』を参照してください。
分岐
ストアド プロシジャ内で論理の分岐を生成するには IF 文を使用します。IF 文は最
初に条件を評価し、その条件が真の場合、文の THEN 部分に含まれている文ブロッ
クが実行されます。条件が真でない場合、IF 文に ELSE 句または ELIF(ELSE IF) 節
が含まれている場合を除いて、実行は次の文に移ります。次は IF 文の例を示して
います。
CREATE PROCEDURE str_compare (str1 CHAR(20), str2 CHAR(20))
RETURNING INT;
DEFINE result INT;
IF str1 > str2 THEN
result = 1;
ELIF str2 > str1 THEN
8-26
Informix Guide to SQL: Tutorial
ループ
result = -1;
ELSE
result = 0;
END IF
RETURN result;
END PROCEDURE; -- str_compare
ループ
次の表に、SPL でループを実行するために使用できる 3 つの文を示します。
文
動作
FOR
制御付きループを開始します。終了が保証されていま
す。
FOREACH
ユーザがデータベースから複数行を選択し操作できま
す。暗黙にカーソルを宣言しオープンします。
WHILE
ループを開始します。終了は保証されていません。
次の表は、ループを終了するために使用できる文を示しています。
文
動作
CONTINUE
在のループ内の残りの文をスキップし、そのループの最
初から再度開始します。
EXIT
現在のループを終了します。ループの直後の文から実行
が再開されます。
RETURN
プロシジャを終了します。戻り値が指定されている場
合、終了時にその値が返されます。
RAISE EXCEPTION
外がループ本体内でトラップ ( 捕捉 ) されなかった場合、
ループを終了します。
これらの文の構文と使用方法についての詳細は、
『Informix Guide to SQL: Syntax』を
参照してください。
ストアド プロシジャの作成と使用
8-27
関数の処理
関数の処理
プロシジャからオペレーティング システム コマンドを実行するだけでなく、プロ
シジャを呼び出すこともできます。
プロシジャ内でのプロシジャの呼出し
プロシジャからプロシジャを実行するには、CALL 文または SQL 文 EXECUTE
PROCEDURE を使用します。次の例は、CALL 文を使用してプロシジャ read_name
を呼び出す方法を示しています。
CREATE PROCEDURE call_test()
RETURNING CHAR(15), CHAR(15);
DEFINE fname, lname CHAR(15);
CALL read_name('Putnum') RETURNING fname, lname;
IF fname = 'Eileen' THEN RETURN 'Jessica', lname;
ELSE RETURN fname, lname;
END IF
END PROCEDURE;
プロシジャからのオペレーティング システム コマンドの実行
UNIX
プロシジャからシステム呼出しを実行するには、SYSTEM 文を使用します。次の例
は、echo コマンドを呼び出す方法を示しています。
CREATE DBA PROCEDURE delete_customer(cnum INT)
DEFINE username CHAR(8);
DELETE FROM customer
WHERE customer_num = cnum;
IF username = 'acctclrk' THEN
SYSTEM 'echo ''Delete from customer by acctclrk'' >>
/mis/records/updates' ;
END IF
END PROCEDURE; -- delete_customer
♦
8-28
Informix Guide to SQL: Tutorial
プロシジャとの情報の受渡し
WIN NT
プロシジャからシステム呼出しを実行するには、SYSTEM 文を使用します。次の例
では、最初の SYSTEM 文は、Windows NT オペレーティング システムが一時ファイ
ルにエラー メッセージを送り、アルファベット順にソートされてシステム ログに
そのメッセージを書き込むようにします。2 番目の SYSTEM 文は、オペレーティン
グ システムが一時ファイルを削除するようにします。
CREATE PROCEDURE test_proc()
.
.
.
SYSTEM 'type errormess101 > %tmp%tmpfile.txt |
sort >> %SystemRoot%systemlog.txt';
SYSTEM 'del %tmp%tmpfile.txt';
.
.
.
END PROCEDURE; --test_proc
この例の SYSTEM 文の後に続く式には、2 つの変数 %tmp% と %SystemRoot% があ
ります。Windows NT オペレーティング システムは、これらの変数を両方とも定義
しています。 ♦
プロシジャの再帰的呼出し
プロシジャはそのプロシジャ自身から呼び出すことができます。プロシジャの再帰
的呼出しには制限はありません。
プロシジャとの情報の受渡し
プロシジャを作成するときに、プロシジャに情報が渡されるかどうかを決めるため
に引数の並びを指定します。プロシジャが受け取る情報ごとに、1 つの引数とその
引数のデータ型を指定します。
たとえば、1 つの整数情報を渡されることをプロシジャが要求する場合、次の例の
ようにプロシジャの冒頭部分を作成します。
CREATE PROCEDURE safe_delete(cnm INT)
ストアド プロシジャの作成と使用
8-29
結果の返戻
結果の返戻
1 つまたは複数の値を返すプロシジャの場合、情報を転送するための 2 行のコード
が含まれている必要があります。1 行は返されるデータ型を指定するもので、もう
1 行は値を明示的に返すためのものです。
戻りデータ型の指定
プロシジャの名前と入力パラメータを指定した直後に、予想する戻り値のデータ型
を指定する RETURNING 節を指定する必要があります。次の例は、1 つの整数の入
力を予想し、1 つの整数と 1 つの 10 バイト文字値を返すプロシジャの冒頭部分 ( 名
前、パラメータ、RETURNING 節 ) を示しています。
CREATE PROCEDURE get_call(cnum INT)
RETURNING INT, CHAR(10);
値の返戻
戻り値のデータ型を示すため RETURNING 節を使用すると、プロシジャ内のどこで
も RETURN 文を使用して REETURNING 節に表示されたのと同じ数と同じデータ
型の値を返すことができます。次の例は、プロシジャ get_call から情報を返す方法
を示しています。
CREATE PROCEDURE get_call(cnum INT)
RETURNING INT, CHAR(10);
DEFINE ncalls INT;
DEFINE o_name CHAR(10);
.
.
.
RETURN ncalls, o_name;
.
.
.
END PROCEDURE;
RETURN 文を記述しなくても、コンパイル時にエラー メッセージが返されること
はありません。
8-30
Informix Guide to SQL: Tutorial
結果の返戻
プロシジャからの複数の値セットの返戻
データベースから複数行を返すことができる SELECT 文をプロシジャが実行する場
合、またはループ内から値を返す場合、RETURN 文でキーワード WITH RESUME
を使用する必要があります。RETURN...WITH RESUME 文を使用すると、1 つまた
は複数の値が呼出し元のプログラムまたはプロシジャに返されます。呼出し元のプ
ログラムが値を受け取った後、RETURN...WITH RESUME 文の直後の文に制御が戻
され、実行されます。
次の例は、概括プロシジャを示しています。これは FOREACH ループと FOR ロー
プから値を返します。このようなプロシジャは、FOREACH ループを持っているの
で概括プロシジャといいます。
CREATE PROCEDURE read_many (lastname CHAR(15))
RETURNING CHAR(15), CHAR(15), CHAR(20), CHAR(15),CHAR(2),
CHAR(5);
DEFINE
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 INT ;
i INT ;
LET lcount = 0;
TRACE ON;
CREATE VIEW myview AS SELECT * FROM customer;
TRACE 'Foreach starts';
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;
END FOREACH;
FOR i IN (1 TO 5)
BEGIN
RETURN 'a', 'b', 'c', 'd', 'e' WITH RESUME;
END
END FOR;
END PROCEDURE;
ストアド プロシジャの作成と使用
8-31
例外処理
このプシジャを実行すると、指定された姓をもつ人ごとにその名前と住所が返され
ます。一連の文字も返されます。呼出し元のプロシジャまたはプログラムは複数の
戻り値があることを想定する必要があり、カーソルまたは FOREACH 文を使用し
て、複数の戻り値を処理する必要があります。
例外処理
データベースがプロシジャに返す例外 ( つまりエラー ) またはプロシジャが呼び出
す例外をトラップする場合、ON EXCEPTION 文を使用できます。RAISE
EXCEPTION 文を使用すると、プロシジャ内で例外を生成できます。
エラーのトラップと回復
ON EXCEPTION 文はエラーをトラップします。
エラーをトラップするには、一連の文を 1 つの文ブロックに入れ、その文ブロック
の前に ON EXCEPTION 文を置きます。ON EXCEPTION 文の後に続くブロック内で
エラーが発生した場合、回復処理を実行できます。
次の例は、BEGIN...END ブロック内の ON EXCEPTION 文を示しています。
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
8-32
Informix Guide to SQL: Tutorial
ON EXCEPTION 文の制御の有効範囲
END EXCEPTION WITH RESUME
INSERT INTO t VALUES (10); -- will fail if t does not exist
LET c = (SELECT d FROM t); -- will fail if d does not exist
END
エラーが発生すると、SPL インタープリタが、エラーをトラップする最も内側の
ON EXCEPTION 宣言を探索します。エラーをトラップしたら、まず最初にエラー
をリセットします。エラー処理コードの実行が完了し、呼び出された ON
EXCEPTION 宣言にキーワード WITH RESUME が含まれている場合、エラーが発生
した文の次の文から実行が自動的に再開されます。ON EXCEPTION 宣言にキー
ワード WITH RESUME が含まれていない場合、現在のブロックの実行が完全に終
了します。
ON EXCEPTION 文の制御の有効範囲
ON EXCEPTION 文は、ON EXCEPTION 文の後に続く文ブロック、その後続文ブ
ロック内のすべての入れ子文ブロック、ON EXCEPTION 文の後に続くすべての文
ブロックに対して有効です。ただし、ON EXCEPTION 文がある文ブロック内では
有効ではありません。
次の例は、プロシジャ内で例外が有効な範囲を示しています。つまり、指定したブ
ロックのどれかでエラー 201 が発生した場合、a201 という処理が実行されます。
CREATE PROCEDURE scope()
DEFINE i INT;
.
.
.
BEGIN
-- begin statement block A
.
.
.
ON EXCEPTION IN (201)
-- do action a201
END EXCEPTION
BEGIN -- statement block aa
ストアド プロシジャの作成と使用
8-33
ユーザ生成の例外
-- 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;
ユーザ生成の例外
RAISE EXCEPTION 文を使用すると、次の例に示すように自分でエラーを生成でき
ます。この例では、ON EXCEPTION 文が 2 つの変数 esql と eisam を使用して、
データベース サーバが返すエラー番号を保持します。エラーが発生し、SQL エラー
番号が -206 の場合、IF 節が実行されます。それ以外の SQL エラーがトラップされ
た場合、この BEGIN...END ブロックから前の例の最後の BEGIN...END ブロックに
制御が移り、それが実行されます。
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
SQL エラーのシミュレート
SQL エラーをシミュレートするため、次の例に示すようにエラーを生成できます。
ユーザが pault の場合、ストアド プロシジャはそのユーザが実際には更新アクセス
権を持っていても持っていないかのように動作します。
BEGIN
IF user = 'pault' THEN
RAISE EXCEPTION -273; -- deny Paul update privilege
END IF
END
8-34
Informix Guide to SQL: Tutorial
ユーザ生成の例外
入れ子コードを終了するための RAISE EXCEPTION の使用
次の例は、RAISE EXCEPTION 文を使用して何重にも入れ子になったブロックを終
了する方法を示しています。最も内側の条件が真 (aa が負 ) の場合、例外が呼び出
され、ブロックの END の後のコードに制御が移りそのコードが実行されます。こ
の場合、TRACE 文に実行が移ります。
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
BEGIN...END ブロックは 1 つの文であることに注意してください。ブロック内でエ
ラーが発生し、そのブロックの外でトラップされた場合、実行が再開されたときに
ブロックの残りはスキップされ、次の文で実行が再開されます。
ブロック内のこのエラーについてトラップを設定する場合を除いて、エラー条件は
呼出しが入っているブロックに返され、そのブロックが入っているすべてのブロッ
クにも返されます。エラーを処理するように設定された ON EXCEPTION 文が存在
しない場合、プロシジャの実行は停止し、そのプロシジャを実行しているプログラ
ムまたはプロシジャに対してエラーが作成されます。
ストアド プロシジャの作成と使用
8-35
まとめ
まとめ
ストアド プロシジを使用すると、データベース性能の向上、アプリケーションの簡
略化、データ アクセスの制限または監視などのデータベース処理の効率を上げるこ
とができます。SPL 文の構文ダイヤグラムについては、
『Informix Guide to SQL:
Syntax』を参照してください。
8-36
Informix Guide to SQL: Tutorial
第9章
トリガの作成と使用
トリガを使用するタイミング .
. . .
. . .
. . .
. . .
. .
9-3
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
9-4
9-5
9-5
9-6
9-7
トリガアクションの使用方法 . . . . . . . . . . . . .
BEFORE および AFTER トリガアクションの使用方法 . . . . .
FOR EACHROW トリガアクションの使用方法 . . . . . . .
REFERENCING 節の使用方法 . . . . . . . . . .
WHEN 条件の使用方法 . . . . . . . . . . . .
ストアドプロシジャのトリガアクションとしての使用方法 . . .
ストアドプロシジャへのデータの引渡し . . . . . . .
ストアドプロシジャ言語の使用方法. . . . . . . . .
ストアドプロシジャからのデータを使用した非トリガ列の更新.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
9-7
9-7
9-9
9-9
9-10
9-11
9-11
9-12
9-12
Dynamic Server 用の再入可能トリガ
. .
9-13
トリガアクションのトレース . . . . . . . . . . . . . . .
ストアド プロシジャ内の TRACE 文の例 . . . . . . . . . .
TRACE 出力の例 . . . . . . . . . . . . . . . . .
9-13
9-14
9-14
エラーメッセージの生成 . . . . .
固定エラーメッセージの適用 . . .
可変エラーメッセージの生成 . . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. . .
. .
. .
. .
9-15
9-15
9-17
まとめ . . .
. . .
. . .
. . .
. .
9-18
トリガの作成方法 . . . . . .
トリガ名の割当て . . . . .
トリガイベントの指定 . . . .
トリガアクションの定義 . . .
完全な構成の CREATE TRIGGER 文
. . .
. .
.
.
.
.
.
. .
. . .
.
.
.
.
.
.
.
.
.
.
. . .
.
.
.
.
.
.
.
.
.
.
. . .
.
.
.
.
.
. . .
9-2
Informix Guide to SQL: Tutorial
SQL トリガは、データベースに存在している機構です。使用許可さえ受けていれ
ば、どのようなユーザでも使用することができます。SQL トリガは、特定の表に対
して挿入、削除、更新などの特定の操作を行う場合に、データベースサーバが自動
的に一つまたは複数の追加動作を実行するように指定します。追加動作としては、
INSERT 文 DELETE 文、UPDATE 文、または EXECUTE PROCEDURE 文が可能で
す。
この章では、CREATE TRIGGER 文の各要素の目的を説明して、トリガの使用例を
紹介します。また、トリガアクションとしてストアドプロシジャを使用する場合の
利点についても触れます。
AD/XP
Informix Dynamic Server with Advanced Decision Support and Extended Parallel Options は
SQL トリガをサポートしません。 ♦
トリガを使用するタイミング
トリガはデータベース内に存在し、必要なアクセス権を持つユーザは誰でも使用で
きるので、トリガを使用して複数のアプリケーションで使える一連の SQL 文を書
くことができます。トリガを使えば、複数のプログラムが同じデータベース操作を
実行する必要がある場合に、コードが冗長になりません。
トリガを使用して、次の動作や、このリスト以外の動作を実行することができま
す。
■
データベースでの動作更新記録を作成します。たとえば、監査表に対する
確認情報を更新することによって、表 orders に対する更新を追跡すること
ができます。
■
ビジネスルールの実現。たとえばオーダーが顧客の信用限度を超える条件
を決めて、それに応じたメッセージを表示することができます。
トリガの作成と使用
9-3
トリガの作成方法
■
表やデータベース内で使用できない補助データの導出。たとえば表 items の
列 quantity が更新されると、それに応じて列 total_price を計算し直すこと
ができます。
■
参照整合性の確保。たとえば、ある顧客を削除するときに、トリガを使用
して表 orders 内の対応する行 ( 同じ顧客番号を持つ行 ) を削除することが
できます。
トリガの作成方法
トリガの作成には、CREATE TRIGGER 文を使用します。CREATE TRIGGER 文は
SQL 文を表に対する発端動作と関連付けるデータ定義文です。発端動作が行われる
と、データベースに格納されている関連付けられた SQL 文がトリガされます。図
9-1 に、発端動作、つまりトリガイベントとその動作によって引き起こされるトリ
ガアクションの関係をまとめます。
図 9-1
トリガイベントと
トリガアクション
UPDATE
item_num
2
3
4
5
quantity
total_price
3
1
4
1
15.00
236.00
100.00
280.00
EXECUTE PROCEDURE
upd_items
トリガイベント
CREATE TRIGGER 文は、次の動作を実行する節から構成されます。
9-4
■
トリガ名の割当て
■
トリガイベント、つまり、表とトリガを開始する動作の型の指定
■
トリガされる SQL 動作の定義
Informix Guide to SQL: Tutorial
トリガ名の割当て
REFERENCING 節と呼ばれているオプションの節については、9-9 ページの「FOR
EACHROW トリガアクションの使用方法」で説明します。
トリガの作成は、DB-Access、リレーショナルオブジェクトマネージャ、もしくは
SQL API を使用して行えます。ここでは、DB-Access およびリレーショナルオブ
ジェクトマネージャで対話型問合せ言語オプションを使用して入力する CREATE
TRIGGER 文について説明します。SQL API では、文の前に埋込み文であることを
示す記号またはキーワードを付けます。
トリガ名の割当て
トリガは、トリガ名によって識別されます。トリガ名は文中の CREATETRIGGER
の後に指定します。トリガ名の長さは最高 18 文字で、先頭が文字、その後は文字
と 0 ∼ 9 までの数字とアンダスコアで構成することができます。次の例の CREATE
TRIGGER 文では、トリガに upqty という名前を割り当てています。
CREATE TRIGGER upqty
-- assign trigger name
トリガイベントの指定
トリガイベントは、トリガを起動する一種の文です。この種の文が表に対して実行
されると、データベースサーバは、トリガアクションを構成する SQL 文を実行し
ます。トリガイベントには、INSERT 文、DELETE 文、UPDATE 文を指定すること
ができます。UPDATE トリガイベントを定義すると、表の列名を一つ以上指定して
トリガを起動することができます。列名を指定しない場合、表のどの列が更新され
てもトリガが起動されます。INSERT トリガと DELETE トリガは、一つの表に一つ
しか作成できませんが、トリガ列が互いに排他的な関係を持つ限り、UPDATE トリ
ガを複数作成することができます。
次の CREATE TRIGGER 文の例では、表 items の列 quantity の更新動作として、ト
リガイベントが定義されています。
CREATE TRIGGER upqty
UPDATE OF quantity ON items -- an UPDATE trigger event
トリガの作成と使用
9-5
トリガアクションの定義
文のこの部分は、トリガを作成する表を特定しています。トリガイベントが挿入ま
たは削除の場合、次の例に示すように、この種の文と表名のみが必要になります。
CREATE TRIGGER ins_qty
INSERT ON items
-- an INSERT trigger event
トリガアクションの定義
トリガアクションは、トリガイベントが発生したときに実行される SQL 文です。
トリガアクションは、INSERT 文、DELETE 文、UPDATE 文、または EXECUTE
PROCEDURE 文で構成することができます。ただし実行する動作の指定だけでな
く、トリガ文を基準にして実行するタイミングも指定しなければなりません。この
タイミングは次のいずれかです。
■
トリガ文の実行前
■
トリガ文の実行後
■
トリガ文の影響を受けるそれぞれの行ごと
一つのトリガで、このようなそれぞれのタイミングに対して、実行する処理を定義
することができます。
トリガされるアクションを定義するときは、実行されるタイミングと、実行する
SQL 文を指定してください。アクションを実行するタイミングとして、キーワード
BEFORE、AFTER、FOR EACH ROW のいずれかを指定し、その後にトリガアク
ションをカッコに入れて指定します。次のトリガアクション定義は、ストアドプロ
シジャ upd_items_p1 がトリガ文の前に実行されることを指定します。
BEFORE(EXECUTE PROCEDURE upd_items_p1) -- a BEFORE action
9-6
Informix Guide to SQL: Tutorial
完全な構成の CREATE TRIGGER 文
完全な構成の CREATE TRIGGER 文
トリガ名節、トリガイベント節、およびトリガアクション節を結合します。完全な
CREATE TRIGGER 文を定義するには、次の CREATE TRIGGER 文は、上記の例の
文のコンポーネントを結合したものです。このトリガは、表 items の列 quantity が
更新されると必ず、ストアドプロシジャ upd_items_p1 を実行します。
CREATE TRIGGER upqty
UPDATE OF quantity ON items
BEFORE(EXECUTE PROCEDURE upd_items_p1)
CREATE TRIGGER 文を処理するときに、トリガ定義内のデータベースオブジェク
ト ( たとえば、この例のストアドプロシジャ upd_items_p1) が存在しない場合、デー
タベースサーバはエラーを返します。
トリガアクションの使用方法
トリガを効果的に使用するには、トリガ文とそれによって引き起こされるトリガア
クションの関係を理解する必要があります。トリガアクションを発生させるタイミ
ング、つまり BEFORE、AFTER、および FOR EACH ROW のいずれかを指定すると
きに、この関係を定義してください。
BEFORE および AFTER トリガアクションの使用方法
トリガイベントの前または後に起こるトリガアクションは、1 回のみ実行されます。
BEFORE トリガアクションは、トリガ文の前、つまりトリガイベントの発生前に実
行されます。AFTER トリガアクションは、トリガ文のアクションの完了後に実行
されます。また、BEFORE トリガアクションと AFTER トリガアクションは、トリ
ガ文によって行が処理されない場合も実行されます。
トリガの作成と使用
9-7
BEFORE および AFTER トリガアクションの使用方法
使い方はいろいろありますが、特に、トリガ文の影響を調べるために、BEFORE ト
リガアクションと AFTER トリガアクションを使用することができます。たとえば
次の例に示されているように、表 items の列 quantity を更新する前に、ストアドプ
ロシジャ upd_items_p1 を呼び出して、表内のすべての品目に対するオーダーの合計
数量を計算することができます。このプロシジャは、old_qty と呼ばれる広域変数に
合計数量を格納します。
CREATE PROCEDURE upd_items_p1()
DEFINE GLOBAL old_qty INT DEFAULT 0;
LET old_qty = (SELECT SUM(quantity) FROM items);
END PROCEDURE;
トリガ更新の終了後、再び合計数量を計算してどのくらい変化したかを調べること
ができます。次のストアドプロシジャ 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 文によってトリガが終了されて、エラーになり
ます。トリガがデータベースサーバで失敗し、データベースにログ機能がある場合
には、データベースサーバは、トリガ文とトリガアクションの両方によって加えら
れた変更をロールバックします。トリガ失敗時に何が発生するかについての詳しい
説明は、
『Informix Guide to SQL: Syntax』の CREATE TRIGGER 文を参照してくださ
い。
9-8
Informix Guide to SQL: Tutorial
FOR EACHROW トリガアクションの使用方法
FOR EACHROW トリガアクションの使用方法
FOR EACH ROW トリガアクションは、トリガ文が影響を与える各行に対して一回
ずつ実行されます。たとえば、トリガ文が次の構文を持っているとします。
UPDATE items SET quantity = quantity * 2 WHERE manu_code = 'KAR'
FOR EACH ROW トリガアクションは、列 manu_code が値 ‘ KAR’ を持つ表 items の
各行に対して一回ずつ実行されます。
トリガ文によって行が処理されない場合には、FOR EACH ROW トリガアクション
は実行されません。
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 節では、列名と結合できる二つのプレフィクスを作成することがで
きます。一つは列の元の値の参照用、もう一つは列の新しい値の参照用です。これ
らのプレフィクスを関連名と呼びます。これらの関連名は、要求に応じて、一つあ
るいは、両方作成することもできます。どちらを作成するかは、キーワード OLD
と NEW を使用して指定します。次の REFERENCING 節では、関連名として
pre_upd と post_upd を作成して、行の元の値と新しい値を参照しています。
REFERENCING OLD AS pre_upd NEW AS post_upd
トリガの作成と使用
9-9
FOR EACHROW トリガアクションの使用方法
次のトリガアクションは、表 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 トリガアクション内の SQL 文では、文がトリガアクションから
独立して有効になる場合を除いて、必ず列名といっしょに関連名を使用しなければ
なりません。詳細は、
『Informix Guide to SQL: Syntax』の CREATE TRIGGER 文を
参照してください。
WHEN 条件の使用方法
オプションとして、トリガアクションの前に WHEN 節を使用し、検査の結果に基
づくアクションを実行することができます。WHEN 節は、最初にキーワード
WHEN、その後にカッコで囲った条件文を続けます。つまり、CREATE TRIGGER
文では、キーワード BEFORE、AFTER、または FOR EACH ROW の後に WHEN 節
を使用し、その後にトリガアクションの並びを指定してください。
WHEN 条件が存在していて、その条件が真の場合には、トリガアクションは、指定
されたアクションの並びの順に実行されます。偽または真偽不明の場合には、トリ
ガアクションの並びのアクションは実行されません。トリガに FOR EACH ROW の
指定がある場合は、WHEN 条件は行ごとにも評価されます。
次のトリガの例では、トリガアクションは WHEN 節の中の条件が真である場合の
み実行されます。つまり、更新後の単価が更新前の単価の 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))
9-10
Informix Guide to SQL: Tutorial
ストアドプロシジャのトリガアクションとしての使用方法
『Informix Guide to SQL: Syntax』の第 1 章の CREATE
WHEN 条件についての詳細は、
TRIGGER 文を参照してください。
ストアドプロシジャのトリガアクションとしての使用方法
トリガのもっとも画期的な機能の一つは、トリガアクションとしてストアドプロシ
ジャを呼び出せることです。ストアドプロシジャを呼び出す EXECUTE
PROCEDURE 文を使用すると、トリガ表からストアドプロシジャにデータを渡すこ
とができる他、ストアドプロシジャが返した値でトリガ表を更新することもできま
す。SPL では、変数を定義して値を割り当て、比較を行ったり、プロシジャ文を使
用して、トリガアクション内で複雑な処理をすることができます。
ストアドプロシジャへのデータの引渡し
EXECUTE PROCEDURE 文の引数の並びを使用して、ストアドプロシジャにデータ
を渡すことができます。下記のトリガ例では、EXECUTE PROCEDURE 文で、表
items の列 quantity と列 total_price の値が、ストアドプロシジャ calc_totpr に渡され
ます。
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)
ストアドプロシジャにデータを渡すと、プロシジャが実行する操作でそのデータを
使用できます。
トリガの作成と使用
9-11
ストアドプロシジャのトリガアクションとしての使用方法
ストアドプロシジャ言語の使用方法
前の例のトリガ内の EXECUTE PROCEDURE 文は、次の例に示すストアド プロシ
ジャを呼び出します。このプロシジャは、表 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 はトリガ表から直接入手できないデータをトリガに導出させてい
ます。
ストアドプロシジャからのデータを使用した非トリガ列の更新
トリガアクション内で、EXECUTE PROCEDURE 文の INTO 節を使用して、トリガ
表の非トリガ列を更新することができます。次の例の EXECUTE PROCEDURE 文
は、列 total_price を参照する、INTO 節の入ったストアドプロシジャ calc_totpr を呼
び出します。
FOR EACH ROW(EXECUTE PROCEDURE calc_totpr(pre_upd.quantity,
post_upd.quantity, pre_upd.total_price) INTO total_price);
total_price に入る更新値は、ストアドプロシジャの終りの RETURN 文によって返さ
れます。トリガ文の影響を受ける各行に対して、列 total_price( 合計金額 ) が更新さ
れます。
9-12
Informix Guide to SQL: Tutorial
Dynamic Server 用の再入可能トリガ
IDS
Dynamic Server 用の再入可能トリガ
Dynamic Server は再入可能トリガをサポートします。再入可能トリガは、トリガ ア
クションがトリガ表を参照できるケースを指します。言い換えると、トリガ イベン
トとトリガ アクションの両方が同じ表で動作できます。たとえば、次の 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 に対するト
リガ アクションは無効です。
トリガが再入可能な場合とそうでない場合についての規則の一覧は、
『Informix
Guide to SQL: Syntax』の CREATE TRIGGER 文を参照してください。
トリガアクションのトレース
トリガアクションが期待どおりに動作しない場合は、ストアドプロシジャに入れ、
SPL TRACE 文を使用して動作を監視してみてください。トレースを開始する前に
SET DEBUG FILE TO 文を使用してトレース結果がファイルに出力されるようにし
ます。
トリガの作成と使用
9-13
ストアド プロシジャ内の TRACE 文の例
ストアド プロシジャ内の TRACE 文の例
次の例は、ストアド プロシジャ 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'; -- modify this pathname according to the
-- conventions that your operating system requires
TRACE 'begin trace';
TRACE ON;
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 出力の例
次の例は、SET DEBUG FILE TO 文で命名されるファイル内にあるときのプロシ
ジャ items_pct からのトレース出力の例を示しています。プロシジャ変数とプロシ
ジャ引数の値、戻り値、エラーコードが示されています。
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)
9-14
Informix Guide to SQL: Tutorial
エラーメッセージの生成
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 文を使用したストアドプロシジャの論理的なエラーの診断については、「ス
トアド プロシジャの作成と使用」を参照してください。
エラーメッセージの生成
SQL 文が原因でトリガの実行に失敗した場合は、データベースサーバは、エラーの
原因に従って SQL エラー番号を返します。
トリガアクションがストアドプロシジャの場合は、二つの予約エラー番号のうちの
一つを使用して、他のエラー条件を表すエラーメッセージを生成することができま
す。一つはエラー番号 -745 で、これには一般的な固定エラーメッセージが割り当て
られています。もう一つは -746 であり、最大 71 文字からなるメッセージテキスト
を指定することができます。
固定エラーメッセージの適用
SQL エラー以外の任意のトリガエラーにエラー番号 -745 を適用することができま
す。このエラーには、次の固定メッセージがあります。
-745 Trigger execution has failed.
トリガの作成と使用
9-15
固定エラーメッセージの適用
このメッセージは、SPL の RAISE EXCEPTION 文で使用することができます。次の
例では、new_qty が old_qty の 1.50 を掛けた値倍大きい場合に、エラー -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 を使用している場合は、図 9-2 に示すように、エラー -745 のメッセージ
テキストは、画面の一番下に表示されます。
図 9-2
固定メッセージが表示されるエラー -745
Press CTRL-W for Help
SQL: New Run Modify Use-editor Output Choose Save Info Drop Exit
Modify the current SQL statements using the SQL editor.
----------------------- stores8@myserver --------- Press CTRL-W for Help ---INSERT INTO items VALUES( 2, 1001, 2, 'HRO', 1, 126.00);
745: Trigger execution has failed.
SQL API で SQL 文を使用して、エラーのあるプロシジャをトリガすると、データ
ベースサーバは、SQL エラー状態変数を -745 に設定し、その値をプログラムに返
します。このメッセージを表示するには、SQL エラーメッセージのテキスト抽出の
ために Informix アプリケーション開発支援ツールが提供しているプロシジャに従っ
てください。
9-16
Informix Guide to SQL: Tutorial
可変エラーメッセージの生成
可変エラーメッセージの生成
エラー番号 -746 では、エラーメッセージのテキストを指定することができます。前
述の例のように、次の例も new_qty が old_qty に 1.50 を掛けた値より大きい場合に
エラーを生成します。ただし、この例では、エラー番号は -746 であり、RAISE
EXCEPTION 文の 3 番目の引数に "Too many items for Mfr.(Mfr の品目が多すぎます
)" というメッセージを指定しています。RAISE EXCEPSION 文の構文と使用方法に
ついての詳細は、
「ストアド プロシジャの作成と使用」を参照してください。
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 より大き
い場合には、図 9-3 に示す結果になります。 .
図 9-3
ユーザ指定のメッセージテキストが表示されるエラー番号 -746
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.
トリガの作成と使用
9-17
まとめ
SQL API で SQL 文を使用してトリガを起動すると、データベースサーバは sqlcode
を -746 に設定し、SQL 通信領域 (SQLCA) のフィールド sqlerrm にメッセージテキ
ストを返します。SQLCA の使用方法についての詳細は、SQL API のマニュアルを
参照してください。
まとめ
トリガ入門の観点から、この章では次のことを説明しました。
9-18
■
CREATE TRIGGER 文の各要素の目的
■
BEFORE トリガアクションと AFTER トリガアクションの作成方法と、それ
らのトリガアクションを使用したトリガ文の影響の調査方法
■
FOR EACH ROW トリガアクションの作成方法と、
REFERENCING 節を使用
した、トリガ文の実行前後の列値の参照方法
■
ストアドプロシジャをトリガアクションとして使用した場合の利点
■
トリガアクションが期待どおりに動作しないときのトレース方法
■
トリガアクション内の 2 種類のエラーメッセージの生成方法
Informix Guide to SQL: Tutorial
索引
索引
記号
B
!=、不等号、関係演算子 2-31
<、小なり、関係演算子 2-31
<=、小なりまたは等号、関係演算
子 2-32
=、等号、関係演算子 2-30, 2-91
>=、大なりまたは等号、関係演算
子 2-32
>、大なり、関係演算子 2-31
BEGIN WORK 文 4-32
BETWEEN キーワード
WHERE 節での一致の検査 2-29
行範囲を指定するための使用 232
数字
10 進数 (DECIMAL) 型、
SQLWARN での警告 5-11
A
ALL キーワード、副問合せ文の開
始 3-31
ALTER INDEX 文、表に対する
ロック 7-8
AND 論理演算子 2-36
ANSI 1-16
ANSI 標準準拠
アイコン 序 11
レベル 序 15
ANSI 標準準拠のデータベース
SQLWARN での警告 5-11
不要な FOR UPDATE 節 6-16
ANY キーワード、副問合せ文の開
始 3-32
AVG 関数、集計関数 2-59
C
CALL 文
値の割当て 8-25
プロシジャの実行 8-12
CASE 式
使用方法 2-55
説明 序 7, 2-54
CLOSE DATABASE 文、データ
ベースに与えるロックの影響 78
Codd, E. F. 1-11
COMMIT WORK 文
SQLCODE の設定 6-5
カーソルのクローズ 7-21
ロックの解除 7-11, 7-21
CONTINUE 文、ループの終了 8-27
COUNT 関数
DISTINCT 2-59
GROUP BY 節 3-6
削除する行のカウント 4-5
集計関数 2-58
副問合せ文での使用 4-6
CREATE DATABASE 文
SQLWARN の警告後 5-11
共有ロックの設定 7-8
CREATE INDEX 文、表に対する
ロック 7-8
CREATE PROCEDURE FROM 文、
埋込み言語 8-7
CREATE PROCEDURE 文
CREATE PROCEDURE FROM 文
内 8-7
使用方法 8-6
CURRENT 関数、列値の比較 2-63
COUNT 関数の使用 2-59
GROUP BY 節との関係 3-4
SELECT 文での使用 2-20
DOCUMENT キーワード、ストア
ドプロシジャ内での使用 8-8
DROP INDEX 文、表に対するロッ
ク 7-8
D
E
DATABASE 文
SQLWARN の警告後 5-11
排他モード 7-8
ロック 7-8
DATE 関数、変換関数 2-68
DAY 関数、時刻関数 2-64
DB 領域、DBINFO 関数が返す名
前 2-83
DB-Access、データベースの作成 534
DBA アクセス権付きプロシジャ 817
DBDATE 環境変数 4-9
DBINFO 関数、SELECT 文 2-83
DBSERVERNAME 関数、SELECT
文 2-82, 3-19
DECLARE 文
FOR INSERT 節 6-9
FOR UPDATE 節 6-15
SCROLL キーワード 5-24
WITH HOLD 節 7-23
説明 5-20
DECODE 関数 2-84
DEFINE 文、ストアドプロシ
ジャ 8-21
DELETE 文
WHERE 節の制限 4-7
一元化された削除 6-6
埋込み 5-6, 6-3 – 6-8
カーソル 6-7
行数 5-10
行のカウント 6-4
処理 5-31
説明 4-4
トランザクション 6-5
表のすべての行 4-4
副問合せ文の使用 4-6
DISTINCT キーワード
en_us.8859-1 ロケール 序 4
ESCAPE キーワード、WHERE 節
での使用 2-44
ESQL
DELETE 文 6-3
INSERT 文 6-9
SQLCODE フィールド 5-9
SQLERRD フィールド 5-10
SQL 通信領域 (SQLCA) 5-8
UPDATE 文 6-15
エラーの処理 5-17
カーソルからの行の取出し 5-22
カーソルの使用 5-20 – 5-28
概要 5-3 – 5-37, 6-3 – 6-18
スクロールカーソル 5-23
静的な埋込み 5-5
単一行の選択 5-14
動的な埋込み 5-5, 5-29
標識変数 5-16
プリプロセッサ 5-4
ホスト変数 5-6, 5-8
ホスト変数の区切り 5-7
EXECUTE IMMEDIATE 文、説
明 5-33
EXECUTE PROCEDURE 文
値の割当て 8-25
使用方法 8-12
EXECUTE 文、説明 5-31
EXISTS キーワード、WHERE 節 331
EXIT 文、ループの終了 8-27
EXTEND 関数
式での使用 2-67
日付 (DATE) 型、日時
(DATETIME) 型および時間隔
(INTERVAL) 型 2-63
序 2 Informix Guide to SQL: Tutorial
F
FETCH 文
ABSOLUTE キーワード 5-24
順 5-23
順カーソル 5-25
説明 5-22
finderr ユーティリティ 序 13
FIRST 節
ORDER BY 節 2-47
使用方法 2-46
説明 2-46
ユニオン問合せ 2-48
FLUSH 文
挿入された行のカウント 6-11
バッファへの行の書込み 6-10
FOR UPDATE キーワード
ANSI 標準準拠のデータベースで
は不要 6-16
ORDER BY 節との競合 6-8
特定の列 6-16
FOR 文、ストアドプロシジャ内の
ループ 8-27
FOREACH 文、ストアドプロシ
ジャ内のループ 8-27
FREE 文
処理された文の解放 5-33
FROM キーワード、別名 2-97
G
GLS 「広域言語サポート」を参照。
GRANT 文、埋込み SQL 5-34 – 5-36
GROUP BY キーワード
説明 3-4
列番号 3-7
H
HAVING キーワード 3-8
HEX 関数、式での使用 2-83
HOLD カーソル、定義 7-21
I
IF 文
分岐 8-26
IN 関係演算子 3-31
$INFORMIXDIR/bin ディレクト
リ序5
INITCAP 関数、文字列操作関数 273
INSERT カーソル
使用方法 6-12
定義 6-9
INSERT 文
NULL 4-8
SELECT 文 4-10
VALUES 節 4-7
埋込み 6-9 – 6-14
行数 5-10
挿入
行 4-7
単一行 4-7
複数の行 4-10
挿入された行のカウント 6-11
重複値 4-8
定数データ 6-12
データの終わり 6-14
INTO TEMP キーワード、説明 2101
INTO キーワード
FETCH 文 5-23
INSERT 文での制限 4-11
PREPARE 文によって処理された
文での制限 5-30
SQLWARN で警告された不一
致 5-12
設定場所の選択 5-23
複数行の抽出 5-20
IS NOT NULL キーワード 2-35
IS NULL キーワード 2-35
ISAM エラーコード 5-10
ISO 8859-1 コードセット 序 4, 2-25
ISOLATION_LOCKS 構成パラメー
タ、ロックする行数の指定 7-15
L
LENGTH 関数
可変長文字 (VARCHAR) 型 2-80
式での使用 2-80
テキスト (TEXT) 型またはバイト
(BYTE) 型の文字列 2-80
LET 文
値の割当て 8-25
プロシジャの実行 8-12
LIKE キーワード
WHERE 節での使用 2-29
説明 2-37
LOCK TABLE 文、表の明示的な
ロック 7-9
LOWER 関数、文字列操作関数 272
LPAD 関数、文字列操作関数 2-77
M
MATCHES 関係演算子
WHERE 節 2-37
ロケールの影響 2-42
MATCHES キーワード
WHERE 節での使用 2-29
広域言語サポート (GLS) の使
用 2-42
MAX 関数、集計関数 2-60
MDY 関数、時刻関数 2-63
MIN 関数、集計関数 2-60
MODE ANSI キーワード、トランザ
クションの指定 4-32
MONTH 関数、時刻関数 2-63
カーソルの選択と更新のオープ
ン 5-21
カーソルを動作状態にする 5-21
OR 関係演算子 2-33
OR 論理演算子 2-36
ORDER BY キーワード
DESC キーワード 2-14, 2-25
FOR UPDATE 節での制限 6-8
GROUP BY 節との関連 3-6
INSERT 文での制限 4-11
行のソート 2-13
広域言語サポート (GLS) 2-25
昇順 2-14
番号による列の選択 2-24
表示ラベル 2-56
複数の列 2-15
P
PREPARE 文
SQLERRD でのエラー戻り 5-10
説明 5-30
複数の SQL 文 5-31
PUT 文
返されたデータのバッファへの送
信 6-10
挿入された行のカウント 6-11
定数データ 6-12
N
NOT 関係演算子 2-32
NOT 論理演算子 2-36
NULL
ESQL での検出 5-16
INSERT 文 4-8
検査 2-35
論理演算子 2-36
NVL 関数 2-86
O
ON EXCEPTION 文
エラーのトラップ 8-32
制御の有効範囲 8-33
ユーザ生成のエラー 8-34
onload ユーティリティ 4-34
onunload ユーティリティ 4-34
OPEN 文
R
RAISE EXCEPTION 文、ループの
終了 8-27
RANGE 関数、集計関数 2-60
REFERENCING 節 9-9
REPLACE 関数、文字列操作関
数 2-74
RETURN 文、ループの終了 8-27
REVOKE 文、埋込み SQL 5-34 – 536
ROLLBACK WORK 文
SQLCODE の設定 6-5
カーソルのクローズ 7-21
ロックの解除 7-11, 7-21
rowid
修正された行を探索するための使
用方法 3-18
セルフ結合での使用方法 3-15
索引 3
内部行番号を格納するための使用
方法 3-16
RPAD 関数、文字列操作関数 2-79
S
SCROLL キーワード、DECLARE
文での使用 5-24
SELECT 文
カーソル 5-20
SELECT カーソル
オープン 5-21
使用 5-21
SELECT 文
DISTINCT キーワード 2-20
ESQL での INTO 節 5-14
FIRST 節 2-46
GROUP BY 節 3-4
HAVING 節 3-8
INTO TEMP 節 2-101
ORDER BY 節 2-13
rowid 3-20
SELECT 節 2-12 – 2-28
UNION 演算子 3-40
アクティブセット 2-28
値の割当て 8-25
埋込み 5-14 – 5-17
カーソル 5-20
外部結合 3-20 – 3-27
関数 2-57 – 2-83
簡単な 2-3 – 2-101
結合 2-91 – 2-97
結合した表 2-101
高度な 3-4 – 3-52
式の選択 2-49
自然結合 2-94
集計関数 2-57, 2-68
使用方法
結合 2-8
射影 2-7
選択 2-6
セルフ結合 3-11
選択対象の並び 2-12
単一 2-28
データの終わりを示すリターン
コード 6-14
日付関連の関数 2-63
一つの表 2-11, 2-11 – 2-83
表示ラベル 2-52
複合問合せ文 3-40
複数表 2-89
副問合せ文 3-30 – 3-39
部分文字列の選択 2-27
別名 2-97
SET ISOLATION 文
SET TRANSACTION 文との比
較 7-12
説明 7-12
SET LOCK MODE 文、説明 7-19
SET TRANSACTION 文、SET
ISOLATION 文との比較 7-13
SET キーワード、UPDATE 文での
使用 4-13
SET 節 4-15
SITENAME 関数、SELECT 文 2-82,
3-19
SOME キーワード、副問合せ文の
開始 3-31
SPL
SQL との関係 8-3
広域変数 8-20
定義 8-3
流れ制御文 8-26
プログラム変数 5-6
ローカル変数 8-20
SQL
ANSI 標準への準拠 1-16
Informix SQL と ANSI SQL 1-16
アプリケーションプログラミング
インターフェイス 5-4
エラーの処理 5-17
カーソル 5-20
説明 1-15
標準化 1-15
歴史 1-15
SQL 通信領域 (SQLCA)
行の挿入 6-11
説明 5-8
トランザクションの終了前に変
更 6-5
SQLCODE フィールド
DELETE 文で設定 6-4
FLUSH 文の実行 6-11
PUT 文で設定 6-11
SELECT 文のみのデータの終わ
り 6-14
カーソルのオープン後 5-21
索引 4 Informix Guide to SQL: Tutorial
説明 5-9
データの終わりの警告 5-17
SQLERRD 配列
行のカウント 6-14
削除された行のカウント 6-4
説明 5-10
挿入された行のカウント 6-11
名前付けの構文 5-8
SQLERRM 文字配列 5-13
SQLSTATE 変数
ANSI 標準準拠でないデータベー
ス 5-18
カーソルとの使用 5-21
SQLWARN 配列
PREPARE 文 5-31
説明 5-11
名前付けの構文 5-8
STDEV 関数、集計関数 2-61
stores7 データベース 序 5
SUBSTR 関数、文字列操作関数 276
SUBSTRING 関数、文字列操作関
数 2-75
SUM 関数、集計関数 2-60
T
TABLE ロックモード 序 7, 7-9
TO_CHAR 関数、変換関数 2-69
TO_DATE 関数、変換関数 2-70
TODAY 関数、定数式 2-82, 4-9
TRACE 文
出力 9-14
ストアドプロシジャのデバッ
グ 8-14
U
UNION 演算子
説明 3-40
表示ラベル 3-44
UNIQUE キーワード、SELECT
文 2-20
UPDATE カーソル、定義 6-15
UPDATE 文
埋込み 6-15 – 6-17
行数 5-10
結合を使用する列の更新 4-17
処理 5-31
説明 4-12
データの終わり 6-14
複数の代入 4-15
副問合せ文の制限 4-15
UPPER 関数、文字列操作関数 2-72
USER 関数、式 2-81, 3-18
X
X/Open 準拠
レベル 序 15
Y
YEAR 関数、時刻関数 2-63
V
VALUES 節、INSERT 文 4-7
VARIANCE 関数、集計関数 2-62
W
WEEKDAY 関数、時刻関数 2-63, 266
WHERE CURRENT OF 節
DELETE 文 6-7
UPDATE 文 6-15
WHERE キーワード
NULL かどうかの検査 2-35
値の範囲 2-32
WHERE 節
DELETE 文 4-4 – 4-7
NOT キーワード 2-32
OR キーワード 2-33
関係演算子 2-29
行の選択 2-28
比較条件 2-29
日付関連の関数 2-66
副問合せ文 3-31
部分文字列 2-44
部分文字列の検査 2-44
ホスト変数 5-15
論理式 2-36
ワイルドカード比較 2-37
WHERE 節でのワイルドカード比
較 2-37 – 2-44
WHILE 文、ストアドプロシジャ内
のループ 8-27
WITH HOLD キーワード、HOLD
カーソルの宣言 7-23
WITH LISTING IN キーワード、ス
トアドプロシジャ内の警告 8-10
あ
アーカイブ
説明 4-33
データベースサーバ方式 4-33
トランザクションログ機能 4-33
アイコン
機能 序 10
コメント 序 9
準拠 序 11
製品 序 10
プラットフォーム 序 10
アクセス権
DBA アクセス権付きプロシ
ジャ 8-17
Execute 8-18
概要 1-9
所有者アクセス権付きプロシ
ジャ 8-17
ストアドプロシジャでの取消
し 8-20
ストアドプロシジャに対する 817
ストアドプロシジャのデフォル
ト 8-18
データベースレベル 4-17
必要
データの修正 4-17
表示 4-19
アクセスモード、説明 7-18
アクティブセット
カーソル 5-24
定義 2-28
アスタリスク、SELECT 文のワイ
ルドカード文字 2-12
アプリケーション
エラーの処理 5-17
共通の機能 1-17
説明 1-18
注文入力の設計 4-29
い
一元化された削除 6-6
一時表
カーソルのアクティブセット 525
例 4-12
列名の割当て 3-12
違反表、フィルタモードでの使
用 4-27
意味整合性 4-21
インデックス
表に対するロック 7-8
フィルタモード 4-27
無効化モード 4-27
有効化モード 4-27
う
埋込み SQL
使用可能な言語 5-4
定義 5-4
え
エラー
DELETE 文実行後 6-4
ISAM エラーコード 5-10
カーソルのオープン時に検出 521
カーソルを使用した挿入 6-11
更新中 4-28
コード 5-10
コンパイル時 8-8
処理 5-17
ストアドプロシジャ構文 8-9
エラーチェック
エラーのシミュレート 8-34
ストアドプロシジャ 8-32
例外処理 8-32
エラーメッセージ
トリガでの生成 9-15
トリガの失敗 9-15
プログラム内のトリガテキストの
抽出 9-16, 9-18
索引 5
エラーメッセージファイル 序 13
エラーメッセージ変数 5-13
お
オープン、カーソルの 5-21, 5-24
大文字小文字変換
INITCAP 関数 2-73
LOWER 関数 2-72
UPPER 関数 2-72
オブジェクトモード、説明 4-26
オンラインマニュアル 序 12
か
カーソル
FETCH での値の抽出 5-22
UPDATE 7-11
WITH HOLD 7-21
アクティブセット 5-24
オープン 5-21, 5-24
クローズ 7-21
更新 6-15
順 5-23, 5-25
スクロール 5-23
宣言 5-20
挿入 6-9
定義 5-20, 5-24
プログラムの操作の流れ 5-20
保持 7-21
カーソル安定性 (INFORMIX) 排他
レベル 序 7, 7-15
外部キー 4-22
外部結合 序 7, 3-20
外部表 序 7, 4-34
拡張機能、SQL への、表す記号 序
11
確定読込み (ANSI) 排他レベル 7-14
確定読込み (INFORMIX)、排他レ
ベル 7-14
カスケード削除
関連したロック 4-24
制約 4-26
定義 4-24
ログ機能 4-24
各国語可変長文字 (NVARCHAR)
型、問合せ 2-11
各国語文字 (NCHAR) 型、問合せ 211
可変長文字 (VARCHAR) 型、
LENGTH 関数の使用 2-80
可変長文字 (VARCHAR) 型値、表
示 2-11
関係演算 2-5
関係演算子
BETWEEN 2-32
EXISTS 3-31
IN 3-31
LIKE 2-37
NOT 2-32
NULL 2-35
OR 2-33
WHERE 節 2-29 – 2-31
関数
DATE 2-68
DBINFO 2-83
DECODE 2-84
INITCAP 2-73
LOWER 2-72
LPAD 2-77
NVL 2-86
REPLACE 2-74
RPAD 2-79
SELECT 文 2-57
SPL での名前の混同 8-24
SUBSTR 2-76
SUBSTRING 2-75
TO_CHAR 2-69
TO_DATE 2-70
UPPER 2-72
式への適用 2-63
時刻 2-63
集計 2-57
ストアドプロシジャ 8-28
日付関連 2-63
変換 2-68
文字列操作 2-71
き
キーに対するロック 7-10
キーワード
WHERE 節 2-29
副問合せ文 3-31
索引 6 Informix Guide to SQL: Tutorial
キーワード、WHERE 節での使
用 2-29
キーワードの使用、EXECUTE
文 5-31
機能アイコン 序 10
機能、製品 序 5
疑問符 (?)
PREPARE 文の位置指定子 5-30
行
削除 4-4
処理された行数の検出 2-83
挿入 4-7
定義 1-13, 2-5
ユーザが修正した行の探索 3-18
リレーショナルモデル 1-13
業界標準、準拠 序 15
行に対するロック 7-10
切捨て、SQLWARN での警告 5-12
金額 (MONEY) 型
INSERT 文 4-8
国際金額フォーマット 1-17
く
繰返し読込み (INFORMIX と ANSI)
排他レベル 7-17
け
警告、コンパイル時のストアドプ
ロシジャ 8-10
結合
UPDATE 文 4-17
入れ子になった単純結合 3-24
外部、種類 3-20
外部、定義 3-20
結合性 2-95
作成 2-91
自然 2-94
従表 3-20
主表 3-20
条件 2-89
セルフ結合 3-11
単純 2-89
定義 2-8, 2-89
等結合 2-91
複合 2-89
複数表の結合 2-96
検査制約、定義 4-22
こ
広域言語サポート (GLS)
MATCHES キーワード 2-42
ORDER BY キーワード 2-25, 2-42
説明 序 6
ソート順序 2-25
データベース、説明 1-17
デフォルトロケール 2-25
ロケール 序 4
広域変数、SPL の 8-21
降順のソート、SELECT 文での 214
構成パラメータ、
ISOLATION_LOCKS 7-15
コメント アイコン 序 9
さ
再帰、ストアドプロシジャ 8-29
再帰的関係、例 5-27
最新のシリアル (SERIAL) 型値、
DBINFO 関数が返す 2-83
差の集合演算 3-50
サブスクリプト
SPL 変数 8-22
作用素、存在 3-36
参考文献 序 15
算術演算子、式 2-49
参照整合性、定義 4-22
参照制約、定義 4-23
サンプルコードの表記 序 11
し
時間隔 (INTERVAL) 型、関係式 229
式
CASE 2-54
SPL 8-25
説明 2-49
日付関連 2-63
表示ラベル 2-52
時刻関数、説明 2-63
自己参照型問合せ 3-11, 4-26
システムカタログ
sysprocbody 8-11
systabauth 4-19
アクセス権 4-19
問合せ 4-19
システム記述子領域、説明 5-32
自然結合 2-94
実体、定義 4-21
射影、説明 1-14
射影、定義 2-7
集計関数
AVG 2-59
COUNT 2-58
ESQL 5-14
GROUP BY 節 3-5
MAX 2-60
MIN 2-60
NULL の警告 5-12
RANGE 2-60
SPL 式 8-25
STDEV 2-61
SUM 2-60
VARIANCE 2-62
説明 序 6, 2-57, 2-68
標準偏差 2-61
副問合せ文 3-33
集合演算 3-39
差 3-50
積 3-48
和 3-40
従表 3-20
主キー
断片化された表 3-15
定義 4-21
主キー制約、定義 4-23
出力、TRACE 文からの 9-14
主表 3-20
順カーソル、定義 5-23
循環型問合せ 4-26
準拠
アイコン 序 11
業界標準 序 15
照合順序と広域言語サポート
(GLS) 2-25
昇順のソート、SELECT 文での 214
小なり (<) 関係演算子 2-31
小なりまたは等号 (<=) 関係演算
子 2-32
所有者アクセス権付きプロシ
ジャ 8-17
シリアル (SERIAL) 型
SQLERRD で生成された番号 5-10
開始値の挿入 4-8
挿入された最新のシリアル
(SERIAL) 型値の検出 2-83
診断表、フィルタモードでの使
用 4-27
す
スクロールカーソル
アクティブセット 5-25
定義 5-23
ストアドプロシジャ
DB-Access からの作成 8-6
DBA アクセス権付き、トリガで
の使用 8-17
DEFINE 文 8-21
REFERENCES 節 8-22
SELECT 文 2-87
SPL 式 8-25
SQL 関数との名前の混同 8-25
アクセス権の取消し 8-20
アクセス権の付与 8-18, 8-19
値の返戻 8-30
一般的なプログラミング 1-19
入れ子とアクセス権 8-19
埋込み言語からの作成 8-7
コメント 8-8
再帰 8-29
実行 8-12
実行に必要なアクセス権 8-18
使用 8-4
紹介 8-3
所有者アクセス権付き 8-17
定義 8-4
デバッグ 8-14
デフォルトアクセス権 8-18
ドキュメントの表示 8-11
トリガアクションとして 9-11
トリガアクションのトレース 913
内容の表示 8-11
プログラムの流れの制御 8-26
分岐 8-26
変更 8-16
索引 7
変数 8-20
変数の有効範囲 8-22
冒頭部分 8-30
ループ 8-27
ストアドプロシジャ言語 「SPL」
を参照。
せ
静的 SQL 文 5-5
性能
ストアドプロシジャによる向
上 8-4
並列度に依存 7-3
製品アイコン 序 10
制約
実体整合性 4-21
無効化 4-27
有効化 4-27
積の集合演算 3-48
セッション ID、DBINFO 関数が返
す 2-84
セルフ結合
INTO TEMP 節での列名の割当
て 3-12
説明 3-11
選択、説明 1-14, 2-6
選択対象の並び
関数 2-57 – 2-83
式 2-49
すべての列の選択 2-12
特定の列の選択 2-18
表示ラベル 2-52
部分文字列の特定 2-27
ラベル 3-44
そ
相関副問合せ
カスケード削除での制約 4-26
定義 3-30
増進可能なロック 7-7, 7-11
ソート
ORDER BY 節 2-14
広域言語サポート (GLS) の影
響 2-25
多重 2-15
ロケールによる影響 2-25
ソフトウェアの要件 序 4
た
大なり (>) 関係演算子 2-31
大なりまたは等号 (>=) 関係演算
子 2-32
多重の順序、SELECT 文 2-15
単一 SELECT 文 2-28
単純読込み (INFORMIX) 排他レベ
ル 7-14
断片化された表、主キーの使用 315
ち
中断された更新 4-28
重複値、探索 3-15
直列化可能 (ANSI) 排他レベル、説
明 7-17
て
定数データだけで構成される行の
挿入 6-12
データ型
SPL 変数 8-22
自動変換 5-15
変換 4-9
データ定義文 5-34
データの終わり
SELECT 文のみ 6-14
SQLCODE での警告 5-17
SQLCODE の値 5-9
カーソルのオープン時 5-21
データの整合性 4-28 – 4-33
データのロード 4-34
データベース
ANSI 標準準拠 1-17
GLS 1-17
アプリケーション 1-17
管理 1-10
サーバ 1-9, 1-17
サーバ、定義 1-18
定義 1-12
同時利用 1-9
表の名前 2-102
索引 8 Informix Guide to SQL: Tutorial
リレーショナル、定義 1-11
データベースオブジェクト
違反の検出 4-26
インデックス 4-26
オブジェクトモード 4-26
制約 4-26
トリガ 4-26
データベースサーバ
SQLWARN での警告 5-11
アーカイブ 4-33
定義 1-18
バージョン番号の検索 2-84
表に対するロック 7-8
ホストコンピュータ名の検索 284
データベースに対するロック 7-8
データベースレベルのアクセス
権 4-17
データモデル、説明 1-4
データレプリケーション 4-35
デカルト積
結合の基本 2-91
説明 2-89
テキスト (TEXT) 型
LENGTH 関数の使用 2-80
制限
GROUP BY 節 3-6
LIKE または MATCHES 2-37
関係式 2-29
テキスト (TEXT) 型値、表示 2-11
デッドロックの検出 7-20
デフォルト値、列 4-22
デフォルトロケール 序 4
デモンストレーションデータベー
ス序5
と
問合せ
監査 3-39
自己参照型 4-26
循環型 4-26
データモデルの用語で記述 1-7
複合 3-40
等結合 2-91
等号 (=) 関係演算子 2-30, 2-91
動的 SQL
処理された文の解放 5-33
説明 5-5, 5-29
ドキュメントノート、プログラム
項目 序 14
トランザクション
DELETE 文での例 6-5
SQLWARN で警告される使用 511
最後に解除されるロック 7-11
終了時に解除されるロック 7-21
終了時にクローズされるカーソ
ル 7-21
終了まで続くロック 7-11
説明 4-28
トランザクションログ機能 4-30
トランザクションログ機能
説明 4-30
ログの内容 4-33
トリガ
作成 9-4
使用するタイミング 9-3
定義 9-3
名前の割当て 9-5
無効化モード 4-28
有効化モード 4-28
トリガアクション
BEFORE および AFTER 9-7
FOR EACH ROW 9-9
WHEN 条件 9-10
エラーメッセージの生成 9-15
使用方法 9-7
ストアドプロシジャの使用方
法 9-11
トリガ文との関係 9-6
トレース 9-13
文 9-3
トリガイベント
定義 9-5
例 9-5
に
日時 (DATETIME) 型
ORDER BY 節 2-14
関係式 2-29
関数の戻り 2-63
フォーマットの表示 2-67
文字列への変換 2-69
は
バージョン番号、DBINFO 関数が
返す 2-84
排他レベル
カーソル安定性 (INFORMIX) 7-15
確定読込み (ANSI) 7-14
確定読込み (INFORMIX) 7-14
繰返し読込み (ANSI) 7-17
繰返し読込み (INFORMIX) 7-17
設定 7-12
説明 7-12
単純読込み (INFORMIX) 7-14
直列化可能 (ANSI) 7-17
不確定読込み (ANSI) 7-14
排他ロック 7-7
バイト (BYTE) 型
LENGTH 関数の使用 2-80
制限
GROUP BY 節 3-6
LIKE または MATCHES 2-37
関係式 2-29
バイト (BYTE) 型値、表示 2-11
パラメータ、ストアドプロシ
ジャ 8-29
ひ
比較条件、説明 2-29
日付 (DATE) 型
ORDER BY 節 2-14
関係式 2-29
関数の戻り 2-63
国際金額フォーマット 1-17
文字列への変換 2-69
表
アクセス 2-102
現行データベースに含まれていな
い表へのアクセス 2-38
説明 1-12
データのロード
onload ユーティリティ 4-34
外部表 4-34
名前 2-102
リレーショナルモデル 1-12
ログ付き 4-31
ログなし 4-31
ロック 7-8
表記上のきまり
アイコン 序 9
サンプル コード 序 11
文字 序 8
標識変数、定義 5-16
標準偏差、集計関数 2-61
表示ラベル
ORDER BY 節 2-56
SELECT 文 2-52
表へのアクセス 2-102
ふ
ファイル、データベースとの比
較 1-4
フィルタオブジェクトモードの定
義 4-26
不確定読込み (ANSI) 排他レベル 714
複合問合せ文 3-40
複数表の結合 2-96
副問合せ
相関 4-26
副問合せ文
DELETE 文 4-6
SELECT 文 3-30 – 3-39
UPDATE 文
SET 節 4-13
WHERE 節 4-13
相関 3-30
副文字列 8-22
不等号 (!=) 関係演算子 2-31
部品爆発 5-27
部分文字列 2-27
WHERE 節 2-44
プラットフォームアイコン 序 10
プログラムグループ
ドキュメントノート 序 14
リリースノート 序 14
分散デッドロック 7-21
へ
並列度
アクセスモード 7-18
確定読込み (ANSI) 7-14
確定読込み (INFORMIX) 7-14
繰返し読込み (ANSI) 7-17
索引 9
繰返し読込み (INFORMIX) 7-17
性能上の影響 7-3
説明 4-34, 7-3
単純読込み (INFORMIX) 7-14
直列化可能 (ANSI) 7-17
データベースに対するロック 7-8
デッドロック 7-20
排他レベル 7-12
排他レベルのカーソル安定性
(INFORMIX) 7-15
表に対するロック 7-8
不確定読込み (ANSI) 7-14
ロックの継続期間 7-11
ロックの種類 7-7
ロック範囲 7-7
ページに対するロック 7-10
ペーパーマニュアル 序 13
別名
一時表での列名の割当て 3-12
セルフ結合 3-11
表の名前 2-97
変換関数、説明 2-68
変数
SPL 8-20
SPL 内の有効範囲 8-22
キーワードと同じ名前 8-23
広域、SPL 8-20, 8-21
ま
ら
マシンノート 序 14
マニュアルの種類
エラーメッセージファイル 序 13
オンラインマニュアル 序 12
参考文献 序 15
ドキュメントノート 序 14
ペーパーマニュアル 序 13
マシンノート 序 14
リリースノート 序 14
マルチスレッドアプリケーション、
定義 5-5
ラベル 2-52, 3-44
む
無効オブジェクトモードの定義 426
め
命名規則、表 2-102
メッセージファイル
エラーメッセージ 序 13
も
ほ
冒頭部分、プロシジャの 8-30
ホストコンピュータの名前、
DBINFO 関数が返す 2-84
ホスト変数
DELETE 文 6-4
EXECUTE 文 5-31
INSERT 文 6-9
INTO キーワードセット 5-14
NULL 標識 5-16
PREPARE 文によって処理された
文での制限 5-30
UPDATE 文 6-15
WHERE 節 5-15
切捨ての警告 5-12
説明 5-6
データの取出し 5-22
区切り記号 5-7
動的割当て 5-32
索引 10
文字 (CHAR) 型
関係式 2-29
切捨ての警告 5-12
日時 (DATETIME) 型値への変
換 2-70
日付 (DATE) 型値への変換 2-68
部分文字列 2-27, 2-44
文字列
日時 (DATETIME) 型値への変
換 2-70
日付 (DATE) 型値への変換 2-68
ゆ
有効オブジェクトモードの定義 426
ユーティリティプログラム
onload 4-34
onunload 4-34
Informix Guide to SQL: Tutorial
り
リリースノート
格納場所 序 14
プログラム項目 序 14
リレーショナルデータベース、定
義 1-11
リレーショナルモデル
結合 2-8
射影 2-6
説明 1-11
選択 2-6
る
ループ
RAISE EXCEPTION 文での終了 835
SPL での作成と終了 8-27
れ
列
説明 1-13
定義 2-5
ラベル 3-44
リレーショナルモデル 1-13
列の定義域 4-21
列番号、使用 2-24
レプリケーション
データ 4-35
透過性 4-36
ろ
ローカル変数、SPL の 8-20
ログスライス、説明 4-31
ログなし表 序 7, 4-31
ロケール 序 4, 1-17
ロック
DELETE 文 6-4
UPDATE カーソル 7-11
細分度 7-7
整合性 7-3
説明 7-6
デッドロック 7-20
トランザクションの終了時に解除
されるロック 7-21
並列度 4-34
ロックする行数の指定 7-15
ロックの継続期間 7-11
ロックの種類
キーに対するロック 7-10
行に対するロック 7-10
共有ロック 7-7
増進可能なロック 7-7, 7-11
データベースに対するロック 78
排他ロック 7-7
表に対するロック 7-8
ページに対するロック 7-10
ロックの範囲 7-7
ロックモード 7-19
NOT WAIT 7-19
WAIT 7-19
ロックモードの設定 7-19
ロックモード、TABLE 7-9
論理演算子
AND 2-36
NOT 2-36
OR 2-36
論理式、論理演算子 2-36
論理ログ
説明 4-30
バックアップ 4-33
わ
ワイルドカード文字、アスタリス
ク 2-12
和の集合演算 3-40
索引
11
Fly UP