SQL
出典: フリー百科事典『ウィキペディア(Wikipedia)』
SQLは、リレーショナルデータベースマネージメントシステム(RDBMS)において、データの操作や定義を行うための問い合わせ言語。
SQLは、Structured Query Languageの略と思っている人やそう紹介しているサイトも少なくないが、多くの場合、これは正しくない。
IBM社のRDBMSのSQLなら、これで正解である。一方、標準SQLは、IBM社のDB2の仕様を多く取り入れており、影響を受けていることは疑いようもないが、「SQLは、何かの略語ではない」としている。
IBM社のRDBMSのSQLは、シークェルと読まれることもある。これは、SQLの元となったデータベース操作言語が、IBM社が開発したRDBMSの実験実装である System R の操作言語「SEQUEL(Structured English Query Language)」であったことが由来である。
目次 |
[編集] 標準SQL規格
当初は特に統一標準規格が存在しない状況で、各RDBMSベンダーごとに様々な拡張がなされてきた。 近年になってANSI、後にISOで言語仕様の標準化が行われており、制定された年ごとにSQL86、SQL89、SQL92、SQL99などの規格があるが、対応の程度はベンダーごとにバラバラなのが実情である。これは標準SQL策定に時間がかかりすぎたことにより、ビジネスの現状から早期の機能拡張が迫られたベンダーの都合と、独自構文を頻繁に利用していたユーザに対し、互換性保持を保障する必要もあったためである。
SQL規格は非常に多くの改正が行われた。制定年度順に代表的な規格を以下に挙げる。
年 | 規格名称 | 別称 | 説明 |
---|---|---|---|
1986 | SQL86 | SQL87 | ANSIによって最初に発表された最初の規約。1987年にISOによって批准された。 ・DML仕様策定:COBOL、FORTRAN、PL/Iなど、親言語(母言語、ホスト言語とも言う)への埋込みSQL文仕様策定 |
1989 | SQL89 | マイナーバージョン。 ・DDL仕様策定(CREATE TABLE文、CREATE VIEW文、GRANT文。ただし、DROP文、ALTER文、REVOKE文はなし) ・制約および整合性機能を追加(DEFAULT、UNIQUE制約、NOT NULL制約、PRIMARY KEY制約、CHECK制約、参照整合性制約) ・C言語への埋込みSQL文仕様の追加 |
|
1992 | SQL92 | SQL2 | メジャーバージョン ・直交性の改善(表式) ・データ型の拡張(可変長文字列、ビット、文字集合、日付・時刻・時間間隔(DATE,TIME,TIMESTAMP)) ・外部結合(OUTER JOIN) ・定義域(Domain) ・表明(Assertion) ・一時表(TEMPORARY TABLE:永続化しないデータを格納) ・DDL仕様追加(DROP文、ALTER文) ・動的SQL仕様 ・前方・後方スクロール可能なカーソルサポート ・クライアント/サーバシステムのためのCONNECT/DISCONNECT文 |
1995 | SQL/CLI | コールレベルインターフェース(Call Level Interface) 業界標準になったODBCインタフェースに相当する機能を国際標準化した規格 |
|
1996 | SQL/PSM | 永続格納モジュール(Persistent Storage Module) 一般的にストアドプロシージャと呼ばれる機能を国際標準化した規格 |
|
1999 | SQL:1999 (SQL99) |
SQL3 | RDBMSのための完全な言語になることを目指した仕様。 ・正規表現による値照合再帰的クエリー ・OLAP(ROLLUP、CUBE、GROUPING SETS) ・ユニオン・結合経由の更新 ・カーソル操作の機能強化(トランザクション完了後のオープン状態保持)・ユーザ定義権限(Roll)・トランザクション管理の新機能(SAVEPOINT) ・SQL/PSM強化(制御構文(IF、LOOPなど)サポートなど) ・SQLJ(Javaを親言語とする埋め込みSQL規格) ・データベーストリガー ・ユーザ定義関数(ストアドファンクション) ・非スカラー型の新しいデータ型:真理値(BOOLEAN)型と配列(ARRAY)型、LOB(Large Object)、ユーザ定義型、構造型 ・スーパーテーブルとサブテーブル(上位表と副表) ・オブジェクト指向の考え方を取り入れたオブジェクトリレーショナル技術(ORDB)。配列型やユーザ定義型、ユーザ定義関数とスーパー/サブテーブル仕様により実現されている。 ※(非スカラー型とオブジェクト指向機能については、いくらか論議を呼ぶことになり、いまだ広く支持されていない。) |
2003 | SQL:2003 | SQL/MM(マルチメディア:フレームワーク、フルテキスト検索、空間データ(Spatial)、静止画像)) ・SQL/MED(外部データ管理:非リレーショナルデータ(順次ファイルや階層型データベースなど)や他社のリレーショナルデータをSQLでアクセスするための規格) ・SQL/OLB(オブジェクト言語バインディング:SQLJを標準化する。Javaプログラムに埋め込むSQL文) ・XML関連の機能、 ・「ウインドウの機能」 ・順序(シーケンス)の標準化と識別キー列に対する値の自動生成を行う列仕様の導入(ID型) |
[編集] SQLとオンライン処理
当初はRDBMSに端末から直接命令を発行することを想定していたため、制御文法の仕様が存在しなかった。このため、COBOLやC言語などは「手続き型プログラミング言語」、SQLは「宣言型プログラミング言語」と分類される。
その後、手続き型プログラミング言語(母言語)からRDBへのアクセスを行えるようにするため、母言語のソースコードにSQL文を記述し、プリプロセッサによってSQL部分を母言語のコードに変換してデータベースアプリケーションを開発する方式が普及した。これを「埋め込みSQL」(Embedded SQL/ESQL)と呼び、後にANSIにより仕様が標準化された。
暫くの間、データベースアプリケーションは、RDBMSベンダーが製品に同封したユーティリティや埋め込みSQLにより開発されてきたが、Microsoft社がC言語からAPIレベルで統一したソースコードを記述し、クライアント・サーバ型アプリケーションシステムの構築に有用である仕組み「ODBC」を発表し、その有用性からANSIではODBC仕様を参考に「SQL/CLI」という仕様を標準化した。
[編集] SQLとバッチ処理
埋め込みSQLやODBCの普及により、オンライン処理向きのSQLアクセス方法は確立されたが、バッチ処理性能向上の必要性が求められるようになった。
あるテーブルの内容を編集して別のテーブルに格納する大量データの更新処理などをデータベースエンジン内部で処理プログラムを実行し、I/Oのほとんどをデータベース内部で完結することにより、クライアント側とのデータ通信によるオーバヘッドを削減することでバッチ処理性能を向上させる「ストアドプロシージャ」が考え出された。
ストアドプロシージャは、同じくデータベース内部に定義し、データベースに発生したイベントの内容に応じて任意の処理を実行する機能である「データベーストリガー」とともに、標準SQL仕様に採用され、SQL99規格として標準化された。
しかし、標準化される以前から各RDBMSベンダーがDBエンジン内部で制御文法を記述し実行できるように独自の拡張が行われていたため、ストアドプロシージャの処理ロジック記述文法はそれ以前に標準化されたSQL文法と比較して著しい非互換が認められるため、アプリケーションの開発生産性・保守性を損なう場合がある。
各RDBMSベンダーによる、制御構文を含む独自SQL文法には以下のようなものがある。これらの仕様には、文法単位の独自追加だけでなく、命令やデータ型の非互換も存在するため注意が必要である。
- PL/SQL (Oracle)
- Transact-SQL (Sybase、Microsoft SQL Server)
- PL/pgSQL (PostgreSQL)
- MySQL Query Browser(MySQL)
[編集] Javaとデータベース
後に大規模システム開発において、Javaによるアプリケーション開発が一般的になるきっかけとなったのは、リレーショナルデータベースアクセスをJavaから行うAPI仕様である「JDBC」が発表されてからである。
さらにJavaで大規模エンタープライズシステムを開発するための仕様「J2EE(Java2 Enterprise Edition)」には、リレーショナルデータベースのテーブルのレコードデータを、Javaのオブジェクトに1対1に対応させ、オブジェクト内容の永続化=レコードデータの保存というデータのリンクと、オブジェクトのメソッド呼び出し=データベースへのトランザクション処理を同期させる特殊なJava Beanを動作・管理する機構である「EJB(Enterprise Java Bean)」が導入された。
EJB2.1までは、オブジェクトーリレーショナルの間にあるインピーダンスミスマッチによりRDBの機能を十分に生かせなないことや性能面の問題があったが、EJB3.0仕様により改善されてきている。
[編集] SQLの対話的実行
SQLを対話的に実行する場合、データベース製品に付属するコマンドラインタイプのアクセスユーティリティを利用するのが一般的である。SQLを記述したテキストファイルをスクリプトとして実行し、バッチ的に実行することが可能なものもあり、広く利用されている。データベース製品ごとに、そのユーティリティ固有の命令を備えているものもあるため、データベース開発初心者はその命令もデータベースエンジンが解釈するSQL文法の一つであると間違って覚えてしまい、ODBCやJDBCなどAPIからSQLを実行したときのエラーの原因が理解できずに混乱することもある。
ユーティリティ固有の文法で誤解しやすいものには、全データベース共通ではSQL文の文末に指定する文字である「;」、Oracle Database の ユーティリティであるSQL*Plusで、ストアドプロシージャの定義や無名PL/SQLブロックを発行するときに文末行に指定する「/」 や、Sybase/SQL Serverのisql/osqlではすべてのSQL文の文末行に指定する「GO」などがある。このなかでもっとも間違えやすいのが「;」である。これは、一般的なSQL教科書でも構文の終端文字として例が記載されているが、標準SQLの構文の終端文字ではない。
[編集] SQL文法
[編集] コマンド種別
SQL文法の種別は、以下の3つに大別される。
- データ定義言語(DDL:Data Definition Language)
- データ操作言語(DML:Data Manipulation Language)
- データ制御言語(DCL:Data Control Language)
その他に、これらの命令の適用範囲を補完するための機能として、SQL文を実行時に解釈する「動的SQL」や、埋め込みSQLのための命令などが用意されている。 RDBMS以前のデータベースマネージメントシステム(DBMS)では、これらは必ずしも同一の言語ではなかった。データ定義言語は存在せずにすべて専用のコマンドにパラメタを指定して実行する実装も存在した。
[編集] コマンド文法
[編集] DDL
- CREATE (DBオブジェクト(テーブル、インデックス、制約など)の定義)
- DROP (DBオブジェクトの削除)
- ALTER (DBオブジェクトの定義変更)
[編集] DML
- INSERT INTO (レコードデータの挿入)
- UPDATE ~ SET (レコードデータの更新)
- DELETE FROM (レコードの削除)
- SELECT ~ FROM ~ WHERE (レコードの検索、結果集合の取り出し)
- 後述する「動的SQL」でのSELECT文には、一度の実行で1レコード文の結果を取得する「単一行SELECT文」と、カーソルにより結果を取得する「カーソルSELECT文」がある。
列名と値を、対で指定 INSERT INTO 表名(列名1,列名2) VALUES(値1,値2) 表を構成するすべての列に値を格納する場合は、列名の記述を省略可能 INSERT INTO 表名 VALUES(値1,値2) 他表のデータを検索して格納 INSERT INTO 表名1 SELECT 列名1,列名2 FROM 表名2 ~ 更新 UPDATE 表名 SET 列名2=値2,列名3=値3 WHERE 列名1=値1 削除 DELETE FROM 表名 WHERE 列名1=値1 1行以上の検索 SELECT * FROM 表名 WHERE 列名1 BETWEEN 値1 AND 値2 ORDER BY 列名1 1行だけの検索 SELECT * INTO 受け取り変数 FROM 表名 WHERE 列名1=値1
[編集] DCL
- SET TRANSACTION トランザクションモードの設定(平行トランザクションの分離レベル(ISOLATION MODE)など)
- BEGIN (トランザクションの開始)
- COMMIT (トランザクションの確定)
- ROLLBACK (トランザクションの取り消し)
- SAVEPOINT (任意にロールバック地点を設定する)
- LOCK (表などの資源を占有する)
[編集] カーソル定義・操作
主に応用プログラムなどの手続き型言語からのSQL実行において利用する。 SELECT文による検索実行の結果を1レコードづつ取得して処理するために、DBサーバ側にある結果集合とレコード取得位置を示す概念を「カーソル」と言う。
- DECLARE CURSOR (カーソル定義)
- OPEN (カーソルのオープン)
- FETCH (カーソルのポインタが指し示す位置のレコードデータを取得し、ポインタを一レコード分進める。)
- UPDATE (カーソルのポインタが指し示す位置のレコードデータを更新する)
- DELETE (カーソルのポインタが指し示す位置のレコードデータを削除する)
- CLOSE (カーソルのクローズ)
DECLARE CR1 CURSOR FOR SELECT * FROM TBL1 WHERE 検索条件 OPEN CR1 ↓ FETCH CR1 INTO 受け取り変数 ↓ ↓→→→→→→→→→→→→→→→→→→→→→→ ↓ ↓ ↓ ↓ UPDATE TBL1 DELETE FROM TBL1 ↓ SET CLMB=値 WHERE CURRENT OF CR1 ↓ WHERE CURRENT OF CR1 ↓ ↓ ↓ ↓ ↓←←←←←←←←←←←←←←←←←←←←←← ↓ CLOSE CR1 ※FETCH(必要ならUPDATE、DELETEも)を、データが無くなるまで繰り返す
[編集] 動的SQL
通常SQL文をDBMSの送信の度にデータベースエンジンで実行可能な内部中間コードに翻訳する作業を事前に行うことによって、場合の翻訳済みSQLコードを再度利用してSQL解析のオーバーヘッドを削減することと、SQL文をコードで固定せずにDBへのアクセス毎に構文を書き換えたい場合に有用である。DMLももちろん実行できるが、DDLのようにデータベース製品の機能アップによって新しい命令が追加されるものは、プリプロセッサの対応作業が重荷になるため、ほとんどのデータベース製品ではDDL文は動的SQLにて実行することが一般的となっている。
- PREPARE (文字列で与えたSQL文を解析・翻訳する)
- EXECUTE (PREPAREで翻訳したSQL文を実行する)
パラメタなし PREPARE PRESQL FROM 'DELETE FROM TBL1 WHERE CLMA=1' ↓ EXECUTE PRESQL パラメタあり(1回のPREPAREで、EXECUTEの繰り返し実行が可能) PREPARE PRESQL FROM 'DELETE FROM TBL1 WHERE CLMA=? AND CLMB=?' ↓ EXECUTE PRESQL USING :XCLMA,:XCLMB
[編集] 埋め込みSQL
もともとカーソルは、埋め込みSQLでホスト言語(母言語)から結果集合を取得するために、都合のよい方法として考えられたものである。データベースと通信するためのリソースの割り当て確保や開放、1レコードごとにホスト言語のループ処理で取得するための命令(FETCH)などがある。
- ALLOCATE(DEALLOCATE) DESCRIPTOR (データベースとホスト言語(母言語)間での通信領域の確保と開放。)
- WHENEVER (エラー発生時の振る舞いを定義)
- SQLSTATE (SQL文実行後の状態が保存される領域)
EXEC SQL INCLUDE SQLCA END-EXEC. EXEC SQL BEGIN DECLARE SECTION END-EXEC. 77 XPARM PIC X(3). 01 XTBL1. 03 XCLMA PIC X(3). 03 XCLMB PIC X(10). 01 XTBL2. 03 XCLM1 PIC S9(5) COMP-3. 03 XCLM2 PIC S9(9) COMP. EXEC SQL END DECLARE SECTION END-EXEC. EXEC SQL DECLARE CR1 CURSOR FOR SELECT CLMA,CLMB FROM TBL1 WHERE CLMA>=:XPARM ORDER BY CLMA END-EXEC. EXEC SQL WHENEVER SQLERROR GO TO ERR--PROC END-EXEC. * SQLの静的実行(カーソル操作例) MOVE 'ABC' TO XPARM. EXEC SQL OPEN CR1 END-EXEC. PERFORM TEST BEFORE UNTIL SQLCODE NOT = ZERO EXEC SQL FETCH CR1 INTO :XCLMA,:XCLMB END-EXEC IF SQLCODE = ZERO データ検索時の処理 END-IF END-PERFORM. IF SQLCODE = 100 EXEC SQL CLOSE CR1 END-EXEC END-EXEC. * SQLの動的実行(?パラメタ使用) EXEC SQL PREPARE PRESQL FROM 'INSERT INTO TBL2(CLM1,CLM2) VALUES(?,?)' END-EXEC. MOVE ZERO TO XCLM2. PERFORM TEST AFTER VARYING XCLM1 FROM 1 BY 1 UNTIL XCLM1 >= 10 EXEC SQL EXECUTE PRESQL USING :XCLM1,:XCLM2 END-EXEC END-PERFORM. GOBACK. ERR--PROC. 例外処理
[編集] 3値論理
SQLで用いられる論理値は、コンピュータの世界でもっとも広く利用されている2値論理(TRUE, FALSE)ではなく、3値論理(TRUE, FALSE, UNKNOWN)となっている。