Al reunir un proceso rápido para ayudar con la depuración, me encontré con lo que parece ser un error en el 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;
Intentar lo anterior devuelve el siguiente error
Mensaje 2714, Nivel 16, Estado 1, Procedimiento spFoo, Línea 19
Ya existe un objeto llamado '#bar' en la base de datos.
En un sentido legible para los humanos, el proceso parece estar bien: solo select into
se ejecutará una sola declaración, ya que están dentro de los if-else
bloques. Sin embargo, muy bien, el servidor SQL no puede confirmar que las declaraciones estén lógicamente excluidas entre sí. Quizás más confuso es que el error permanece cuando drop table #foo
se coloca dentro del bloque if-else (que se supone que le indicaría al compilador que desasigne el nombre del objeto) como se muestra a continuación.
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;
El proceso en sí está bien. Lo absorbí y escribí las declaraciones create table #foo( ... )
y insert #foo ( ... )
, había estado tratando de saltarme la select * into
sintaxis. En este punto, solo estoy tratando de entender por qué el compilador me criticó con la sintaxis del tipo vago. Lo único que puedo pensar es que el comando DDL reserva el nombre del objeto EN TEMPDB .
¿Por qué el texto en negrita?
create proc spIck
as
begin
create table #ack ( col1 int );
drop table #ack;
create table #ack ( colA char( 1 ) );
drop table #ack;
end;
Esto falla con el mismo código de error que el anterior. Pero lo siguiente ...
create proc spIck
as
begin
create table ack ( col1 int );
drop table ack;
create table ack ( colA char( 1 ) );
drop table ack;
end;
... tiene éxito. Lo mismo sigue arriba al intento de proceso original. Entonces...
Mi pregunta es esta
¿Cuál es la diferencia (y por qué está presente) en la reserva de nombre de objeto para TempDB
objetos en lugar de bases de datos de usuario? Ninguna de las referencias de Procesamiento de consultas lógicas ni las referencias de comandos DDL que he revisado parecen explicar esto.