2012-03-26 115 views
3

我需要在SQL中运行一个循环。谷歌这有点难以出于某种奇怪的原因。在SQL Server我只是把这是在SQL Server枭雄查询编辑工作室SQL Server循环并插入到sql中

DECLARE @z_start INT 
SET @z_start = 0 
DECLARE @z_end INT 
SET @z_end = 0 

WHILE (@z_start <= 14) BEGIN 
    IF(@z_start != 0 AND @z_end != 14) 
     WHILE (@z_end <= 14) BEGIN 
      INSERT INTO [campusMap].[dbo].[zoom_levels] ([zoom_start],[zoom_end]) VALUES (@z_start,@z_end) 
      SET @z_end = @z_end + 1 
     END 
     SET @z_start = @z_start + 1 
    END 
END 

所有我想要做的是设置zoom_start和zoom_end所以(0,0)到(14,14)只跳过(0,14),这已经在表格中了。

我想我很近。任何人都知道它在哪里?谢谢。 Cheers -Jeremy

回答

14

而不是做一个嵌套循环并插入每一行的时间,你可以使用一个CTE(或者预先存在的数字表),并添加你需要一次的所有行:

;WITH Numbers (Number) AS 
(
    SELECT 0 
    UNION ALL 
    SELECT 1 + Number FROM Numbers 
    WHERE 1 + Number <= 14 
) 
INSERT INTO [campusMap].[dbo].[zoom_levels] ([zoom_start],[zoom_end]) 
SELECT n1.Number, n2.Number 
FROM 
    Numbers n1 CROSS JOIN 
    Numbers n2 
WHERE 
    NOT (n1.Number = 0 AND n2.Number = 14) 

SQL中的基于集合的操作通常比程序性的逐行方法更清晰且更容易理解。

+0

很好的解决方案! – rlobban 2012-03-26 16:37:43

+0

+1 ... Tally表总是在sql中获得循环点头。 – 2012-03-26 16:39:09

+0

哇..是的.. +1在这里tk在那里学习我。 :d – 2012-03-26 16:49:29

2

在第一次循环之后,您不会将@z_end重新初始化为零。不要

DECLARE @z_start INT 
SET @z_start = 0 
DECLARE @z_end INT 
SET @z_end = 0 
WHILE (@z_start <= 14) BEGIN 
    IF(@z_start != 0 AND @z_end != 14) 
     WHILE (@z_end <= 14) BEGIN 
      INSERT INTO [campusMap].[dbo].[zoom_levels] ([zoom_start],[zoom_end]) VALUES (@z_start,@z_end) 
      SET @z_end = @z_end + 1 
     END 
     SET @z_start = @z_start + 1 
     SET @z_end = 0 
    END 
END 
1
insert into [campusMap].[dbo].[zoom_levels] ([zoom_start],[zoom_end]) 
select T1.N, T2.N 
from 
    (values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14)) as T1(N) 
cross join 
    (values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14)) as T2(N) 
where not (T1.N = 0 and T2.N = 14)