如何从不同的表中有条件地插入INTO?

时间:2019-01-20 13:20:21

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

我正在编写存储过程以进行一些常规检查,在存储过程中,我具有类似以下的代码,以避免创建过多的@variables

IF type = 'spl' 
THEN BEGIN
    SELECT col1, col4, col5, col9, col20, ... INTO #tmp
    FROM tbl1 
    WHERE primary_key = unique_id
END
ELSE BEGIN
    SELECT col1, col5, col7, col8, col19, ... INTO #tmp
    FROM tbl2
    WHERE primary_key = unique_id
END

尽管这两个INSERT永远无法同时运行,但仍会导致#tmp table already exist错误,并且无法创建存储过程。

有什么共同的解决办法吗?

以下内容当然是可能的,但是看上去比声明@variables还要糟。但这是我唯一可以拿出atm的东西。

SELECT * 
INTO #TEMP 
FROM 
     (SELECT 
          CASE WHEN type = 'spl' 
                  THEN a.col1 
                  ELSE b.col1 
               END, 
   ...
   FROM ... CROSS JOIN ... 
)

1 个答案:

答案 0 :(得分:1)

您可以通过将多个数据源与union all组合并具有单独的where子句来从多个数据源进行“条件”插入:

insert into #tmp
  select col1, col2, ...
    from tbl1
    where @type = 'spl' and primary_key = unique_id
  union all
  select col1, col2, ...
    from tbl2
    where @type <> 'spl' and primary_key = unique_id;

如果要为您创建输出表,可以将select ... into ...where子句一起使用,以防止插入任何行。结果将是具有正确架构的空表:

-- Create empty   #tmp   table.
select col1, col2, ...
  from tbl1
  into #tmp
  where 42 = 6 * 9; -- Answer to the Ultimate Question of Life, the Universe, and Everything.

请注意,使用if / then执行单独的查询可以使查询优化器为每个查询生成最佳计划,而不是为整个union all进行混搭,并且使长期维护的意图更加清晰。

这也是阅读parameter sniffing的好时机。