Cú pháp của vòng lặp for trong SQL Server


238

Cú pháp của một forvòng lặp trong TSQL là gì?


10
SQL là một ngôn ngữ rất khác so với những gì bạn đã sử dụng. Nó tập trung vào những gì , không phải như thế nào . Bạn nói với SQL Server những kết quả bạn muốn và để nó tìm ra cách tạo ra câu trả lời. Hoặc, để chia sẻ lại những gì tôi vừa nói - không có vòng lặp for trong SQL.
Damien_The_Unbeliever

5
WHILE @I < 10; SET @I = @I + 1; BEGIN; ...; END? Tuy nhiên, điều này không nên được sử dụng cho hầu hết xử lý truy vấn (nhưng đôi khi được yêu cầu cho thao tác bắt buộc). Nhiều hướng dẫn / gợi ý như vậy có sẵn trên google bằng cách sử dụng tìm kiếm "tsql for loop".

7
Tránh các vòng lặp có lợi cho THAM GIA và thiết lập các hoạt động.
Oded

2
Nếu bạn không phải là chuyên gia về SQL, bạn không nên xem xét sử dụng vòng lặp. Chỉ có một vài điều kiện cần thiết và hầu hết thời gian còn lại, sử dụng vòng lặp là tương đương với việc đẩy xe của bạn thay vì lái nó. Học cách suy nghĩ về các tập dữ liệu thay vì lặp qua các bản ghi. LOoping là một hàm cấp chuyên gia không phải vì cú pháp khó mà vì bạn cần biết chính xác mức độ nguy hại mà bạn có thể làm với nó trước khi bạn được phép sử dụng nó.
HLGEM

2
Đôi khi, nó có thể được sử dụng để nhanh chóng gợi lên dữ liệu kiểm tra trong cơ sở dữ liệu kiểm tra mà bạn sẽ xóa ngay sau đó. Trong trường hợp đó, việc sử dụng điều này sẽ loại bỏ sự cần thiết phải thông qua một chương trình riêng biệt được viết bằng một cái gì đó giống như C #, và kỹ thuật không phải là mối quan tâm chính. Một lần nữa, tôi chỉ nói điều này về mặt dữ liệu thử nghiệm.
Panzercrisis

Câu trả lời:


210

T-SQL không có FORvòng lặp, nó có WHILEvòng lặp
WHILE (Transact-SQL)

WHILE Boolean_expression
BEGIN

END

8
THAM GIA (và thiết lập các hoạt động) nên được ưu tiên hơn các cấu trúc lặp trong SQL.
Oded

6
Không có giới hạn nào cho việc nhấn mạnh (đặc biệt đối với những người chưa quen với SQL), Damien nói: "SQL là một ngôn ngữ rất khác so với những gì bạn đã từng sử dụng. Nó tập trung vào những gì, không phải như thế nào. Bạn nói với SQL Server những gì kết quả bạn muốn và để nó tìm ra cách đưa ra câu trả lời. "
ypercubeᵀᴹ

1
Thật thú vị khi lưu ý các tài liệu MS là sai ở đây, thực sự. WHILE không có biểu thức boolean - nó có một vị ngữ - ngoài việc có thể đánh giá thành TRUE hoặc FALSE, còn có thể là UNKNOWN.
Damien_The_Unbeliever

359

Không có vòng lặp for, chỉ có vòng lặp while:

DECLARE @i int = 0

WHILE @i < 20
BEGIN
    SET @i = @i + 1
    /* do some work */
END

20
Hãy lưu ý rằng nếu bạn có ý định sử dụng chỉ mục trong vòng lặp, bạn có thể muốn tăng điều cuối cùng thay vì đầu tiên, tùy thuộc vào trường hợp sử dụng của bạn.
jinglểula

3
Cũng lưu ý rằng giá trị mặc định cho biến cục bộ không được hỗ trợ trong SQL thuần túy. Do đó bạn cần tách riêng SET @i = 0trước cho vòng lặp.
Nux

1
@Nux: 0 được đặt rõ ràng trong khi khai báo
TcKs

7
Có, nhưng điều đó không hoạt động trên Máy chủ SQL cũ hơn (ít nhất là không phải vào năm 2005).
Nux

Ngoài ra, cần lưu ý rằng công việc thường được thực hiện trước khi số nguyên được tăng lên. Rất nhiều vòng lặp trong SQL thực sự sử dụng số nguyên đó trong công việc của họ (lặp từ hàng này sang hàng khác hoặc kết quả là dẫn đến các bảng tạm thời) và có thể bị loại bỏ nếu sự gia tăng xảy ra ở đầu chu kỳ thay vì kết thúc.
CSS

34

Thông tin thêm

Chỉ cần thêm vào vì không ai đã đăng một câu trả lời bao gồm cách thực sự lặp lại mặc dù một tập dữ liệu trong một vòng lặp, bạn có thể sử dụng từ khóa OFFSET FETCH .

Sử dụng

DECLARE @i INT = 0;
SELECT @count=  Count(*) FROM {TABLE}

WHILE @i <= @count
BEGIN

    SELECT * FROM {TABLE}
    ORDER BY {COLUMN}
    OFFSET @i ROWS   
    FETCH NEXT 1 ROWS ONLY  

    SET @i = @i + 1;

END

2
Đẹp thay thế cho việc sử dụng một con trỏ.
DanteTheSmith

28

DECLARE @intFlag INT
SET @intFlag = 1
WHILE (@intFlag <=5) 
BEGIN
    PRINT @intFlag
    SET @intFlag = @intFlag + 1
END
GO

13
Chào mừng bạn đến với Stack Overflow! Bạn có xem xét việc thêm một số tường thuật để giải thích tại sao mã này hoạt động không, và điều gì làm cho nó trở thành một câu trả lời cho câu hỏi? Điều này sẽ rất hữu ích cho người đặt câu hỏi và bất kỳ ai khác đi cùng.
Andrew Barber

18
Điều này là tự giải thích.
Edward Olamisan

4
Làm thế nào là điều này không tự giải thích? Tôi đã có cùng một câu hỏi, tôi hiểu câu trả lời ngay lập tức.
DanteTheSmith

1
Câu trả lời này khác với @TcK như thế nào ngoại trừ quy ước đặt tên?
Sushil Jadhav

7

Còn cái này thì sao:

BEGIN
   Do Something
END
GO 10

... Tất nhiên bạn có thể đặt một bộ đếm gia tăng bên trong nó nếu bạn cần đếm.


3
'ĐI 10'? SQL Server 2008 không thích nó.
Tài nguyên

7

Đối với vòng lặp chưa được hỗ trợ chính thức bởi máy chủ SQL. Đã có câu trả lời về việc đạt được CHO các cách khác nhau của Loop. Tôi đang chi tiết câu trả lời về các cách để đạt được các loại vòng lặp khác nhau trong máy chủ SQL.

Vòng lặp

DECLARE @cnt INT = 0;

WHILE @cnt < 10
BEGIN
   PRINT 'Inside FOR LOOP';
   SET @cnt = @cnt + 1;
END;

PRINT 'Done FOR LOOP';

Nếu bạn biết, bạn cần phải hoàn thành lặp đầu tiên của vòng lặp dù sao, sau đó bạn có thể thử do..while hoặc REPEAT..UNTIL phiên bản của SQL server.

DO..WHILE Loop

DECLARE @X INT=1;

WAY:  --> Here the  DO statement

  PRINT @X;

  SET @X += 1;

IF @X<=10 GOTO WAY;

REPEAT..UNTIL Loop

DECLARE @X INT = 1;

WAY:  -- Here the REPEAT statement

  PRINT @X;

  SET @X += 1;

IFNOT(@X > 10) GOTO WAY;

Tài liệu tham khảo


Điều này dường như đã được sao chép-dán-sắp xếp lại ở đây: stackoverflow.com/a/46363319/8239061
SecretAgentMan

@SecretAgentMan: Cả hai câu trả lời đều trả lời các câu hỏi khác nhau. Dữ liệu bổ sung được đưa ra trong cả hai câu trả lời.
Somnath Muluk

6

Câu trả lời đơn giản là NO !!.

Không có FORSQL, nhưng bạn có thể sử dụng WHILEhoặc GOTOđể đạt được cách thức FORhoạt động của ý chí.

TRONG KHI :

DECLARE @a INT = 10

WHILE @a <= 20
BEGIN
    PRINT @a
    SET @a = @a + 1
END

ĐI ĐẾN :

DECLARE @a INT = 10
a:
PRINT @a
SET @a = @a + 1
IF @a < = 20
BEGIN
    GOTO a
END

Tôi luôn thích WHILEhơn GOTOtuyên bố.


1
Tôi thích cách bạn đề cập đến cả hai lựa chọn thay thế chỉ là 1 như hầu hết các câu trả lời
DanteTheSmith

0

Trong khi ví dụ Loop trong T-SQL liệt kê ngày bắt đầu đến ngày kết thúc của tháng hiện tại.

DECLARE @Today DATE= GETDATE() ,
@StartOfMonth DATE ,
@EndOfMonth DATE;

DECLARE @DateList TABLE ( DateLabel VARCHAR(10) );
SET @EndOfMonth = EOMONTH(GETDATE());
SET @StartOfMonth = DATEFROMPARTS(YEAR(@Today), MONTH(@Today), 1);

WHILE @StartOfMonth <= @EndOfMonth
BEGIN
    INSERT  INTO @DateList
    VALUES  ( @StartOfMonth );
    SET @StartOfMonth = DATEADD(DAY, 1, @StartOfMonth);
END;

SELECT  DateLabel
FROM    @DateList;  

0

Hãy thử nó, tìm hiểu nó:

DECLARE @r INT = 5
DECLARE @i INT = 0
DECLARE @F varchar(max) = ''
WHILE @i < @r
BEGIN

    DECLARE @j INT = 0
    DECLARE @o varchar(max) = ''
    WHILE @j < @r - @i - 1
    BEGIN
        SET @o = @o + ' '
        SET @j += 1
    END

    DECLARE @k INT = 0
    WHILE @k < @i + 1
    BEGIN
        SET @o = @o + ' *'  -- '*'
        SET @k += 1
    END
    SET @i += 1
    SET @F = @F + @o + CHAR(13)
END
PRINT @F

Có ngày:

DECLARE @d DATE = '2019-11-01'
WHILE @d < GETDATE()
BEGIN
    PRINT @d
    SET @d = DATEADD(DAY,1,@d)
END
PRINT 'n'
PRINT @d
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.