如何使用SELECT * INTO tempTable FROM CTE Query创建临时表?

245

我有一个MS SQL CTE查询,想要从中创建一个临时表。但是我不知道该如何做,因为它会出现“无效对象名称”错误。

以下是整个查询,仅供参考:

SELECT * INTO TEMPBLOCKEDDATES FROM 
;with Calendar as (
    select EventID, EventTitle, EventStartDate, EventEndDate, EventEnumDays,EventStartTime,EventEndTime, EventRecurring, EventStartDate as PlannedDate
    ,EventType from EventCalender
    where EventActive = 1 AND LanguageID =1 AND EventBlockDate = 1
    union all
    select EventID, EventTitle, EventStartDate, EventEndDate, EventEnumDays,EventStartTime,EventEndTime, EventRecurring, dateadd(dd, 1, PlannedDate)
    ,EventType from Calendar
    where EventRecurring = 1
        and dateadd(dd, 1, PlannedDate) <= EventEndDate 
)
select EventID, EventStartDate, EventEndDate, PlannedDate as [EventDates], Cast(PlannedDate As datetime) AS DT, Cast(EventStartTime As time) AS ST,Cast(EventEndTime As time) AS ET, EventTitle
,EventType from Calendar
where (PlannedDate >= GETDATE()) AND ',' + EventEnumDays + ',' like '%,' + cast(datepart(dw, PlannedDate) as char(1)) + ',%'
    or EventEnumDays is null
order by EventID, PlannedDate
option (maxrecursion 0)

我希望能得到指引,或者知道是否可以从这个CTE查询中创建临时表。


这是如何操作的:https://dev59.com/vHA75IYBdhLWcg3wboUz - Luxspes
2
@RGI,两个答案都适用于我的情况,我选择了Martin的回答并点赞。感谢你的回答。我更喜欢你的回答,因为你提到了临时查询的删除部分。也为你的回答点赞。 - Learning
8个回答

318

示例 DDL

create table #Temp
(
    EventID int, 
    EventTitle Varchar(50), 
    EventStartDate DateTime, 
    EventEndDate DatetIme, 
    EventEnumDays int,
    EventStartTime Datetime,
    EventEndTime DateTime, 
    EventRecurring Bit, 
    EventType int
)

;WITH Calendar
AS (SELECT /*...*/)

Insert Into #Temp
Select EventID, EventStartDate, EventEndDate, PlannedDate as [EventDates], Cast(PlannedDate As datetime) AS DT, Cast(EventStartTime As time) AS ST,Cast(EventEndTime As time) AS ET, EventTitle
,EventType from Calendar
where (PlannedDate >= GETDATE()) AND ',' + EventEnumDays + ',' like '%,' + cast(datepart(dw, PlannedDate) as char(1)) + ',%'
    or EventEnumDays is null

使用完毕后,请确保删除该表

If(OBJECT_ID('tempdb..#temp') Is Not Null)
Begin
    Drop Table #Temp
End

10
为什么有两个句号?这是打错了吗? - Mike Cole
30
省略模式的指定是使用“..”。例如,tempdb.dbo.#temp可以写成tempdb..#temp。 - sam
16
这并没有回答这个问题。原帖的作者明确询问了如何使用Select Into,而这个回答并没有解决这个问题。虽然这是一个好回答,但不是正确的回答。 - DaveInAZ
关于模式名称,文档也指出:如果在创建或访问临时表时包含模式名称,则会被忽略。所有临时表都将在dbo模式中创建。 - JvR

265

事实上,格式可以非常简单 - 有时不需要预定义一个临时表 - 它会从select的结果中创建。

Select FieldA...FieldN 
into #MyTempTable 
from MyTable

所以,除非你想要不同类型或者对定义非常严格,否则请保持简单。需要注意的是,在存储过程内部创建的任何临时表在存储过程执行完成后会自动删除。如果存储过程A创建了一个临时表并调用存储过程B,那么B将能够使用A创建的临时表。

然而,通常被认为是良好的编码实践,无论如何都要显式地删除您创建的每个临时表。


4
如果我在代码中没有使用drop table命令删除临时表,那么临时表在执行后会在数据库中存在多久?因为我两次执行了"select * into #temp"代码,但第二次执行时出现错误:"表#temp已经存在于数据库中"。 - TomasMolina
6
@Kurapika 连接的时间长度。 - Jonesopolis
22
我们不需要在使用表之前显式创建它,这一事实是答案中最相关的事实。谢谢! - Alfabravo

46

如何在存储过程中使用临时表?

以下是步骤:

CREATE TEMP TABLE

-- CREATE TEMP TABLE 
Create Table #MyTempTable (
    EmployeeID int
);

插入临时数据到临时表

-- INSERT COMMON DATA
Insert Into #MyTempTable
Select EmployeeID from [EmployeeMaster] Where EmployeeID between 1 and 100

选择临时表(现在您可以使用此选择查询)

Select EmployeeID from #MyTempTable

最后一步,删除表格

Drop Table #MyTempTable

我希望这会有所帮助。简单明了 :)


13
这并没有回答问题。OP明确要求使用"Select Into"语句来完成,而这个回复并没有满足要求。 - DaveInAZ

32

SELECT ... INTO 需要在 CTE 的 select 中。

;WITH Calendar
     AS (SELECT /*... Rest of CTE definition removed for clarity*/)
SELECT EventID,
       EventStartDate,
       EventEndDate,
       PlannedDate                   AS [EventDates],
       Cast(PlannedDate AS DATETIME) AS DT,
       Cast(EventStartTime AS TIME)  AS ST,
       Cast(EventEndTime AS TIME)    AS ET,
       EventTitle,
       EventType
INTO TEMPBLOCKEDDATES /* <---- INTO goes here*/        
FROM   Calendar
WHERE  ( PlannedDate >= Getdate() )
       AND ',' + EventEnumDays + ',' LIKE '%,' + Cast(Datepart(dw, PlannedDate) AS CHAR(1)) + ',%'
        OR EventEnumDays IS NULL
ORDER  BY EventID,
          PlannedDate
OPTION (maxrecursion 0) 

18

以下是一项微小更改,用于在执行查询时创建表格(即您无需先创建表格):

SELECT * INTO #Temp
FROM (
select OptionNo, OptionName from Options where OptionActive = 1
) as X

不确定为什么这不是被接受的答案,但是谢谢! - d0rf47

11
Select      Eventname, 
            count(Eventname) as 'Counts'
INTO        #TEMPTABLE                                                                                
FROM        tblevent
where       Eventname like 'A%'
Group by    Eventname
order by    count(Eventname)

通过使用 into 子句,表会直接被创建。


4
这与现有答案有何不同? - zx8754

1
你还应该知道存在全局临时表。这些表可以从另一个连接中引用。它们的行为与早期答案所描述的基本相同。要创建一个全局临时表,只需在表名前加上 ##。这就是我正在寻找的内容;希望其他人也会发现这很有用。

0

您还可以使用View创建临时/虚拟表 CREATE VIEW view_name AS SELECT column1, column2, ... FROM table_name WHERE condition;


3
这个回答太模糊了。 - Vega

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接