web-dev-qa-db-ja.com

SQL Server 2008でwhileループを実行する

SQL Server 2008でdo whileループを実装する方法はありますか?

114
Nithesh

MS SQL Server 2008のDO-WHILEについてはよくわかりませんが、DO-WHILEループのように使用するようにWHILEループロジックを変更できます。

例はここから取られます: http://blog.sqlauthority.com/2007/10/24/sql-server-simple-example-of-while-loop-with-continue-and -break-keywords /

  1. WHILEループの例

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

    ResultSet:

    1
    2
    3
    4
    5
    
  2. BREAKキーワードを使用したWHILEループの例

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

    ResultSet:

    1
    2
    3
    
  3. CONTINUEキーワードとBREAKキーワードを使用したWHILEループの例

    DECLARE @intFlag INT
    SET @intFlag = 1
    WHILE (@intFlag <=5)
    BEGIN
        PRINT @intFlag
        SET @intFlag = @intFlag + 1
        CONTINUE;
        IF @intFlag = 4 -- This will never executed
            BREAK;
    END
    GO
    

    ResultSet:

    1
    2
    3
    4
    5
    

しかし、データベースレベルでループを避けるようにしてください。 参照

180
Pratik

GOTOキーワードにそれほど気を悪くしていないのであれば、T-SQLでDO/WHILEをシミュレートするために使用できます。疑似コードで書かれた、次のどちらかといえば意味のない意味を持たない例を考えてください。

SET I=1
DO
 PRINT I
 SET I=I+1
WHILE I<=10

これは、gotoを使った同等のT-SQLコードです。

DECLARE @I INT=1;
START:                -- DO
  PRINT @I;
  SET @I+=1;
IF @I<=10 GOTO START; -- WHILE @I<=10

GOTO対応ソリューションと元のDO/WHILE疑似コードの間の一対一のマッピングに注目してください。 WHILEループを使用した同様の実装は次のようになります。

DECLARE @I INT=1;
WHILE (1=1)              -- DO
 BEGIN
  PRINT @I;
  SET @I+=1;
  IF NOT (@I<=10) BREAK; -- WHILE @I<=10
 END

さて、あなたはもちろんこの特定の例を単純なWHILEループとして書き直すことができます、なぜならこれはDO/WHILE構文にとってそれほど良い候補ではないからです。 DO/WHILEを必要とする合法的なケースはまれであるため、適用可能性よりもむしろ例の簡潔さに重点が置かれました。


REPEAT/UNTIL、誰でも(T-SQLでは動作しません)?

SET I=1
REPEAT
  PRINT I
  SET I=I+1
UNTIL I>10

...とT-SQLのGOTOベースのソリューション:

DECLARE @I INT=1;
START:                    -- REPEAT
  PRINT @I;
  SET @I+=1;
IF NOT(@I>10) GOTO START; -- UNTIL @I>10

GOTOを創造的に使用し、NOTキーワードを使用して論理を反転することにより、元の疑似コードとGOTOベースのソリューションの間には非常に密接な関係があります。 WHILEループを使用した同様の解決策は以下のようになります。

DECLARE @I INT=1;
WHILE (1=1)       -- REPEAT
 BEGIN
  PRINT @I;
  SET @I+=1;
  IF @I>10 BREAK; -- UNTIL @I>10
 END

REPEAT/UNTILの場合、if条件が反転されていないため、WHILEベースのソリューションの方が簡単であるという議論をすることができます。その一方で、それはまたより冗長です。

それがGOTOの使用に関するすべての軽蔑のためではなかったならば、明快さのためにこれらの特定の(悪)ループ構造がT-SQLコードで必要であるときにはこれらは慣例的な解決法でさえありえます。

あなたの仲間の開発者があなたが狂ったGOTOを使っているのを捕らえたときに怒りに苦しまないように、あなた自身の裁量でこれらを使ってください。

58

私はこの記事を何度も読んだことを思い出すように思われます、そしてその答えは私が必要とするものに近いだけです。

通常、私がT-SQLでDO WHILEが必要になると思うとき、それはカーソルをイテレートしているためです。そして、私は最適な明瞭さ(対最適な速度)を主に探しています。 T-SQLではWHILE TRUE/IF BREAKに合うようです。

それがここにあなたをもたらしたシナリオであるならば、この断片はあなたをちょっと節約するかもしれません。それ以外の場合は、私を歓迎します。今、私は私が何度もここにいたことを確信できます。 :)

DECLARE Id INT, @Title VARCHAR(50)
DECLARE Iterator CURSOR FORWARD_ONLY FOR
SELECT Id, Title FROM dbo.SourceTable
OPEN Iterator
WHILE 1=1 BEGIN
    FETCH NEXT FROM @InputTable INTO @Id, @Title
    IF @@FETCH_STATUS < 0 BREAK
    PRINT 'Do something with ' + @Title
END
CLOSE Iterator
DEALLOCATE Iterator

残念ながら、T-SQLは、この無限ループよりも、ループ操作を個別に定義するためのより明確な方法を提供しているようには見えません。

18
shannon

コードをもう少し読みやすくしたい場合は、exit変数を使用することもできます。

DECLARE @Flag int = 0
DECLARE @Done bit = 0

WHILE @Done = 0 BEGIN
    SET @Flag = @Flag + 1
    PRINT @Flag
    IF @Flag >= 5 SET @Done = 1
END

もっと複雑なループがあり、ロジックを追跡しようとしている場合、これはおそらくより関連性があります。前述のようにループは高価ですので、可能であれば他の方法を試してみてください。

4
Sebris87

WhileループのみがSQLサーバーで正式にサポートされています。 DO whileループ中にすでに 答え があります。 SQLサーバーでさまざまな種類のループを実現する方法についての回答を詳述しています。

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

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;

FOR Loop

DECLARE @cnt INT = 0;

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

PRINT 'Done FOR LOOP';

参考文献

1
Somnath Muluk