为什么不在存储过程中创建表?

时间:2012-04-28 03:53:29

标签: sql sql-server sql-server-2008 stored-procedures

我正在创建存储过程,我需要动态构建一个临时表。我尝试了以下代码,但它没有创建表。当我在Query窗口中执行生成的Query时,它在那里工作正常。

--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)

2 个答案:

答案 0 :(得分:3)

您的问题是您的临时表仅存在于其创建的范围内...这属于您的第一个sp_executesql范围内。当您调用select语句时,临时表不再在范围内。

要解决此问题,您必须构建一个字符串,其中包含您对临时表所需的所有内容:createinsertselect一次sp_executesql电话。

但是,您应该知道,如果您无法完全控制用于构建命令的所有值,那么您当前的方法可能容易受到SQL注入的攻击。<​​/ p>

答案 1 :(得分:3)

CREATE SELECT 语句中使用的

对象 #final 不在同一范围内。

这是构建查询的一种方法。

  • 尝试使用分号终止SQL语句。即使它不是强制性的,它也可以帮助您区分语句的可读性。请注意,我在 CREATE INSERT SELECT 语句的末尾添加了分号。

  • 您可以注意到 CREATE INSERT SELECT 在同一个事务中执行。因此,您不会失去临时表的范围。

脚本

    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