2012-04-28 16 views
0

我正在創建存儲過程,我需要動態地構建一個臨時表。我嘗試了下面的代碼,但沒有創建表。當我在查詢窗口中執行生成的查詢時,它在那裏正常工作。爲什麼不是從存儲過程內創建表?

--declare query variable 
DECLARE @Query nvarchar(MAX) 
SET @Query = 'CREATE TABLE #final (DATE int,' 


--DECLARE @COLUMNNAME VARIABLE 
DECLARE @ColName nvarchar(10) 

OPEN @taCur 

FETCH NEXT FROM @taCur INTO @ColName 
WHILE (@@FETCH_STATUS = 0) 
BEGIN 
    SET @Query = @Query + 'T_' + @ColName +' int,' 
    FETCH NEXT FROM @taCur INTO @ColName 
END 

SET @Query = @Query + 'TOTAL int,CUMM_TOTAL int)' 
print @Query 
EXEC sp_executesql @Query 
--SET @Query = 'INSERT INTO #final (DATE) VALUES (1)' 
SET @Query = 'SELECT * FROM #final' 
print @Query 
EXEC(@Query) 

最終生成創建表的查詢是遵循

CREATE TABLE #final (DATE int,T_211E int,T_211G int,T_211H int,T_211J int,T_211L int,T_221F int,TOTAL int,CUMM_TOTAL int) 

回答

3

對象#final使用CREATESELECT語句不是在同一範圍內。

以下是構建查詢的一種方法。

  • 嘗試用分號終止SQL語句。儘管它不是強制性的,但它會幫助您區分可讀性陳述。請注意,我在的末尾包含分號CREATEINSERTSELECT語句。

  • 你可以注意到CREATEINSERT選擇在同一事務執行。因此,您不會失去臨時表的範圍。

腳本

CREATE TABLE dbo.ColumnSchema 
    (
     ColName NVARCHAR(10) 
    ); 

    INSERT INTO dbo.ColumnSchema (ColName) VALUES 
     ('211E'), 
     ('211G'), 
     ('211H'), 
     ('211J'), 
     ('211L'), 
     ('211F'); 


DECLARE @Query  NVARCHAR(MAX); 
DECLARE @ColName NVARCHAR(10); 

SET @Query = 'CREATE TABLE #final (DATE int,'; 

DECLARE taCursor CURSOR FOR 
    SELECT ColName 
    FROM dbo.ColumnSchema; 

OPEN taCursor 

FETCH NEXT FROM taCursor 
    INTO @ColName 

    WHILE (@@FETCH_STATUS = 0) 
    BEGIN 

     SET @Query = @Query + 'T_' + @ColName + ' int, ' 

     FETCH NEXT FROM taCursor 
      INTO @ColName 
    END 

CLOSE  taCursor; 
DEALLOCATE taCursor; 

SET @Query = @Query + 'TOTAL int,CUMM_TOTAL int); ' 
SET @Query = @Query + 'INSERT INTO #final (DATE) VALUES (1); ' 
SET @Query = @Query + 'SELECT * FROM #final; ' 

EXEC (@Query); 

輸出

DATE T_211E T_211G T_211H T_211J T_211L T_211F TOTAL CUMM_TOTAL 
---- ------ ------ ------ ------ ------ ------ ----- ---------- 
1 NULL NULL NULL NULL NULL NULL NULL NULL 
+0

+1對於代碼示例.. – 2012-04-28 04:10:01

+0

謝謝@Siva ...你的回答很有幫助 – Dharmesh 2012-04-28 04:15:24

3

你的問題是,你的臨時表只知道它創建的範圍內是否存在...這是你的第一個sp_executesql的範圍之內。當你打電話給你的select聲明時,你的臨時表不在範圍之內。

爲了解決這個問題,你就必須建立一個包含你需要用臨時表盡一個字符串:你createinsertselect內的所有單sp_executesql電話。

但是,您應該知道,如果您沒有完全控制用於構建命令的所有值,則您當前的方法可能容易受到SQL注入的攻擊。

+0

我應該怎麼做才能在範圍選擇語句? – Dharmesh 2012-04-28 04:06:38

+0

非常感謝.....你已經清除了我所有的疑惑 – Dharmesh 2012-04-28 04:13:17