Menyatukan quickie proc untuk membantu debugging, saya menemukan apa yang tampaknya merupakan kesalahan dalam kompiler.
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;
Mencoba di atas mengembalikan kesalahan berikut
Msg 2714, Level 16, Negara 1, Prosedur spFoo, Baris 19
Sudah ada objek bernama '#bar' dalam database.
Dalam arti yang dapat dibaca manusia, proc tampaknya baik-baik saja: hanya satu select into
pernyataan yang akan dieksekusi karena mereka dibungkus di dalam if-else
blok. Sangat baik, SQL server tidak dapat mengkonfirmasi bahwa pernyataan secara logis dikecualikan dari satu sama lain. Mungkin yang lebih membingungkan adalah bahwa kesalahan tetap ketika drop table #foo
ditempatkan di dalam blok if-else (yang diasumsikan akan memberitahu kompiler untuk membatalkan alokasi nama objek) seperti di bawah ini.
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 itu sendiri baik-baik saja. Saya mengisapnya dan menulis create table #foo( ... )
dan insert #foo ( ... )
pernyataan, saya sudah mencoba untuk melewatkan dengan select * into
sintaks. Pada titik ini, saya hanya mencoba untuk memahami mengapa kompiler mencampuri saya dengan sintaks malas-guy. Satu-satunya hal yang dapat saya pikirkan adalah bahwa perintah DDL menyimpan nama objek DI TEMPDB .
Mengapa teksnya tebal?
create proc spIck
as
begin
create table #ack ( col1 int );
drop table #ack;
create table #ack ( colA char( 1 ) );
drop table #ack;
end;
Ini gagal dengan kode kesalahan yang sama seperti di atas. Namun berikut ini ...
create proc spIck
as
begin
create table ack ( col1 int );
drop table ack;
create table ack ( colA char( 1 ) );
drop table ack;
end;
... berhasil. Hal yang sama mengikuti di atas untuk upaya proc asli. Begitu...
Pertanyaan saya adalah ini
Apa perbedaannya (dan mengapa itu ada) dalam reservasi nama objek untuk TempDB
objek yang bertentangan dengan database pengguna. Tidak satu pun dari referensi Pemrosesan Permintaan Logika atau referensi perintah DDL yang telah saya ulas tampaknya menjelaskan hal ini.