#SomeTableを複数回作成および削除することは「合法」ですか?


8

私のコードは「コヒーレントブロック」として分離されており、長い「構成スクリプト」に何度も挿入できます。使用しているパターンの1つは次のとおりです。

CREATE TABLE #WidgetSetting 
(
    WidgetID bigint not null,
    Name nvarchar(100) not null,
    Value nvarchar(max) not null,
    CreateDate datetime not null
)

INSERT VALUES

MERGE TABLES

DROP TABLE #WidgetSetting

しかし、現在SSMSは、オブジェクトがすでにCREATE TABLE火災が発生するまでにすでに存在していると不平を言っています。何ができますか?

スクリプトの最初に一度テーブルを宣言し、ドロップではなく切り捨てる必要があるのは明らかだと思いますが、当然のことながら、テーブルをドロップして同じ名前を再び使用するのは簡単ではありません。


Aaronが以下でコメントしたように、これがあなたが取ったルートである場合、最も簡単な修正は、スクリプトの最後に#TABLEをドロップし、その間の手順で単にそれを切り捨てることです。これは、そもそもスクリプトを再設計して動作を変えることが不可能であると想定しているためです。:)
カーン

1
それは実際にそれを解決するために私がやったことです。私はその行動に戸惑いました。彼はなぜそれを修正する方法よりも私がもっと欲しかった理由を説明しました。
jcolebrand

回答:


11

いいえ、パーサーでは同じ#tempテーブルを同じバッチで2回作成できません(これはSSMSとは関係ありません)。#tempテーブルのコピーが1つしか作成できなくても問題ありません。たとえば、人間にとって明らかに1つのブランチしか実行できない次の条件付きロジックでは、SQL Serverはそれを認識できません。

IF 1 = 1
BEGIN
  CREATE TABLE #x(i INT);
  DROP TABLE #x;
END
ELSE
BEGIN
  CREATE TABLE #x(j INT);
  DROP TABLE #x;
END

メッセージ2714、レベル16、状態1、行8
データベースにはすでに「#x」という名前のオブジェクトがあります。

そして、コンパイル時にSSMSが文句を言うのではないことを証明するには(一般的な誤解):

DECLARE @sql NVARCHAR(MAX) = N'IF 1 = 1
BEGIN
  CREATE TABLE #x(i INT);
  DROP TABLE #x;
END
ELSE
BEGIN
  CREATE TABLE #x(j INT);
  DROP TABLE #x;
END';

EXEC sp_executesql @sql;

SSMSがを介してサーバーに送信する前に動的SQLを解析または検証しない場合でも、まったく同じエラーが発生しますsp_executesql

もちろん、修正は、ドロップする代わりに同じ#tempテーブルを再利用するか、毎回異なる#tempテーブルを使用するか、最初に#tempテーブルを使用しないことです。

これは、SQL Serverがより適切に処理することを期待するべきものではありません。つまり、決定した回避策に慣れます。

別の説明を提供するスタックオーバーフローに関するこの関連回答も参照してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.