我们可以在 SQL Server 中使用 while 循环将记录存储在临时表中吗?



我有一个场景,使用 while 循环将记录存储在临时表中,如下所示。

例如

DECLARE @intFlag INT
SET @intFlag = 1
WHILE (@intFlag <=5)
BEGIN
PRINT @intFlag
SET @intFlag = @intFlag + 1
select @intFlag datas
into #tempped
END
GO

可以这样做吗?

您可以创建临时表并从循环insert到其中。 例如:

create table #tempped (datas int);
DECLARE @intFlag INT
SET @intFlag = 1
WHILE (@intFlag <=5)
BEGIN
PRINT @intFlag;
insert into #tempped (datas)
select @intFlag;
SET @intFlag = @intFlag + 1;
END
GO

我认为这个问题是一个抽象,如果您对性能感兴趣,那么while循环、递归 cte 或游标不是性能最高的解决方案。请改用数字或计数表。

延伸阅读:

  • 生成不带循环的集合或序列 - 1 - 亚伦·伯特兰
  • 生成没有循环的集合或序列 - 2 - 亚伦·伯特兰
  • 生成不带循环的集合或序列 - 3 - 亚伦·伯特兰
  • ">
  • 数字"或"计数"表:它是什么以及它如何取代循环 - 杰夫·莫登

这是使用递归 CTE 的另一种解决方案:

;WITH
cte(datas) AS
(
SELECT      1
UNION ALL
SELECT      datas + 1
FROM        cte
WHERE       datas < 5
)
SELECT  datas
INTO    #tempped
FROM    cte
OPTION (MAXRECURSION 0)

另一个带有TALLY CTE的选项。这将适用于多达 10K 的记录...

WITH
E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS 
(
SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
select N 
INTO #tempped
FROM cteTally
WHERE N <= 5

SELECT * FROM cteTally
SELECT * FROM #tempped
DROP TABLE #tempped

这样做的好处是您可以使用它创建一个视图......再也不用担心这个问题了。也就是说,您可以在需要"数字表"连接时引用视图。

create View [dbo].[cteTally] as
WITH
E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS 
(
SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
select N from cteTally
GO

然后,对于您的示例,您只需执行以下操作:

SELECT  N
INTO    #tempped
FROM    cteTally
WHERE N <=5

肖恩·朗格原始视图...

最新更新