【问题标题】:How to use an IF statement within a view to drop/use a #Temp Table?如何在视图中使用 IF 语句来删除/使用#Temp 表?
【发布时间】:2019-08-09 10:13:08
【问题描述】:

我需要创建一个视图,它以以下 SQL 开头:

IF OBJECT_ID('tempdb..#TempTable') Is Not null
Drop Table #TempTable

我还在视图中进一步重建此 #TempTable,然后将 Temptable 中的数据用于查询的其余部分 - 以获得更好的性能。见:

Reduce cost for Table Valued Function - XML Reader in query plan - how?

但是,SSMS 告诉我:

Incorrect syntax near the keyword 'IF'
Views or functions are not allowed on temporary tables. 
Table names that begin with '#' denote temporary tables.

有没有什么办法可以使用IF语句,把Temptable去掉,然后在视图中使用重建的Temptable?

回答 - 我需要使用存储过程,而不是视图。

【问题讨论】:

  • 你不能。 “视图是一个虚拟表,其内容由查询定义” (Views)。 View 实际上是一个预编译的SELECT 语句,仅此而已。您不能使用VIEW 来执行 DDL 或 DML 操作。您在这里试图解决的实际问题是什么?也许你在这里真正追求的是一个存储过程?
  • 刚刚研究了一些,存储过程是运行上述查询的另一种方式。

标签: sql sql-server tsql sql-server-2012


【解决方案1】:

存储过程与视图完全不同。视图只是一个封装的查询。

但是,存储过程不能在SELECT 语句中使用。您只能使用EXEC 执行它。

您可能想要的是user-defined function (UDF)。 UDF 返回一个表,因此可以在查询的FROM 子句中引用它们。与视图不同的是,它们可以包含多个语句并且可以有参数。

请注意,无需删除存储过程或函数中的临时表。如果在代码体中声明了临时表,则在退出代码时会自动将其删除。但是,您可能希望使用表变量。

【讨论】:

  • Gordon,用户偶然发现了这样一个事实,即查询花费了很长时间,这有助于将工作分成两个步骤。 OP 在想,CTE 的处理方式就像一张桌子。但是在链接的问题中,优化器可能没有减少集合之前昂贵的动作发生。在这种情况下,UDF 将具有与视图相同的限制...您知道任何技巧吗,如何强制引擎首先执行 CTE 并继续使用缩减集而不离开 ad-hoc ?
  • @Shnugo 。 . .我不确定我是否完全理解你的问题。 UDF 可以包含临时表和表变量,因此可以类似地进行优化。
  • 嗯,评论可能是讨论这个问题的错误地方......当我有时间时,我可能会提出一个完整的问题......我不知道,如果一个 multi-语句 UDF 会在此处欺骗优化器... 抽象地说:有一个非常大的集合和一个昂贵的操作。但是这个昂贵的操作是针对从大集合中提取的非常减少的集合来完成的。在某些情况下,引擎不会看到这一点,并且会在集合减少之前执行昂贵的操作。在这种情况下,我想告诉引擎,应该按什么顺序完成。
  • 感谢您的提示。但是我被告知我不能在我们的数据库中创建 UDF。所以我将不得不重新使用我原来的 CTE,但使用 WHERE 子句来限制 CTE 中返回的行数,以便查询可以在合理的时间内完成
猜你喜欢
  • 1970-01-01
  • 2015-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-19
  • 2021-11-26
  • 2020-12-16
  • 1970-01-01
相关资源
最近更新 更多