【问题标题】:CTE,Temp table and table variableCTE、临时表和表变量
【发布时间】:2015-11-09 18:17:31
【问题描述】:

谁能告诉我在哪里使用CTEtemp tabletable variable

我了解了它们的区别,但我对它们的用法感到困惑。请帮忙。

谢谢。

【问题讨论】:

    标签: common-table-expression sql-server-2014 temp-tables table-variable


    【解决方案1】:

    您可以使用 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)。它将一直可用,直到它被丢弃或服务器重新启动。

    【讨论】:

      猜你喜欢
      • 2017-05-27
      • 2011-07-15
      • 1970-01-01
      • 2019-11-21
      • 2022-01-09
      • 1970-01-01
      • 2014-06-03
      • 2022-10-05
      • 2015-07-19
      相关资源
      最近更新 更多