2

重複の可能性:
動的SQLから一時テーブルへのTSQLの書き込み

 ALTER PROCEDURE [dbo].[usp_ServicesStats1](@PERIOD VARCHAR(30) )

 AS
 BEGIN
-- SET NOCOUNT ON added to prevent extra result SETs FROM
-- interfering with SELECT statements.
SET NOCOUNT ON;


 DELETE FROM servicesstats1;
 DECLARE @QUERY  NVARCHAR(MAX);

 DECLARE @mainTable VARCHAR(50)

 SET @mainTable = '[ServicesStats' + @PERIOD + ']';



 SET @QUERY = 'INSERT INTO servicesstats1(Department,StudentUsers) 
 SELECT department,COUNT(*) FROM ' +  @mainTable + 
 'GROUP BY department';

 EXEC(@QUERY); -- runs okay!


 IF OBJECT_ID('tempdb..[##tmp5]') is not null 
BEGIN 
    drop table [##tmp5] 
END

 SET @QUERY = ' SELECT studentid
 INTO [##tmp5]
 FROM ' + @mainTable + '
 GROUP BY studentid
 having COUNT(*)=1; select * from [##tmp5];';
 PRINT @QUERY;


 EXEC sp_executesql @QUERY;

 IF OBJECT_ID('tempdb..[#tmp3]') is not null 
BEGIN 
    drop table [#tmp3] 
END

 SELECT S.department,COUNT(*) AS No INTO #TMP3 --  ONLY THIS SERVICE 
 FROM servicesstats_0511_0412 s, #TMP5 T    -- this is not being replaced yet by the @mainTable
 WHERE S.STUDENTID = T.STUDENTID
 GROUP BY S.department

エラー :

オブジェクト名'#TMP5'が無効です。

問題は一時的なテーブル#tmp5です。これを実行すると機能しますが、動的ではありません。

SELECT studentid
INTO [#tmp5]
FROM tableName
GROUP BY studentid
having COUNT(*)=1;

基本的に、動的テーブル名のためにこれを行っています。しかし#tmp、そのエラーをスローしています。

4

1 に答える 1

2

動的SQLのスコープ内にのみ存在するローカル一時テーブルを使用しているため、エラーなしで次のように参照できます。

SET @QUERY = ' SELECT studentid
INTO [#tmp5]
FROM ' + @mainTable + '
GROUP BY studentid
having COUNT(*)=1; 
SELECT * 
FROM [#tmp]';

EXEC sp_executesql @QUERY;

ただし、動的SQLの範囲外でアクセスしようとすると、SSMSの別のウィンドウからアクセスできるようになります。グローバル一時テーブルを使用する必要があります。そうすれば、それにアクセスできます。

SET @QUERY = ' SELECT studentid
INTO [##tmp5]
FROM ' + @mainTable + '
GROUP BY studentid
having COUNT(*)=1;';

EXEC sp_executesql @QUERY;

SELECT  *
FROM    [##Tmp5];

マルチユーザー環境で発生する可能性のある問題に注意してください。

于 2012-10-29T17:32:05.037 に答える