web-dev-qa-db-ja.com

sp_ExecuteSqlが新しいセッションを作成する場合、動的SQLの外部で(実行前に)作成されたローカル一時テーブルにアクセスできるのはなぜですか?

ローカル一時テーブルが現在のセッションでのみ利用可能で、sp_ExecuteSqlが新しいセッションを作成して、それに渡された動的SQL文字列を実行する場合、その動的SQLクエリは、sp_ExecuteSqlを実行するセッションで作成された一時テーブルにどのようにアクセスできますか。

言い換えると、なぜこれが機能するのですか?

SELECT 1 AS TestColumn
INTO #TestTempTable

DECLARE @DS NVARCHAR(MAX) = 'SELECT * FROM #TestTempTable'
EXEC sp_EXECUTESQL @DS

結果:

Temp Table Results from Dynamic SQL Select

反対のことができない理由(動的SQLで一時テーブルを作成してから、実行中のセッションで動的SQLクエリの外部にアクセスする)に対する私の理解は、sp_ExecuteSqlが新しいセッションで実行されるためです。

3
J.D.

回答 から Remus Rusan による:

動的SQLは、呼び出しコードと同じセッションで実行されます。問題はセッションではなく範囲です。動的SQLは、sp_executesql呼び出し内に一時テーブルを作成します。したがって、MSDNに記載されているように、作成された#tempテーブルはそのsp_executesql呼び出し内でのみ表示されます。

次のコマンドを実行すると、sp_executesql呼び出しで同じセッションを使用していることを確認できます。

DECLARE @DS NVARCHAR(MAX) = 'SELECT @@SPID'
EXEC sp_EXECUTESQL @DS

sp_executesqlは別のスコープではなく別のスコープで実行されていることを認識し、 一時テーブルのドキュメント にある情報を追加します。

一時テーブルは、DROP TABLEを使用して明示的に削除しない限り、範囲外になると自動的に削除されます。

そして、一時テーブルの可視性に関する同じソース:

ローカル一時テーブルは現在のセッションでのみ表示されます

スコープとセッションのこれらの違いは、sp_executesql呼び出しから一時テーブルにアクセスできるが、その逆はできない理由を説明しています。

8
Randi Vertongen