Comments
Description
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