Reunindo um processo rápido para ajudar na depuração, encontrei um que parece ser um erro no compilador.
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;
Tentativa acima, retorna o seguinte erro
Msg 2714, Nível 16, Estado 1, Procedimento spFoo, Linha 19
Já existe um objeto chamado '#bar' no banco de dados.
Em um sentido legível por humanos, o proc parece estar bem: apenas uma select into
declaração será executada, uma vez que estão dentro dos if-else
blocos. Muito bem, o SQL Server não pode confirmar se as instruções são logicamente excluídas uma da outra. Talvez o mais confuso seja o fato de que o erro permanece quando drop table #foo
é colocado dentro do bloco if-else (que se supõe que seria dito ao compilador para desalocar o nome do objeto) como abaixo.
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;
O proc em si está bem. Eu peguei e escrevi as declarações create table #foo( ... )
e insert #foo ( ... )
, eu estava tentando pular com a select * into
sintaxe. Neste ponto, estou apenas tentando entender por que o compilador me cagou com a sintaxe do cara preguiçoso. A única coisa em que consigo pensar é que o comando DDL reserva o nome do objeto IN TEMPDB .
Por que o texto em negrito?
create proc spIck
as
begin
create table #ack ( col1 int );
drop table #ack;
create table #ack ( colA char( 1 ) );
drop table #ack;
end;
Isso falha com o mesmo código de erro acima. Mas o seguinte ...
create proc spIck
as
begin
create table ack ( col1 int );
drop table ack;
create table ack ( colA char( 1 ) );
drop table ack;
end;
... consegue. O mesmo segue acima para a tentativa proc original. Assim...
Minha pergunta é esta
Qual é a diferença (e por que está presente) na reserva de nome de objeto para TempDB
objetos em oposição aos bancos de dados do usuário. Nenhuma das referências do Logical Query Processing nem das referências de comando DDL que revi parecem explicar isso.