我正在编写存储过程以进行一些常规检查,在存储过程中,我具有类似以下的代码,以避免创建过多的@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 ...
)
答案 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的好时机。