1. 遭遇した問題
実際には、大きな問題ではありませんO(∩_∩)O: バッチ処理やストレージ処理で選択結果セットを直接処理したい場合がありますが、このときデータベースが必要になります。このオブジェクトを使用すると、レコードの各行を 1 つずつ処理できます。
2. カーソルの概念
上記の問題を解決するには、「カーソル」と呼ばれるデータベースオブジェクトを使用できます。
カーソル(Cursor)は、結果セットを走査するために使用できるデータ型とみなすことができ、ポインタまたは配列の添字に相当します。結果セットを処理するための次のメソッドがあります:
結果セット内の特定の行を配置する
現在の結果セットの位置から行または行の一部を検索する
内の現在の行のデータを変更する結果セット
3. カーソル 使用方法(作成、開く、読み取る、閉じる、削除)
【カーソルの作成】
は、各種データ型の定義方法と似ていますが、「@」を付けないように注意してください。 (実際には「カーソル型変数」というものもあり、使い方は「カーソル」とほぼ同じで、定義する際には@記号を使います)。カーソルを定義する文は次のとおりです:
declare カーソル名 カーソル [local|global] [forward_only|scroll]
for
select query 文
カーソルは、ローカル カーソルとグローバル カーソル ローカルの 2 種類に分けられます。ローカルカーソル、グローバルを意味します グローバルカーソルを表します(デフォルト値、省略可能)。 forward_only (デフォルト値、省略可能) を指定すると、カーソルは前方のみになります。これは、レコードを先頭から末尾までのみ抽出できることを意味します。行間を行き来する必要がある場合は、scroll を指定する必要があります。
【カーソルを使う】
カーソルは作っただけで使わないと意味がありません。カーソル作成後の手順を示す最も簡単な例を見てみましょう:
--[カーソルの作成]
yirenからxingmingを選択するためにC1カーソルを宣言します
@xingming varchar(20)を宣言します
--[カーソルを開く]
open C1
--[読み込みカーソル]
C1から@xingmingに次をフェッチ --whileの特徴は、最初に一度書く必要があること
while(@@FETCH_STATUS=0)
begin
print 'Name:'+@xingming
fetch next from C1 into @xingming
end
--[カーソルを閉じる]
C1を閉じる
--[カーソルを削除]
C1の割り当てを解除
カーソル という使い方です。 Java の whle(rs.next()){} に似たメソッドですか? 実際、rs.next() が実行されると、結果セットの最後に到達しない場合、結果セット内を直接後方に移動します。ループ本体は引き続き実行されます。ここでのカーソルの使用についても同様です。@@FETCH_STATUS の値が 0 の場合、カーソルはまだ最後に到達していません。 0 でなくなると、カーソルは末尾に到達し、ループを終了します。
カーソル名から変数名リストに次をフェッチするのは、カーソルの内容を読み取る定型形式のメソッドです。クエリ ステートメントで複数のフィールドを選択する場合、読み取り時にこの文を使用して複数の変数に値を割り当てる必要もあります。したがって、変数名のリストとして記述します。
【グローバル カーソルとスクロール カーソル】
前にグローバル カーソルとスクロール カーソルについて説明しましたが、例を示します:
if(CURSOR_STATUS('global','CURSOR_2')!=-3) deallocate CURSOR_2
declare CURSOR_2cursorスクロール --グローバル スクロール カーソル
yiren から xingming、niche、xingbie を選択するため
--最初の T-SQL バッチが開始します
open CURSOR_2
declare @seq int,
@xingming varchar(20) ,@nicheng varchar(50),@xingbie nchar
set @seq=4
CURSOR_2から絶対@seqを@xingming,@nicheng,@xingbie
if(@@FETCH_STATUS=0)
begin
print '+ Cast(@seq as varchar)+' アーティストは: '+@xingming
print case @xingbie when ' Male' then 'him' when ' Female' then 'her' end
+' ニックネームは: '+@ nicheng
end
close CURSOR_2
--2番目のT-SQLバッチが開始します
open CURSOR_2
declare @seq int,
@xingming varchar(2 0),@ nicheng varchar(50),@xingbie nchar
set @seq=5 -- 2つのバッチに分かれており、再度@seqを定義する必要があります
CURSOR_2から@xingming,@nicheng,@xingbieに絶対@seqを取得します
if( @@FETCH_STATUS=0)
begin
print '+cast(@seq as varchar)+' アーティストは: '+@xingming
print case @xingbie when ' Male' then 'him' when ' Female ' then 'she' end
+' ニックネームは: '+@nicheng
end
close CURSOR_2
go
--3回目のバッチでカーソルを削除
deallocate CURSOR_2
スクロールがオンのとき オプションの後、fetchを使用して次を読み取ることができます(移動) back)、previor (前に移動)、first (最初の行)、last (最後の行)、absolute (数値による絶対行への位置)、relative (数値による相対行への位置)。
グローバルカーソルは一度定義すると常に存在するので、すべてのバッチから見ることができます。これは、deallocate を使用して削除するまで消えません。 CURSOR_STATUS('global','CURSOR_2') でステータスを確認できます。
【カーソルの入れ子】
システムのパフォーマンスに大きく影響するので、簡単に見てみましょう。
if(CURSOR_STATUS('global','CURSOR_3')!=-3) CURSOR_3の割り当て解除
CURSOR_3のカーソルを宣言
yanchuidからyanchuidを選択
CURSOR_3を開く
@ycid intを宣言
CURSOR_3から次をフェッチ
into @ycid
while(@@FETCH_STATUS=0)
begin
print '「+cast(@ycid as varchar)+」番目のパフォーマンスに参加しているアーティストは:'
のCURSOR_4カーソルを宣言しますselect xingming from yiren where yirenid in
(select yirenid from yanchuyiren where yanchuid=@ycid)
--この文はサブクエリを使用しており、実際にカーソルをネストできます
declare @xingming varchar(50)
open CURSOR_4
CURSOR_4から次を@xingmingにフェッチ
while(@@FETCH_STATUS=0)
begin
print @xingming
CURSOR_4から次を@xingmingにフェッチ
end
close CURS OR_4
CURSOR_4の割り当てを解除
フェッチnext from CURSOR_3
into @ycid
print ''
end
close CURSOR_3
deallocate CURSOR_3
【カーソル変数】
カーソル変数は実際にカーソルを使用するデータ型として扱います, の違いは、カーソル変数とカーソルオブジェクトは@の有無です。カーソル変数を作成する場合は、まず@cursor変数名cursorを宣言し、select文で@cursor変数名=cursorを設定します。
@c1 CURSORを宣言します
yirenからxingmingを選択するために@c1=cursorを設定します
open @c1
@xingming varchar(50)を宣言します
@c1から@xingmingに次を取得します
print @xingming
閉じる@c1
deallocate @c1
IV. カーソルの注意点
【カーソルのデメリット】
カーソルを使うと結果セットを一つずつ取り出して処理するため、サーバーの負担が大きくなります。カーソルは、デフォルトの結果セットを使用するほど効率的ではありません。したがって、カーソルが使用できない場合は、使用しないようにしてください。
【カーソルの補足説明】
カーソルを開いただけでは、最初のレコードを指すのではなく、最初のレコードの前を指します。本に例えると、カーソルはレコード セット内のレコード (本の内容の各ページ) を指すだけでなく、レコード セットの外側にレコードがない場所 (表紙や裏表紙) も指すことができます。本の表紙)。
@@fetch_statusには3つの値があり、0はフェッチが正常に実行されることを意味し、-1はフェッチが結果セットを超えることを意味し、-2はフェッチが指す行がもう存在しないことを意味します。
5. ページング クエリ ストアド プロシージャを変更し、カーソルを使用します
最初の分岐を次のコードに変更します:
if @currentpage >1
begin
if @currentpage>@totalpages
begin
set @ currentpage = @totalpages
end
declare @start int,@count int
set @count = 0
set @start = @currentpage*@pagesize+1
set @sql='declarecursor_1 カーソルスクロールselect * from '
+@tablename+' order by '+@idname
exec(@sql)
カーソル_1を開く
カーソル_1から相対的な@start,@pagesizeを取得
while @@fetch_status=0
begin
set @count = @count+1
cursor_1から次を取得
if @count=@pagesize-1
break
end
closecursor_1
deallocatecursor_1
end
そして、
を削除します前にオリジナルの goExec(@sql)
以上です。この文を削除しない場合、この文はストアド プロシージャの最後で再度実行されるため、誤って @cursor_1 カーソルが再度生成されます。