我的任务是:创建一个表并在同一个存储过程中的表中插入n个值。
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
我知道问题是表在提交之前不存在;这就是我无法插入的原因。但是如何重写这个能够完成我的任务呢?
答案 0 :(得分:2)
插入应该是动态的。使用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)
答案 1 :(得分:1)
当您在查询中使用变量时,您应该将总查询分配给另一个变量,然后将其执行为.....
DECLARE @sqlstring2 NVARCHAR(MAX) = 'INSERT INTO ' + @tableName + ' VALUES(@i);'
exec(@sqlstring2)