デバッグに役立つQuickieプロシージャをまとめると、コンパイラでエラーのように見えるものに遭遇しました。
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」という名前のオブジェクトがあります。
人間が読める意味では、プロシージャは問題ないように見えます。ブロックselect into
内にラップされているため、実行されるステートメントは1つだけですif-else
。ただし、SQLサーバーは、ステートメントが互いに論理的に除外されていることを確認できません。おそらくもっと混乱するのdrop table #foo
は、以下のようにが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;
プロシージャ自体は問題ありません。私はそれを吸い上げてcreate table #foo( ... )
and insert #foo ( ... )
ステートメントを書きました、私はselect * into
構文でスキップしようとしていました。この時点で、私はコンパイラがレイジーガイ構文でなぜ私に打ちのめされたのかを理解しようとしているだけです。私が考えることができる唯一のことは、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コマンドのリファレンスも、これを説明しているようには見えません。