2010-11-11 12 views
6

我想根据SQL 2005中的条件结果填充临时表。临时表将具有相同的结构,无论哪种方式,但将填充使用一个不同的查询取决于条件。下面的简化示例脚本失败在ELSEINSERT INTO的语法检查用的错误:SQL插入临时表在If和Else块中

已经有一个在数据库中名为 “#MyTestTable”的对象。

DECLARE @Id int 
SET @Id = 1 

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

IF (@Id = 2) BEGIN 
    SELECT 'ABC' AS Letters 
    INTO #MyTestTable; 
END ELSE BEGIN 
    SELECT 'XYZ' AS Letters 
    INTO #MyTestTable; 
END 

我可以在IF/ELSE语句之前创建临时表,然后就做在条件块INSERT SELECT语句,但该表将有很多列的,我是想有效率了。这是唯一的选择吗?或者有什么方法可以做到这一点?

谢谢, 马特

回答

5

您遇到的问题不是您正在填充临时表,而是您正在尝试创建表。 SQL解析你的脚本,发现你正试图在两个不同的地方创建它,这样就会产生一个错误。认识到“执行路径”不可能同时创建两个创建状态并不够聪明。使用动态SQL将不起作用;我试过

DECLARE @Command varchar(500) 

DECLARE @Id int 
SET @Id = 2 

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

IF (@Id = 2) BEGIN 
    SET @Command = 'SELECT ''ABC'' AS Letters INTO #MyTestTable' 
END ELSE BEGIN 
    SET @Command = 'SELECT ''XYZ'' AS Letters INTO #MyTestTable' 
END 

EXECUTE (@Command) 

select * from #MyTestTable 

但临时表只会持续到动态会话的时间。所以,唉,看起来你必须首先声明表并填充它。也许,尴尬的代码来编写和支持,但它会有效地执行。

+1

我的回答既不是建议使用动态SQL,也不是建议使用动态SQL - 事实上,它表明动态SQL *不能用于解决问题,并得出结论:在数据插入之前特别声明临时表可能是最好的选择。 – 2014-06-04 14:11:15

+0

您可以使用动态SQL并插入全局临时表(## MyTesttable),然后删除全局表。将添加为一个单独的答案 – Rym 2017-07-26 09:43:57

2

在你提供,你可以做到这一点

DECLARE @Id int 
SET @Id = 1 

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

SELECT 
    CASE WHEN (@Id = 2) 
    THEN 'ABC' 
    ELSE 'XYZ' 
    END AS Letters 
INTO #MyTestTable; 

;否则,您将需要if statement这样

Create Table #MyTestTable (
    MyValue varchar(3) 
) 
IF (@Id = 2) BEGIN 
    Insert Into (MyValue) 
    SELECT 'ABC' AS Letters; 
END ELSE BEGIN 
    Insert Into (MyValue) 
    SELECT 'XYZ' AS Letters; 
END 
+0

是的,这种情况下,将工作。但实际的查询要复杂得多。 – CuppM 2010-11-11 15:29:32

-1

之前创建表的情况下,您在两种情况下都可以在选择之前删除表格,例如:

DECLARE @Id int 
SET @Id = 1 

IF (@Id = 2) BEGIN 
    IF OBJECT_ID('tempdb..#MyTestTable') IS NOT NULL DROP TABLE #MyTestTable 
    SELECT 'ABC' AS Letters 
    INTO #MyTestTable; 
END ELSE BEGIN 
    IF OBJECT_ID('tempdb..#MyTestTable') IS NOT NULL DROP TABLE #MyTestTable 
    SELECT 'XYZ' AS Letters 
    INTO #MyTestTable; 
END 

更新后评论:

这很烦人。

两张单独的临时表怎么样?然后在If/Else登录后,检查每个存在,如果存在,请选择第三个临时表?这可能表现不佳,但是否重要取决于你需要的东西。

+0

我试过了。我在'INSERT INTO'语句之前的每个块中放入了'IF OBJECT_ID('tempdb ..#MyTestTable')IS NOT NULL DROP TABLE#MyTestTable',但结果相同。 – CuppM 2010-11-11 15:30:28

+0

这是一个倒退?真? – 2010-11-11 15:52:32

+0

不是我。但也许是因为你的建议没有通过语法检查?我认为2个独立的临时表开始做比在IF/ELSE之前创建临时表更多的工作。 – CuppM 2010-11-11 15:54:57

0

这是一个老问题,但对于其他人来到这里:

用户菲利普·凯利给出了本地临时表(#Mytemp)不工作动态SQL答案。你可以做的是创建动态SQL,将其插入到全局临时表(##MyTemp)中,稍后可以删除它。

DECLARE @Command varchar(500) 

DECLARE @Id int 
SET @Id = 2 

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

IF (@Id = 2) BEGIN 
    SET @Command = 'SELECT ''ABC'' AS Letters INTO ##MyTestTable' 
END ELSE BEGIN 
    SET @Command = 'SELECT ''XYZ'' AS Letters INTO ##MyTestTable' 
END 

EXECUTE (@Command) 

select * from ##MyTestTable 

DROP ##MyTestTable 
0

这段代码可以帮助你

--creating temptable using columns of two existing tables 
--you can create your temp table Using other methods 

select top 0 VI.*,VU.FullName 
into #mytemptable 
from dbo.Items VI inner join 
    dbo.Users as VU 
    on VU.Id=VI.Id 

--insert your data base on your condition 
if(i<2) --First Condition 
begin 
INSERT INTO #mytemptable 
SELECT VI.*,VU.FullName 
from dbo.Items VI inner join 
    dbo.Users as VU 
    on VU.Id=VI.Id 
end 
Else if(2<i) --Second Condition 
begin 
INSERT INTO #mytemptable 
SELECT VI.*,VU.FullName 
from dbo.Items VI inner join 
    dbo.Users as VU 
    on VU.Id=VI.Id 
end 

select * from #mytemptable --show result 

drop table #mytemptable --drop table if its needed 

此代码在SQL Server 2014 我不知道它在SQL 2005或不

1

接听工作8年较晚,但我很惊讶没人想到:

select * into #MyTempTable 
where 1=2 

IF -- CONDITION HERE 
insert into #MyTempTable select... 
ELSE 
insert into #MyTempTable select... 

简单,快速,它的工作原理。没有动态的SQL需要