【问题标题】:IF... ELSE... two mutually exclusive inserts INTO #temptableIF... ELSE... 两个互斥插入 INTO #temptable
【发布时间】:2017-08-19 21:21:04
【问题描述】:

我需要根据特定条件将记录集 A 或记录集 B 插入#temptable

我的伪代码:

IF OBJECT_ID('tempdb..#t1') IS NOT NULL DROP TABLE #t1;

IF {some-condition}
  SELECT {columns}
  INTO #t1 
  FROM {some-big-table}
  WHERE {some-filter}
ELSE
  SELECT {columns}
  INTO #t1
  FROM {some-other-big-table}
  WHERE {some-other-filter}

上面的两个 SELECT 是互斥的(由 ELSE 运算符保证)。但是,SQL 编译器试图比我聪明,并抛出以下消息:

There is already an object named '#t1' in the database.

我“解决”这个问题的想法是预先创建#t1,然后执行一个简单的 INSERT INTO(而不是 SELECT...INTO)。但我喜欢极简主义,我想知道这是否可以通过更简单的方式实现,即无需预先明确 CREATE TABLE #t1。

顺便说一句,为什么它在第一行的条件 DROP TABLE 上没有给我一个错误?只是想知道。

【问题讨论】:

  • 回答你最后一个问题; DROP TABLE #t1 只会在 IF 语句返回 true 时执行,即表存在。正如您所说的要简化,您可以将其重写为IF EXISTS(OBJECT_ID('tempdb..#t1')) DROP TABLE #t1;
  • @PatrikBirgersson 我明白了!但是,我并不想知道如何简化那行特定的代码。更多的是关于无法在分支的 IF...ELSE 块中运行条件 SELECT ... INTO #temptable... 与能够在第一行中执行 #temptable 的条件 DROP 之间的不一致。 Rajesh 的回复打消了我所有的疑惑。

标签: tsql if-statement sql-server-2012 compiler-errors temp-tables


【解决方案1】:

在一个 SQL 批处理中不能有 2 个同名的临时表。其中一篇 MSDN 文章说“如果在单个存储过程或批处理中创建了多个临时表,则它们必须具有不同的名称”。您可以使用在 IF-Else 块之外声明的 2 个不同的临时表或表变量/临时表来使用此逻辑。

【讨论】:

    【解决方案2】:

    使用 Dynamic sql 我们可以处理这种情况。作为开发人员,这不是一个好习惯。最好使用表变量或临时表。

    IF 1=2
    BEGIN
    EXEC ('SELECT 1 ID INTO #TEMP1
    SELECT * FROM #TEMP1
    ')
    END
    ELSE
    EXEC ('SELECT 2 ID INTO #TEMP1
    SELECT * FROM #TEMP1    
    ')
    

    【讨论】:

    • 谢谢,这肯定会工作到某个点,即它会填充#temp,然后返回它的所有行。但是,我在后续查询中使用 #temp 表,这使您的方法不适合我的情况。我最终创建了一个 #temp 表并使用 INSERT INTO...
    猜你喜欢
    • 2015-07-08
    • 2011-11-21
    • 1970-01-01
    • 2019-11-08
    • 2019-09-21
    • 1970-01-01
    • 2015-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多