是否可以在视图中创建临时表并在选择后删除它?

pen*_*ake 39 t-sql sql-server

我需要改变一个视图,我想在SELECT之前引入2个临时表.

这可能吗?我怎么能这样做?

ALTER VIEW myView
AS 

SELECT *
INTO #temporary1

SELECT *
INTO #temporary2

SELECT * FROM #temporary1
UNION ALL 
SELECT * FROM #temporary1

DROP TABLE #temporary1
DROP TABLE #temporary2
Run Code Online (Sandbox Code Playgroud)

当我尝试这个时,它抱怨ALTER VIEW必须是批处理中唯一的语句.

我怎样才能做到这一点?

Mar*_*icz 79

不,视图由单个SELECT语句组成.您无法在视图中创建或删除表.

也许公用表表达式(CTE)可以解决您的问题.CTE是在单个语句的执行范围内定义的临时结果集,可以在视图中使用它们.

示例(取自此处) - 您可以将SalesBySalesPersonCTE视为临时表:

CREATE VIEW vSalesStaffQuickStats
AS
  WITH SalesBySalesPerson (SalesPersonID, NumberOfOrders, MostRecentOrderDate)
      AS
      (
            SELECT SalesPersonID, COUNT(*), MAX(OrderDate)
            FROM Sales.SalesOrderHeader
            GROUP BY SalesPersonID
      )
  SELECT E.EmployeeID,
         EmployeeOrders = OS.NumberOfOrders,
         EmployeeLastOrderDate = OS.MostRecentOrderDate,
         E.ManagerID,
         ManagerOrders = OM.NumberOfOrders,
         ManagerLastOrderDate = OM.MostRecentOrderDate
  FROM HumanResources.Employee AS E
  INNER JOIN SalesBySalesPerson AS OS ON E.EmployeeID = OS.SalesPersonID
  LEFT JOIN SalesBySalesPerson AS OM ON E.ManagerID = OM.SalesPersonID
GO
Run Code Online (Sandbox Code Playgroud)

  • 但问题是,根据您想要执行的操作,CTE 会针对 SELECT 中的每条记录重新评估。这仍然会对性能造成巨大影响。想要一种让 CTE 运行“一次”并反复使用结果的方法,就像临时表一样 (3认同)
  • @Fandango68 好点!我刚刚为每个想要更深入分析它的人链接了 /sf/answers/1834356121/。 (2认同)
  • @Fandango68 是对的,我使用具有 20k 记录的表将 CTE 方法与 INNER JOIN 进行了比较,将表与其自身连接以过滤掉部分重复的记录。与 INNER JOIN 方法(4 秒)相比,CTE 慢得多(12 秒)。 (2认同)

Emi*_*dın 5

Stored Procedure您可以使用返回查询结果的方法来实现您想要做的事情。Views不适合/不适合这样的操作。

  • 请注意:在存储过程中创建临时表将导致该过程被**重新编译(因为架构更改),并且用数据填充它可能会导致**第二次重新编译(因为统计信息更改)。这不是一个很好的方法...... (6认同)