18

SQLServer2008にテーブル変数があります

    DECLARE @specsAndModel TABLE
    (
        specName VARCHAR(50)
        ,specVal VARCHAR(50)
    )
    INSERT INTO @specsAndModel
    VALUES('[modelNumber]', 'F00-B4R')

次に、次の例のように、後で、と呼ばれる文字列を作成します@query。これを最終的にに渡そうとします。EXECUTE

    DECLARE @query NVARCHAR(MAX);
    SET @query = 'SELECT specName, specVal FROM @specsAndModel'
    EXECUTE(@query)

ただし、SQLServerから次のエラーメッセージが表示されます。Must declare the table variable "@specsAndModel".

調べてみると、これは実行コンテキストに関係しているのではないかと思いますが、問題を解決できていません。

execute関数の呼び出しでテーブル変数を使用することさえ可能ですか?

4

2 に答える 2

22

作成しているテーブルは、最初のスコープ外では使用できないテーブル変数です。これを修正するには、いくつかの方法があります。

グローバル一時テーブルを作成します(免責事項: 複数のユーザーが同時にこれを実行しようとすると、問題が発生する可能性があります)

create table  ##specsAndModel 
(
    specName VARCHAR(50)
    ,specVal VARCHAR(50)
)
INSERT INTO ##specsAndModel
VALUES('[modelNumber]', 'F00-B4R')

DECLARE @query NVARCHAR(MAX);
SET @query = 'SELECT specName, specVal FROM ##specsAndModel'
EXECUTE(@query)

グローバルではなくローカル一時テーブルを作成します。

create table  #specsAndModel 
(
    specName VARCHAR(50)
    ,specVal VARCHAR(50)
)
INSERT INTO #specsAndModel
VALUES('[modelNumber]', 'F00-B4R')

DECLARE @query NVARCHAR(MAX);
SET @query = 'SELECT specName, specVal FROM #specsAndModel'
EXECUTE(@query)

動的 SQL 内で create table を実行します (醜い):

DECLARE @query NVARCHAR(MAX);
SET @query = 'DECLARE @specsAndModel TABLE
(
    specName VARCHAR(50)
    ,specVal VARCHAR(50)
)
INSERT INTO @specsAndModel
VALUES(''[modelNumber]'', ''F00-B4R'')
SELECT specName, specVal FROM @specsAndModel'
exec(@query)

一時テーブルを使用する代わりに、実際のテーブルを作成し、完了したらドロップします (免責事項: 複数のユーザーが同時にこれを実行しようとすると、問題が発生する可能性があります)

create TABLE specsAndModel 
(
    specName VARCHAR(50)
    ,specVal VARCHAR(50)
)
INSERT INTO specsAndModel
VALUES('[modelNumber]', 'F00-B4R')

DECLARE @query NVARCHAR(MAX);
SET @query = 'SELECT specName, specVal FROM specsAndModel'
EXECUTE(@query)  

drop table specsAndModel

一時テーブルとテーブル変数に関するディスカッションへのリンクを次に示します。

#temp テーブルまたは @table 変数を使用する必要がありますか?

編集:次を使用してテーブル変数を渡すことができますsp_executesql

create type specsAndModel as table (
    specName VARCHAR(50)
    ,specVal VARCHAR(50)
 )
go
declare @t specsAndModel
insert @t VALUES('[modelNumber]', 'F00-B4R')

exec sp_executesql N'select specName, specVal from @var', N'@var specsAndModel readonly', @t

グローバル ##temp テーブルと永続テーブルのいずれかを使用すると、複数のユーザーがプロセスを実行しようとすると競合が発生する可能性があるというリスクが発生します。

ローカルの #temp テーブルを使用するか、 を使用してテーブル変数を渡す方が安全ですsp_executesql

于 2012-08-21T16:48:49.117 に答える
2

また、文字列内にテーブル変数を作成する必要があります。

DECLARE @query NVARCHAR(MAX);
SET @query = 'DECLARE @specsAndModel TABLE  ( specName VARCHAR(50) ,specVal VARCHAR(50))'
SET @Query = @Query + ' INSERT INTO  @specsAndModel VALUES(''modelNumber'',''abcd''); SELECT specName, specVal FROM @specsAndModel'
EXEC (@query)
于 2012-08-21T16:49:46.747 に答える