5

Can any one please tell me where to use CTE, temp table and table variable?

I read about their differences but i'm confused with their usage. please help.

Thanks.

4

1 回答 1

7

您可以使用 CTE 代替子查询或在需要递归时使用。

CTE 仅在包含它的 SQL 语句中可用。前面和后面的语句将无法访问它,也不会看到它。它的行为类似于子查询,但可以在以下选择/更新中多次使用。

这个带有子查询的查询和一个子查询使用了两次:

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 回答