SQL Serverのforループの構文


238

forTSQLのループの構文は何ですか?


10
SQLは、慣れ親しんでいる言語とは非常に異なる言語です。どのようにではなく、に焦点を当てています。SQL Serverに必要な結果を通知し、答えを生成する方法を理解させます。または、今言ったことを要約すると、SQLにはforループはありません。
Damien_The_Unbeliever

5
WHILE @I < 10; SET @I = @I + 1; BEGIN; ...; END?ただし、これはほとんどのクエリ処理に使用するべきではありません(ただし、命令操作では必要になる場合があります)。多くのそのような指示/ヒントは、検索「tsql for loop」を使用してグーグルで利用可能です。

7
JOINと集合演算を優先するループは避けてください。
2010年

2
SQLの専門家でない場合は、ループの使用を検討すべきではありません。必要な状況はほんのわずかで、残りのほとんどの場合、ループを使用することは、車を運転するのではなく押すことと同じです。レコードをループするのではなく、データセットの観点から考えることを学びます。LOopingはエキスパートレベルの関数です。構文が難しいからではなく、使用を許可する前に、それを使ってどの程度の害を与えるかを正確に知る必要があるからです。
HLGEM 2013

2
場合によっては、後ですぐに削除しようとしているテストデータベース内のテストデータをすばやく呼び出すために使用できます。その場合、これを使用すると、C#などで記述された別のプログラムを実行する必要がなくなり、エンジニアリングは特に大きな問題にはなりません。繰り返しますが、これはテストデータの観点から言っています。
Panzercrisis 2017

回答:


210

T-SQLにはFORループがありませんが、ループがありWHILEます
WHILE(Transact-SQL)

WHILE Boolean_expression
BEGIN

END

8
JOIN(およびセット操作)は、SQLのループ構造よりも優先する必要があります。
2010年

6
ストレスに制限はありません(特にSQLを初めて使用する場合)、Damien氏は次のように述べています。あなたが望む結果、それが答えを生成する方法を見つけ出すましょう」。
ypercubeᵀᴹ

1
ここで、MSのドキュメントが間違っていることに注意してください。WHILEはブール式を取りません-述語を取ります-これはTRUEまたはFALSEに評価できることに加えて、UNKNOWNになることもあります。
Damien_The_Unbeliever '20年

359

forループはなく、whileループのみです。

DECLARE @i int = 0

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

20
ループでインデックスを使用する場合は、ユースケースによっては、最初ではなく最後のものをインクリメントしたい場合があることに注意してください。
jinglesthula 2013年

3
ローカル変数のデフォルト値はプレーンSQLではサポートされていないことにも注意してください。したがってSET @i = 0、for beforeループを分離する必要があります。
Nux 2014年

1
@Nux:0は、明示的に宣言時に設定されている
TCKS

7
はい。ただし、それは古いSQLサーバーでは機能しません(少なくとも2005では機能しません)。
Nux 2014年

また、通常、整数がインクリメントされる前に作業が行われることに注意してください。SQLの多くのforループは、実際にその整数を作業で使用し(行から行への反復、または結果として一時テーブルになる)、サイクルの最後ではなく最初にインクリメントが発生するとスローされます。
CSS

34

追加情報

ループ内のデータセットを実際に反復する方法を含む回答を誰も投稿していないので、追加するために、キーワードOFFSET FETCHを使用できます。

使用法

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
カーソルを使用する代わりの素晴らしい方法。
DanteTheSmith

28

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

13
Stack Overflowへようこそ!このコードが機能する理由を説明するためにいくつかの説明を追加することを検討しますか、そしてそれが質問への回答となる理由は何ですか?これは、質問をしている人や、一緒に来た人にとって非常に役立ちます。
Andrew Barber

18
これは自明です。
Edward Olamisan

4
これは自明ではないのですか?同じ質問があり、すぐに答えがわかりました。
DanteTheSmith、2017年

1
この回答は、命名規則を除いて@TcKsとどのように異なりますか?
Sushil Jadhav

7

これはどう:

BEGIN
   Do Something
END
GO 10

...もちろん、カウントする必要がある場合は、その中に増分カウンターを置くことができます。


3
「GO 10」?SQL Server 2008はそれを好みません。
リソース

7

forループは、SQLサーバーではまだ正式にサポートされていません。FORを達成するための答えはすでにありますループのさまざまな方法ます。SQL Serverでさまざまな種類のループを実現する方法について詳しく説明しています。

FORループ

DECLARE @cnt INT = 0;

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

PRINT 'Done FOR LOOP';

わかっている場合は、とにかくループの最初の反復を完了する必要がある場合は、SQLサーバーのDO..WHILEまたはREPEAT..UNTILバージョンを試すことができます。

DO..WHILEループ

DECLARE @X INT=1;

WAY:  --> Here the  DO statement

  PRINT @X;

  SET @X += 1;

IF @X<=10 GOTO WAY;

REPEAT..UNTILループ

DECLARE @X INT = 1;

WAY:  -- Here the REPEAT statement

  PRINT @X;

  SET @X += 1;

IFNOT(@X > 10) GOTO WAY;

参照


これはコピーされて貼り付けられたようです:stackoverflow.com/a/46363319/8239061
SecretAgentMan

@SecretAgentMan:どちらの回答も異なる質問に答えています。両方の回答で追加のデータが提供されています。
Somnath Muluk

6

簡単な答えはNO !!です。

そこにはありませんFORSQLで、しかし、あなたは使用することができますWHILEまたはGOTOどのような方法を達成するためにFOR動作しますが。

WHILE:

DECLARE @a INT = 10

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

GOTO:

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

私はいつも好むWHILEGOTOの文。


1
私は、あなただけではなく、1ほとんどの回答のように、両方の選択肢を述べた方法を好む
DanteTheSmith

0

T-SQLのWhileループの例は、当月の開始日から終了日までをリストしています。

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

試して、学んでください:

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

日付あり:

DECLARE @d DATE = '2019-11-01'
WHILE @d < GETDATE()
BEGIN
    PRINT @d
    SET @d = DATEADD(DAY,1,@d)
END
PRINT 'n'
PRINT @d
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.