33

テーブルからいくつかの値を挿入するクエリがあります。

SELECT ID, NAME INTO #tmpTable1
FROM TableOriginal

最初の実行は問題ありません。MSSMS(Microsoft Sql Server Management Studio)でF5(実行)を押すと、エラーが発生しました。

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

良い。データを挿入する前に、以下TableOriginal#tmpTable1使用して確認することにしました。

IF OBJECT_ID('tempdb.#tmpTable1') IS NOT NULL  
  DROP TABLE #tmpTable1

動作しない場合、エラーは上記のように再び表示されます。

私はtempdbデータベースで次の一時テーブル名を見ました:

dbo.#tmpTable1__________________0000007

なんで?(最初のクエリを使用して)一時テーブルを作成するたびに、テーブル名はMSSMSで自動的に生成されますか?

既存の一時テーブルを削除して、新しい値で新しいテーブルを作成するにはどうすればよいですか?

4

5 に答える 5

61

あなたは非常に近いです-あなたはあなたのチェックで2つのドットを使う必要があります:

IF OBJECT_ID('tempdb..#tmpTable1') IS NOT NULL  
                    ** 
                    |
                  use two dots here!

基本的に、これは次のように言っています。チェックインするtempDBと、テーブルがどのスキーマにあるかは気になりません。

ジョーが正しく言ったように:これは100%正しいわけではありません:すべてのスキーマをチェックインするわけではありません-デフォルトの所有者のスキーマのみをチェックインします-通常はdbo。したがって、これも機能します。

IF OBJECT_ID('tempdb.dbo.#tmpTable1') IS NOT NULL  

デフォルトの所有者以外のスキーマでオブジェクトを作成する場合は、参照しているスキーマを明示的に指定する必要があります。しかし、の一時テーブルtempDBは実際にdboスキーマで作成されています。

于 2012-08-16T11:57:58.853 に答える
12

これは質問への答えではありません。#tempテーブルを参照するときの配置と比較についてのビットへの応答を一時的に投稿したかっただけ.dbo.です..

#tempテーブルを実際にdbo以外のものが所有するようにする方法が見つかりませんでした。それを試してみてください:

CREATE SCHEMA blat;
GO

CREATE TABLE blat.#pound(id INT);
GO

SELECT 
   OBJECT_ID('tempdb..#pound'), 
   OBJECT_ID('tempdb.dbo.#pound'), 
   OBJECT_ID('tempdb.blat.#pound');

USE tempdb;
GO

SELECT [object_id], SCHEMA_NAME([schema_id]) 
  FROM sys.objects 
  WHERE name LIKE '#pound%';

結果:

-1222354987    -1222354987    -1222354987

-1222354987    dbo

これはSQLServer2012で行われました。これをSQLServer2005でテストしましたが、唯一の違いはobject_id値が正であったことです。私も試しました:

  • tempdbに実際に存在するスキーマと呼ばれるblat
  • blat.#poundデフォルトスキーマがであるユーザーによって作成されたテーブルblat
  • 上記の両方

3つのケースすべてで、上記と同じ結果が得られました。

また、異なるスキーマで同じ名前の2つの#tempテーブルを作成することはできません。

CREATE TABLE blat.#flab(id INT);
CREATE TABLE dbo.#flab(id INT);

結果:

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

これは解析の問題ではありません(多くの#tempテーブルの問題がそうであるように)。これらの2つのステートメントを別々に実行して、同じエラーを受け取ることができます。

したがって、これは長い言い方です。#tempテーブル名を解決するときにスキーマを指定する必要はありません。スキーマは常に下に作成されdbo、少なくとも下の解決でOBJECT_IDは、指定したスキーマが無視されます(OBJECT_SCHEMA_NAMEこれも常に#tempdbのコンテキストで実行すると戻りますdboが、他のデータベースでは返されません)。schema_idでクエリを実行しようとすると、すべての賭けが無効になりますtempdb.sys.objects

于 2012-08-16T12:43:30.857 に答える
2
CREATE TABLE #temptable (col1 int);
GO
INSERT INTO #temptable
VALUES (10);
GO
SELECT * FROM #temptable;
GO
IF OBJECT_ID(N'tempdb..#temptable', N'U') IS NOT NULL 
DROP TABLE #temptable;
GO
--Test the drop.
SELECT * FROM #temptable;
于 2015-05-11T09:23:57.243 に答える
-1

そのように定義された一時テーブルは、それを作成した接続が開いている限り存在します。通常、接続内を完全に制御できるため、存在するかどうかを確認したり、手動で削除したりする必要はありませんが、本当に確認する必要がある場合は、tempdb.dbo。#tempTableを確認できます。

于 2012-08-16T12:03:59.050 に答える
-1

OBJECT_ID('tempdb.dbo。#tmpTable1%')がNULLでない場合:)

于 2015-02-02T20:58:22.930 に答える