3

一連のテーブルから情報を抽出する必要がある SQL Server 2008 のストアド プロシージャを作成しています。これらのテーブルの構造を事前に知りません。同じデータベースに別のテーブルがあり、このテーブルのフィールドの名前とタイプを教えてくれます。

私はこれをやっています:

declare @sql nvarchar(max)

set @sql = 'select ... into #new_temporary_table ...'
exec sp_executesql @sql

Then I iterate doing:

set @sql = 'insert into #another_temporary_table ... select ... from #new_temporary_table'
exec sp_executesql @sql

その後、一時テーブルを削除します。これはループで発生するため、テーブルの作成、移入、および削除が何度も行われ、毎回異なる列が使用されます。

これはエラーで失敗します:

無効なオブジェクト名: #new_temporary_table。

いくつかのグーグルの後、私はそれを見つけました:

  1. テーブルは、ストアド プロシージャのスコープとは異なる#new_temporary_table呼び出しのスコープで作成されています。exec sp_executesqlこれが、nextexec sp_executesqlがテーブルを見つけられない理由です。この投稿ではそれについて説明しています: http://social.msdn.microsoft.com/forums/en-US/transactsql/thread/1dd6a408-4ac5-4193-9284-4fee8880d18a

  2. 先頭に .が付加されたグローバル一時テーブルを使用できます##。複数のストアド プロシージャが同時に実行される可能性があり、それらが互いの状態に影響を与える可能性があるため、これを行うことはできません。

  3. この記事では、この状況に陥った場合、データベースの構造を変更する必要があると述べています。これは私にとってオプションではありません: http://www.sommarskog.se/dynamic_sql.html

私が見つけた 1 つの回避策はselect into #new_temporary_table..、すべてのinsert into ...スクリプトを 1 つの巨大なステートメントに結合することでした。これはうまく機能しますが、いくつかの欠点があります。

たとえば、トラブルシューティングのために @sql を出力すると、テキストが切り捨てられます。

他に選択肢はありますか?すべてのアイデアを歓迎します。

4

3 に答える 3

3

グローバル一時テーブルを使用できますが、コンテキスト ID ( newid() など) をグローバル一時テーブル名の一部として使用します。

declare @sql varchar(2000)
declare @contextid varchar(50) = convert(varchar(20), convert(bigint, substring(convert(binary(16), newid()), 1, 4)))
set @sql = 'select getdate() as stuff into ##new_temporary_table_' + @contextid
exec (@sql)
于 2012-05-18T15:45:39.300 に答える
1

単一のスクリプトを使用するのが最善だと思います。

[ツール] > [オプション] > [クエリ結果] > [SQL Server] > [結果をテキストに変換] で印刷する文字数を変更できます - [最大文字数...] を 256 から最大 (8192) に変更します。

8192より大きい場合は印刷が困難です。ただし、この場合は別のオプションを試すことができます。代わりにPRINT @sql;以下を使用します (Results to Grid を使用):

SELECT sql FROM (SELECT @sql) AS x(sql) FOR XML PATH;

結果をクリックすると、新しいクエリ ウィンドウが開きます。これは XML ファイル ウィンドウであり、実行することも色分けすることもできず、変更を無視する必要があります (たとえば、XML データとして有効にするためなど) >>目玉をつけようとしているだけです。必要に応じて、それをコピーして実際のクエリ エディター ウィンドウに貼り付け、エンティティ化された文字を検索して置換することができます。FWIW 私は彼らにそのような XML ウィンドウを実際のクエリ ウィンドウにするように依頼しましたが、これは拒否されました。

http://connect.microsoft.com/SQLServer/feedback/details/425990/ssms-allow-same-semantics-for-xml-docs-as-query-windows

于 2012-05-18T17:30:58.910 に答える
1

#temp テーブル (グローバルではない) は、それらが作成されたスコープ以下で使用できます。だから、あなたは次のようなことができます...

while (your_condition = 1) begin
    set @sql = 'select ... into #temp1 ...from blah
        exec sp_do_the_inserts'
    exec(@sql)
end

sp_do_the_inserts は次のようになります...

select * into #temp2 from #temp1
....your special logic here....

もちろん、これはあらかじめ sp_do_the_inserts を作成していることを前提としています。それがあなたのニーズに役立つかどうかはわかりません。

于 2012-05-18T15:41:46.083 に答える