我在这里遇到了僵局,问题是我必须改变一个使用3个不同临时表的程序。让我们为了对话,将它们命名为#temptable1,#temptable2,#temptable3。 我不能在这里复制/粘贴整个过程,但总体思路是这样的,原始过程(procedure1)在过程的最开始创建#temptable1
create table #temptable1
然后使用select / into语句
创建剩下的两个select T.Col
, T.Col2
, T.Col3
into #temptable2
from table1 T
where T.BB>0
select T.Col
, T.Col2
, T.Col3
into #temptable3
from table2 T
where T.BB>0
drop table #temptable1
drop table #temptable2
drop table #temptable3
在此之前它工作正常,但我想要做的是通过添加if / else语句来改变过程。因此看起来像那样,
declare @BBB nvarchar(32)
create table #temptable1
if @BBB='dd'
begin
select T.Col
, T.Col2
, T.Col3
into #temptable2
from table1 T
where T.BB>0 and T.G='FDL'
select T.Col
, T.Col2
, T.Col3
into #temptable3
from table2 T
where T.BB>0 and T.G='FDL'
drop table #temptable1
drop table #temptable2
drop table #temptable3
end
if @BBB='kk'
begin
select T.Col
, T.Col2
, T.Col3
into #temptable2
from table1 T
where T.BB>0 and T.G='FD'
select T.Col
, T.Col2
, T.Col3
into #temptable3
from table2 T
where T.BB>0 and T.G='FD'
drop table #temptable1
drop table #temptable2
drop table #temptable3
end
else
begin
select T.Col
, T.Col2
, T.Col3
into #temptable2
from table1 T
where T.BB>0
select T.Col
, T.Col2
, T.Col3
into #temptable3
from table2 T
where T.BB>0
drop table #temptable1
drop table #temptable2
drop table #temptable3
end
当我尝试创建新程序时,我收到此消息,
Msg 2714, Level 16, State 1, Procedure pPortfoliostest3, Line 412
There is already an object named '#temptable1' in the database.
Msg 2714, Level 16, State 1, Procedure pPortfoliostest3, Line 550
There is already an object named '#temptable2' in the database.
Msg 2714, Level 16, State 1, Procedure pPortfoliostest3, Line 711
There is already an object named '#temptable3' in the database.
这些行指示临时表在第二个if语句中的位置(如果@ BBB ='kk')。 我尝试了不同的组合但无济于事。有小费吗?谢谢你的时间。
答案 0 :(得分:6)
T-SQL解析器非常原始。特别是, control 流不会影响对象名称何时进入范围并保持在范围内。
因此,您在if
分支中使用的名称仍在范围内,并在解析else
分支时导致冲突。
如果可能,在任何控制流之前将表定义移动到存储过程的顶部,然后切换到INSERT ... SELECT ...
而不是SELECT ... INTO ...
;或者如果表格定义在if
和else
分支之间不匹配,则您需要为临时表使用不同的名称。
作为解析器原始性的另一个例子,请考虑以下内容:
if 1=0
begin
declare @a int
end
select @a
这会产生一个包含null
的结果集,而不是(正如您可能预期的那样)一个错误,表示@a
未被声明。