5

CTEtemp tableおよび をどこで使用するtable variableか教えてください。

私はそれらの違いについて読みましたが、それらの使用法に混乱しています。助けてください。

ありがとう。

4

1 に答える 1

7

サブクエリの代わりに、または再帰性が必要な場合に CTE を使用できます。

CTE は、それを含む SQL ステートメントの実行中にのみ使用できます。前後のステートメントはアクセスできず、表示されません。サブクエリのように動作しますが、次の選択/更新で数回使用できます。

サブクエリを含むこのクエリは、サブクエリを 2 回使用します。

Select D.* From D
Inner Join (
        Select id value, date From A
        Inner Join B on A.data < B.date
        Inner Join C on C.data > B.date
    ) CTE a c1 on c1.id = D.id+1
Inner Join (
    Select id value, date From A
    Inner Join B on A.data < B.date
    Inner Join C on C.data > B.date
) as c2 on c2.id = D.id-1

CTE に置き換えることができます。

; with CTE as (
    Select id value, date From A
    Inner Join B on A.data < B.date
    Inner Join C on C.data > B.date
)
Select D.* From D
Inner Join CTE as c1 on c1.id = D.id+1
Inner Join CTE as c2 on c2.id = D.id-1

これは、同じサブクエリを何度も記述する必要がないため、この場合に役立ちます。

再帰的 CTE (これは単なる例です。これは、このような文字列データを操作するための SQL Server ジョブであってはなりません):

Declare @data varchar(50) = 'Recursive CTE' 
; With list(id, letter) as (
    Select 1, SUBSTRING(@data, 1, 1)
    Union All
    Select id+1, SUBSTRING(@data, id+1, 1) From list
    Where id < len(@data)
) 
Select * from list

再帰 CTE を使用して、階層内のデータを取得できます。

テーブル変数

テーブル変数は、クエリの実行中にのみ存在します。作成後、すべての SQL ステートメントに表示されます。

これらは、テーブル型パラメーターを使用してストアド プロシージャまたは関数にデータを渡す必要がある場合に使用できます。

Create Proc test(
    @id int,
    @list table_type_list READONLY
)
begin
    set nocount on
    select * from @list
end

Declare @t table_type_list
Insert into @t(name) values('a'), ('b'), ('c')
Exec test 1, @t

大きすぎず、インデックスを必要としないものを格納する必要がある場合にも使用できます。テーブル宣言の主キーまたは一意制約によってインデックスが自動的に作成されますが、手動でインデックスを作成することはできません。

テーブル変数に対して作成される統計はなく、統計を作成することはできません。

一時テーブル

一時テーブルは、インデックスと統計の作成から恩恵を受けるより多くのデータを扱う場合に使用できます。

セッションでは、テーブルが作成されると、どのステートメントでもテーブルを使用または変更できます。

create table #temp
Insert into #temp(...) select ... From data
exec procA
exec procB
exec procC

ProcA、ProcB、および ProcC はいずれも、#temp からデータを選択、挿入、削除、または更新できます。

テーブル #temp は、ユーザー セッションが閉じられるとすぐに削除されます。

セッション間で一時テーブルを保持したくない場合は、グローバル一時テーブル (##temp) を使用できます。ドロップするか、サーバーを再起動するまで使用できます。

于 2015-08-17T13:08:25.157 に答える