2010-11-23 13 views
22

をsp_executesqlをするテーブル変数を渡す:私はエラーを取得する私はsp_executesqlをプロシージャにテーブル変数を渡すようにしようとしている

DECLARE @params NVARCHAR(MAX) 
SET @params = '@workingData TABLE (col1 VARCHAR(20), 
       col2 VARCHAR(50))' 

EXEC sp_executesql @sql, @params, @workingData 

Msg 156, Level 15, State 1, Line 1 
Incorrect syntax near the keyword 'TABLE'. 

私は 'の後に列指定を省略してみました表'。また、動的SQL内で変数として表を宣言しようとしました。しかし、運がない...

この手順では、TABLE変数はパラメータとして渡すことはできません。ところで、私はMSSQL2008 R2を実行しています。

は、私は別のプロシージャから作業データをロードするため#workingDataのような局所的な一時テーブルを使用することに興味がない:私は一時varaibleに直接行うことはできません

INSERT INTO @workingData 
    EXEC myProc @param1, @param2 

(?右)。.. 。

+0

@workingdata変数の内容は何ですか? – NotMe

+0

すべての変数の内容は何ですか?私はこれがあなたが何を期待しているのかは考えていません。 – Donnie

+0

@workingData TABLEを使用して、いくつかのプロシージャで使用される一般的な結果セットを返す別のプロシージャの結果を格納します。これは冗長なコードを減らすことです:INSERT INTO @workingData EXEC someProc – Alex

答えて

3

OK、これは私が欲しいものを私を得る、しかし確実にきれいではないだろう。

DECLARE @workingData TABLE (col1 VARCHAR(20), 
     col2 VARCHAR(20)) 

    INSERT INTO @workingData 
     EXEC myProc 

    /* Unfortunately table variables are outside scope 
     for the dynamic SQL later run. We copy the 
     table to a temp table. 
     The table variable is needed to extract data directly 
     from the strored procedure call above... 
    */ 
    SELECT * 
    INTO #workingData 
    FROM @workingData 


     DECLARE @sql NVARCHAR(MAX) 
    SET @sql = 'SELECT * FROM #workingData' 

    EXEC sp_executesql @sql 

はsp_executesqlをに、この一時的な結果セットを渡すためのより良い方法があるに違いありません!

よろしく アレックス

+0

テーブル間でデータをコピーします。あなたは代わりにtempテーブルに直接挿入することができます(これはずっと前に知っていると確信していますが、SOのために、この答えは貧弱です)。 – bambams

11

あなたはまず例えば、テーブルタイプを定義する必要がありますストアドプロシージャにテーブル変数を渡すために、SQL Server 2008を使用している場合:

CREATE TYPE SalesHistoryTableType AS TABLE 
(      
    [Product] [varchar](10) NULL,     
    [SaleDate] [datetime] NULL,     
    [SalePrice] [money] NULL 
) 
GO 

または既存のテーブルを使用しますデータベースに格納されています。

表される入力変数を宣言し、ストアドプロシージャで使用する既存のテーブルタイプ

SELECT * FROM sys.table_types 

を見つけるために、このクエリを使用:

CREATE PROCEDURE usp_myproc 
(
    @TableVariable SalesHistoryTableType READONLY 
) 
AS BEGIN 
    --Do stuff  

END 
GO 

に渡す前に、テーブル変数を移入ストアドプロシージャ:

DECLARE @DataTable AS SalesHistoryTableType 
INSERT INTO @DataTable 
SELECT * FROM (Some data) 

ストアドプロシージャを呼び出します。

EXECUTE usp_myproc 
@TableVariable = @DataTable 

さらなる議論here

+1

+1彼は呼び出し元のスコープに表示されるテーブル変数を変更しようとしていないと考えていますが、 –

+0

私はso_executeSqlに渡された動的SQLで動作するためにこれを必要とします。私は上記の@paramsの仕様でパラメータをテーブル型として宣言しようとしました。私はストアドプロシージャを直接呼び出すわけではありません。 。 。 – Alex

+0

あなたが与えたリンクはもう働きません。利用可能な別のリソースがありますか? – takrl

2

これはあなたの質問に直接答えることはできませんが、問題全体を解決するはずです。

あなたは確かに、一時テーブルにストアドプロシージャの実行結果を取得することができます

INSERT INTO #workingData 
EXEC myProc 

だから、次のように見えるようにコードを変更します。

CREATE TABLE #workingData (col1 VARCHAR(20),  
    col2 VARCHAR(20))  

INSERT INTO #workingData  
    EXEC myProc  

DECLARE @sql NVARCHAR(MAX)  
SET @sql = 'SELECT * FROM #workingData'  

EXEC sp_executesql @sql  

よろしく、 ティム

+0

覚えておくべきことは、テーブル定義内のデータ型とSPから返される結果セットが一致しなければならないことです。 –

+0

私はこの答えの後半になるかもしれないことに気付いた。 :) ごめんなさい! –

+0

これは、テーブル変数ではなく、一時テーブルです。 – gotqn

0
Alter PROCEDURE sp_table_getcount 
@tblname nvarchar(50) , 
@totalrow int output 
AS 
BEGIN 

Declare @params nvarchar(1000) 
Declare @sql nvarchar(1000) 
set @sql = N'Select @cnt= count(*) From @tbl' 
set @params = N'@tbl nvarchar(50) , @cnt int OUTPUT' 
Exec sp_executesql @sql , @params ,@[email protected] , @cnt = @totalrow OUTPUT 
END 
GO 

上記のコードはテーブルはオブジェクトとしてスコープ外です。それはあなたにエラーを与える:テーブル変数を宣言する必要があります。回避するために、我々は以下を行うことができます。

Alter PROCEDURE sp_table_getcount 
@tblname nvarchar(50) , 
@totalrow int output 
AS 
BEGIN 

Declare @params nvarchar(1000) 
Declare @sql nvarchar(1000) 
set @sql = N'Select @cnt= count(*) From dbo.' + @tblname 
set @params = N'@cnt int OUTPUT' 
Exec sp_executesql @sql , @params , @cnt = @totalrow OUTPUT 
END 
GO 
関連する問題