i. カーソルの宣言
このステップでは、カーソルのプロパティと要件に従って生成される結果セットを指定する必要があります。カーソルを指定するには 2 つの方法があります。
フォーム 1 (ANSI 92)
DECLARE カーソル名 [INSENSITIVE] [SCROLL] CURSOR
FOR select_statement
[FOR {UPDATE |OF column_list]}]
フォーム 2
DECLARE カーソル名
[GLOBAL | GLOBAL]
[ FORWARD_ONLY | KEYSET |
[READ_ONLY | OPTIMISTIC]
FOR select_statement
[FOR {READ ONLY |OF column_list]}]
INSENSITIVE キーワードを指定します。一時コピーであり、今後のデータはこの一時コピーから取得されます。後続のカーソル処理中に元のベース テーブル内のデータが変更された場合、カーソルにはそのデータが表示されなくなります。この非依存カーソルではデータの変更は許可されません。
SCROLL キーワードは、カーソルが任意の方向にスクロールできることを示します。すべてのフェッチ オプション (最初、最後、次、相対、絶対) をカーソルで使用できます。このオプションを省略した場合、カーソルは前方 (次へ) にのみスクロールできます。
Select_statement は、SQL ステートメントによって作成された結果セットを指定します。 Transact SQL ステートメント COMPUTE、COMPUTE BY、FOR BROWSE、および INTO は、カーソル宣言の select ステートメントでは許可されません。
READ ONLY は、カーソル結果セットでデータの変更が許可されていないことを示します。
UPDATE キーワードは、カーソルの結果セットを変更できることを示します。
OF column_list は、変更できる結果セット内の列を指定します。デフォルトでは (UPDATE キーワードを使用)、すべての列を変更できます。
LOCAL キーワードは、カーソルがローカルであり、それが宣言されているプロセス内でのみ使用できることを示します。
GLOBAL キーワードを使用すると、カーソルが接続全体でグローバルに表示されます。グローバル カーソルは、接続がアクティブであればいつでも使用できます。接続が終了した場合にのみ、カーソルは使用できなくなります。
FORWARD_ONLY は、カーソルが前方にのみスクロールできることを指定します。
STATIC カーソルは INSENSITIVE カーソルと同じです。
KEYSET は、選択された行の順序を指定します。 SQL Server は結果セットから一時キーワード セットを作成します。データベースのキーワード以外の列に変更が加えられた場合、その変更はカーソルに表示されます。これは固定されたキーワードのセットであるため、キーワード列への変更や新しく挿入された列は表示されません。
DYNAMIC は、カーソルが結果セットに対するすべての変更を反映することを指定します。
SCROLL_LOCK は、カーソル操作の成功を保証するために変更または削除をロックします。
OPTIMISTIC は、カーソルによるどの変更または削除が成功しないかを指定します。
注:
· SELECT ステートメントで DISTINCT、UNION、または GROUP BY ステートメントが使用されており、選択内容に集計式が含まれている場合、カーソルは自動的に INSENSITIVE カーソルになります。
· ベーステーブルに一意のインデックスがない場合、カーソルは INSENSITIVE カーソルとして作成されます。
· SELECT ステートメントに ORDER BY が含まれており、ORDER BY の列が一意の行識別子ではない場合、DYNAMIC カーソルは KEYSET カーソルに変換されます。 KEYSET カーソルを開けない場合は、INSENSITIVE カーソルに変換されます。 SQL ANSI-92 構文を使用して定義されたカーソルにも同じことが当てはまりますが、INSENSITIVE キーワードは使用されません。
IIカーソルは DECLARE ステートメントによって定義されますが、実際の実行は OPEN ステートメントによって行われます。構文は次のとおりです。
OPEN { { [GLOBAL] カーソル変数名 } | カーソル変数名}
GLOBAL はグローバル カーソルを指定します。
Cursor_name は、開いているカーソルの名前です。
Cursor_variable_name は、参照されるカーソルの変数名です。変数はカーソル型である必要があります。
カーソルが開かれた後、システム変数 @@cursor_rows を使用して結果セット内の行数を検出できます。 @@cursor_rows が負の数の場合、カーソルが非同期で移行されていることを意味し、その絶対値 (@@cursor_rows が -5 の場合、絶対値は 5) が現在の結果セット内の行数になります。非同期カーソルを使用すると、カーソルが完全に移行されている間も、ユーザーはカーソルの結果にアクセスできます。 ️カーソルからオフを取得できます。カーソルがスクロール可能として定義されている場合 (宣言時に SCROLL キーワードを使用)、結果セット内の任意の行をいつでも取得できます。非スクロール カーソルの場合、フェッチ操作は現在の行の次の行に対してのみ実行できます。結果セットはローカル変数から取得できます。 Fetch コマンドの構文は次のとおりです。 @variable_name ][ ,...n]]
NEXT は、現在の行の次の行から値を取得することを示します。
PRIOR は、現在の行の前の行から値を取得することを指定します。
FIRST は結果セットの最初の行です。
LAST は結果セットの最後の行です。
ABSOLUTE n は、結果セットの n 番目の行を表します。行番号は、ローカル変数を通じて伝播することもできます。行番号は 0 から始まるため、n が 0 の場合は行を取得できません。
RELATIVE n は、取り出される行が現在の行の n 行前または n 行後であることを意味します。値が正の数の場合、フェッチされる行は現在の行の n 行前に位置します。値が負の場合、現在の行の後の行が返されます。
INTO @cursor_variable_name は、カーソル列の値が格納される変数リストを表します。このリスト内の変数の数は、DECLARE ステートメントの select ステートメントで使用される変数の数と同じである必要があります。変数のデータ型も、選択した列のデータ型と同じである必要があります。変数の値は、次回 FETCH ステートメントが使用されるまで保持されます。
各 FETCH の実行はシステム変数 @@fetch_status に保存されます。 FETCH が成功すると、@@fetch_status が 0 に設定されます。 @@fetch_status が -1 の場合は、結果セットの一部に到達したことを示します (たとえば、カーソルを開いた後にベース テーブル内の行が削除されたなど)。 @@fetch_status を使用して、カーソル処理ループを構築できます。
例:
DECLARE @iname char(20), @fname char(20)
OPEN author_cur
FETCH FROM author_cur INTO @iname, @fname
WHILE @@fetch_status = 0
BEGIN
IF @fname = 'Albert'
「見つかった Albert Ringer」を出力します
Else
「Other Ringer」を出力します
Author_cur から次を @iname、@Fname
end
にフェッチします。カーソルが閉じられた後は、FETCH 操作を実行できません。それでも FETCH ステートメントを使用する必要がある場合は、カーソルを再度開く必要があります。文法は次のとおりです: oClose [Global] Cursor_name | Cursor_variable_name
v. カーソルを解放します
カーソルの使用が必要なくなったら、カーソルを解放する必要があります。 DEALLOCATE ステートメントは、データ構造とカーソルのロックを解放します。構文は次のとおりです:
DEALLOCATE [GLOBAL] カーソル名 | カーソル変数名
カーソルの完全な例を以下に示します:
USE master
GO
CREATE PROCEDURE sp_BuildIndexes
AS
DECLARE @TableName sysname, @msg varchar(100), @cmd varchar()while @@ fetch_status =0
begin
if @@ fetch_status =-2
@msg =“テーブルのビルディングインデックス+”…”
exec(@cmd) ap_BuildIndexes
注: 上記は、ユーザー定義のシステム ストアド プロシージャを作成する例でもあります。
一時テーブルを使用する
一時テーブルは、TempDB で作成されるテーブルです。一時テーブルの名前はすべて「#」で始まります。一時テーブルのスコープは、一時テーブルを作成した接続です。一時テーブルは 2 つの接続間で共有できないため、接続が閉じられると一時テーブルは破棄されます。一時テーブルがストアド プロシージャ内で作成された場合、一時テーブルのスコープはストアド プロシージャ内、またはストアド プロシージャによって呼び出されるストアド プロシージャ内になります。接続間で一時テーブルを共有する必要がある場合は、グローバル一時テーブルを使用する必要があります。グローバル一時テーブルは「##」記号で始まり、SQL Server が再起動されるまでデータベース内に存在します。このような一時テーブルが作成されると、すべてのユーザーがそのテーブルにアクセスできるようになります。一時テーブルでは権限を明示的に指定できません。一時テーブルは、中間結果を保存する機能を提供します。一時テーブルは、複雑なクエリを 2 つのクエリに分割することによってパフォーマンスを向上させることもあります。これは、最初に最初のクエリの結果を一時テーブルに保存し、次にその一時テーブルを 2 番目のクエリで使用することによって実現できます。既存のプロシージャ中に大きなテーブルのサブセットが複数回使用される場合は、一時テーブルをお勧めします。この場合、後続の結合で使用できるようにデータのサブセットを一時テーブルに保持すると、パフォーマンスが大幅に向上します。インデックスは一時テーブルにも作成できます。
上記は SQL Server 7.0 入門 (7) の内容です。さらに関連する内容については、PHP 中国語 Web サイト (www.php.cn) に注目してください。