この項目では、データベース言語について説明しています。マーケティング活動の文脈での利用については「潜在顧客#リードの品質認定 」をご覧ください。
SQLクエリ(UPDATE文)
SQL (Structured Query Language)(エスキューエル[ 2] [ 3] 、シークェル[ 2] 、シーケル[ 4] )は、関係データベース管理システム (RDBMS) において、データ の操作や定義を行うためのデータベース言語 (問い合わせ言語 )、ドメイン固有言語 である。プログラミング においてデータベース へのアクセスのために、他のプログラミング言語 と併用される。
SQLが使われるRDBは「エドガー・F・コッド によって考案された関係データベース の関係モデル における演算体系である、関係代数 と関係論理 (関係計算)に基づいている」と宣伝されていることが多い。しかし、SQLについては、そのコッド自身をはじめ他からも、関係代数と関係論理にきちんと準拠していないとして批判されてはいる(The Third Manifesto - クリス・デイト 、ヒュー・ダーウェン )。
標準SQL規格
SQL規格は1986年に統一標準規格が発表されるまでは、その統一標準規格が存在しない状況であった。そのため、各関係データベース管理システム (RDBMS) ベンダーごとにさまざまな拡張がなされてきた。
近年になってANSI 、後にISO で言語仕様の標準化が行われており、制定された年ごとにSQL86、SQL89、SQL92、SQL:1999 、SQL:2003 、SQL:2006、SQL:2008 、SQL:2011、SQL:2016、SQL:2023などの規格があるが、対応の程度はベンダーごとにバラバラである。これは標準SQL策定に時間がかかりすぎたことにより、ビジネスの現状から早期の機能拡張が迫られたベンダーの都合と、独自構文を頻繁に利用していた利用者およびプログラマーに対し、互換性保持を保証する必要もあったためである。
そして1986年に統一標準規格が発表されて以来非常に多くの改正が行われた。制定年度順に代表的な規格を以下に挙げる。
SQLとオンライン処理
SQLはその性質上、「宣言型」の言語である。
SQLとプログラミング言語
プログラム から関係データベースを操作するための方法として、SQLが関係するものや関係しないものがあり、以下にそれらを述べる。
手続き型プログラミング言語、あるいは手続き型ではないプログラミング言語から関係データベースを操作するため、ソースコード 中にSQLを埋め込み、プリプロセッサ によってSQL部分を変換してデータベースアプリケーションを開発する方式がある。これを「埋め込みSQL」(Embedded SQL/ESQL) と呼び、後にANSIにより仕様が標準化された。
マイクロソフト は、C言語からAPI レベルで統一したソースコードを記述し、クライアント・サーバ型アプリケーションシステムの構築に有用である仕組み「Open Database Connectivity 」(ODBC) を発表し、その有用性からANSIではODBC仕様を参考に「SQL/CLI 」という仕様を標準化した。
LINQ では、プログラミング言語C# 内において、文脈によって何らかの綴りをキーワード として扱うという contextual keyword を活用し、言語内に言語の拡張のようにしてSQLライクな記述ができる。文字列ベースの埋め込みで発生するインジェクションに関係する問題や、プレースホルダの利用のようなわずらわしさが無いのが利点である。
SQLとバッチ処理
埋め込みSQLやODBC の普及により、オンライントランザクション処理 向きのSQLアクセス方法は確立されたが、バッチ処理 性能向上の必要性が求められるようになった。
ある表(テーブル) の内容を編集して別の表に格納する大量データの更新処理などをデータベースエンジン内部で処理プログラムを実行 し、入出力 (I/O) のほとんどをデータベース内部で完結することにより、クライアント側とのデータ通信によるオーバヘッドを削減することでバッチ処理性能を向上させる「ストアドプロシージャ 」 が考え出された。
ストアドプロシージャは、同じくデータベース内部に定義し、データベースに発生したイベントの内容に応じて任意の処理を実行する機能である「データベーストリガ 」とともに、標準SQL仕様に採用され、SQL:1999 (SQL99) 規格の永続格納モジュール (SQL/PSM ) として標準化された。
しかし、標準化される以前から各関係データベース管理システム (RDBMS) ベンダーがデータベースエンジン内部で制御文法を記述し実行できるように独自の拡張が行われていたため、ストアドプロシージャの処理ロジック記述文法はそれ以前に標準化されたSQL文法と比較して著しい非互換が認められるため、アプリケーションソフトウェア の移植性 ・開発生産性・保守性を損なう場合がある。
標準SQLのSQL/PSMを採用したRDBMSを以下に挙げる。これらは概ね仕様に準拠しているが、仕様に定められていない部分や実装上の理由により細部には違いがある。
各RDBMSベンダーによる標準以外の独自のプロシージャには以下のようなものがある。これらには、独自追加された制御構文だけでなく、命令やデータ型の非互換も含むため注意が必要である。
SQLの対話的実行
SQLを対話的に実行する場合、関係データベース管理システム (RDBMS) に付属するコマンドラインタイプ のアクセスユーティリティを利用するのが一般的である。SQL文を記述したテキストファイル をスクリプトとして実行し、バッチ的に実行することが可能なものもあり、広く利用されている。RDBMSごとに、そのユーティリティ固有の命令を備えているものもあるため、データベースを扱うアプリケーションソフトウェア開発の初心者はその命令もデータベースエンジンが解釈する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) では、これらは必ずしも同一の言語ではなかった。データ定義言語は存在せずにすべて専用のコマンドにパラメタを指定して実行する実装 も存在した。
コマンド文法
データ定義言語
CREATE (データベースオブジェクト(表、インデックス、制約など)の定義)
DROP (データベースオブジェクトの削除)
ALTER (データベースオブジェクトの定義変更)
データ操作言語
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
取得行数を指定した検索
SELECT *
FROM 表名
LIMIT 取得行数
データ制御言語
GRANT (特定のデータベース利用者に特定の作業を行う権限を与える)
REVOKE (特定のデータベース利用者からすでに与えた権限を剥奪する)
SET TRANSACTION (トランザクション モードの設定(並行トランザクションの分離レベル (ISOLATION MODE) など))
BEGIN (トランザクションの開始)
COMMIT (トランザクション の確定)
ROLLBACK (トランザクションの取り消し)
SAVEPOINT (任意にロールバック地点を設定する)
LOCK (表などの資源を占有する)
カーソル定義・操作
「カーソル 」とは、SELECT 文などによるデータベース検索による検索実行の結果を1行ずつ取得して処理するために、データベースサーバ側にある結果集合と行取得位置を示す概念をいう。
カーソルの定義とその操作は、主にアプリケーションプログラムなどの手続き型言語からのSQL実行において利用する。
DECLARE CURSOR (カーソル定義)
OPEN (カーソルのオープン)
FETCH (カーソルのポインタが指し示す位置の行データを取得し、ポインタを一行分進める。)
UPDATE (カーソルのポインタが指し示す位置の行データを更新する)
DELETE (カーソルのポインタが指し示す位置の行データを削除する)
CLOSE (カーソルのクローズ)
カーソル宣言例
DECLARE CR1 CURSOR FOR
SELECT CLMA , CLMB , CLMC
FROM TBL1
WHERE CLMA BETWEEN : V開始値 AND : V終了値
※V開始値、V終了値は、埋め込み変数あるいはホスト変数と呼ばれ、埋め込みSQLの場合は、プログラム中のBEGIN DECLARE SECTION 〜END DECLARE SECTION の間で宣言する。
カーソルのオープン例
※カーソルのオープン前に、V開始値、V終了値には値を設定しておく。
行の取り出し例
FETCH CR1 INTO : V列A , : V列B , : V列C
検索条件に合致した行をすべて取り出すには、「データなし」になるまでFETCHを繰り返す。
※V列A, :V列B, :V列C は、埋め込み変数あるいはホスト変数と呼ばれ、埋め込みSQLの場合は、プログラム中のBEGIN DECLARE SECTION 〜END DECLARE SECTION の間で宣言する。
取り出した行の更新例
UPDATE TBL1
SET CLMB = CLMB + 1 , CLMC = : V列C更新値
WHERE CURRENT OF CR1
FETCHで位置付けた行を更新するには、UPDATE文でWHERE CURRENT OF カーソル名 を指定する。
※V列C更新値は、埋め込み変数あるいはホスト変数と呼ばれ、埋め込みSQLの場合は、プログラム中のBEGIN DECLARE SECTION 〜END DECLARE SECTION の間で宣言する。
取り出した行の削除例
DELETE FROM TBL1
WHERE CURRENT OF CR1
FETCHで位置付けた行を削除するには、DELETE文でWHERE CURRENT OF カーソル名 を指定する。
カーソルのクローズ例
動的SQL
動的SQLは、通常SQL文をRDBMSに対して送信の度にデータベースエンジンで実行可能な内部中間コードに翻訳する作業を事前に行うことによって、翻訳済みSQLコードを再度利用してSQL解析のオーバーヘッドを削減することと、SQL文をソースコードで固定せずにデータベースへのアクセス毎に構文を書き換えたい場合に、有用である。データ操作言語 (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) となっている。
3値論理自体は古くから存在し、Fortran など数値計算においてはよく用いられる。
再帰
Oracle 9i 以来 CONNECT BY 構文がサポートされるようになり、ネットワーク型のデータ構造の処理が軽くなった。すなわち、再帰的な処理を行うさいに、ホスト側が再帰的な処理を負担するとデータサーバーとのトラフィックが増大し、その間はコミットされるまで他のサーバがデータサーバーにアクセスできないという問題があった。それを解消するために「データサーバー内で再帰的な処理を行う」というアプローチが試みられた。とはいえ、「SQL で再帰を書く」というプログラマは珍しがられた。
主な SQL
脚注
注釈
^ a b 標題はいずれも Database Language SQL
^ 標題はいずれも Database Language SQL with Integrity Enhancement
^ 非スカラー型とオブジェクト指向 機能については、いくらか論議を呼ぶことになり、いまだ広く支持されていない。
出典
参考文献
関連項目
ウィキブックスに
SQL 関連の解説書・教科書があります。