将值插入同一存储过程中动态创建的 table

Insert values into dynamically created table in the same stored procedure

我的任务是:创建一个 table 并将 n 个值插入同一存储过程中的 table。

CREATE PROCEDURE PROC
    @tableName nvarchar(30),
    @nRows          int
AS
BEGIN
    IF EXISTS (SELECT * FROM sys.objects 
               WHERE object_id = OBJECT_ID(@tableName) 
                 AND type in (N'U'))
        DROP TABLE [dbo].[@tableName ]

    DECLARE @SQLString NVARCHAR(MAX)

    SET @SQLString = 'CREATE TABLE ' + @tableName +
                     '(
                          [ID] [int] IDENTITY(1,1) NOT NULL,
                          [col1] [int] NOT NULL
                      ); GO';

    EXEC (@SQLString);

    DECLARE @i int = 1;

    WHILE (@i <= @nRows)
    BEGIN
        SET @i = @i + 1;

        INSERT INTO @tableName values (@i);
    END
END

我知道问题是 table 在提交之前不存在;这就是为什么我不能插入。但是如何重写它才能完成我的任务呢?

插入应该是动态的。使用 sp_executesql:

....

EXEC (@SQLString);

DECLARE @params NVARCHAR(MAX) = '@i INT'
SET @SQLString = 'INSERT INTO ' + @tableName + ' VALUES(@i)'

DECLARE @i INT = 1;
WHILE ( @i <= @nRows )
    BEGIN
        SET @i = @i + 1;
        EXEC sp_executesql @SQLString, @params, @i;
    END

没有循环执行的版本:

....

EXEC (@SQLString);

SET @SQLString = 'INSERT INTO ' + @tableName + ' VALUES'

DECLARE @i INT = 1;
WHILE ( @i <= @nRows )
    BEGIN
        SET @SQLString = @SQLString + '(' + CAST(@i AS NVARCHAR(MAX)) + '),'
        SET @i = @i + 1;
    END

EXEC(SUBSTRING(@SQLString, 1, LEN(@SQLString) - 1))

带有 Tally 的版本:

....

EXEC (@SQLString);

SET @SQLString = '
;WITH cte AS(SELECT ROW_NUMBER() OVER(ORDER BY (SELECT (1))) AS RN FROM 
           (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(ID)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(ID)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(ID)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) d(ID)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) e(ID)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) f(ID)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) g(ID)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) h(ID)
)
INSERT INTO ' + @tableName + '
SELECT RN FROM cte WHERE RN <= ' + CAST(@nRows AS NVARCHAR(MAX))

EXEC(@SQLString)

当您在查询中使用变量时,您应该将整个查询分配给另一个变量,然后将其执行为......

DECLARE @sqlstring2 NVARCHAR(MAX) = 'INSERT INTO ' + @tableName + ' VALUES(@i);'
 exec(@sqlstring2)