汇集了一个快速处理程序以帮助调试,我遇到了编译器中似乎是错误的错误。
create proc spFoo
@param bit
as
begin
if @param = 0
begin
select *
into #bar
from [master].dbo.spt_values
-- where number between ...
end
else
begin
select top 10 *
into #bar
from [master].dbo.spt_values
order by newid();
end;
end;
尝试执行上述操作会返回以下错误
消息2714,级别16,状态1,过程spFoo,第19
行在数据库中已经有一个名为“ #bar”的对象。
在人类可读的意义上,该proc似乎很好:select into
因为它们被包装在if-else
块中,所以仅将执行一条语句。但是,非常好,SQL Server无法确认这些语句在逻辑上相互排斥。也许更令人困惑的是,将drop table #foo
if放置在if-else块内时(如果假定它将告诉编译器取消分配对象名),错误仍然存在,如下所示。
create proc spFoo
@param bit
as
begin
select top 1 *
into #bar
from [master].dbo.spt_values
if @param = 0
begin
drop table #bar;
select *
into #bar
from [master].dbo.spt_values
-- where number between ...
end
else
begin
drop table #bar;
select top 10 *
into #bar
from [master].dbo.spt_values
order by newid();
end;
end;
proc本身很好。我把它吸了起来并写了create table #foo( ... )
and insert #foo ( ... )
语句,我一直试图跳过select * into
语法。在这一点上,我只是想了解为什么编译器使用lazy-guy语法对我不利。我唯一想到的是DDL命令保留了对象名称IN TEMPDB。
为什么要加粗文字?
create proc spIck
as
begin
create table #ack ( col1 int );
drop table #ack;
create table #ack ( colA char( 1 ) );
drop table #ack;
end;
这将失败,并显示与上面相同的错误代码。但是以下...
create proc spIck
as
begin
create table ack ( col1 int );
drop table ack;
create table ack ( colA char( 1 ) );
drop table ack;
end;
...成功。原始proc尝试与上面相同。所以...
我的问题是这个
TempDB
与用户数据库相比,对象的对象名称保留有什么区别(以及为什么存在)。我已经阅读过的“逻辑查询处理”参考和DDL命令参考都没有一个可以解释这一点。