SQL Server 2008でdo while
ループを実装する方法はありますか?
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 /
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
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
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
しかし、データベースレベルでループを避けるようにしてください。 参照 。
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
を使っているのを捕らえたときに怒りに苦しまないように、あなた自身の裁量でこれらを使ってください。
私はこの記事を何度も読んだことを思い出すように思われます、そしてその答えは私が必要とするものに近いだけです。
通常、私が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は、この無限ループよりも、ループ操作を個別に定義するためのより明確な方法を提供しているようには見えません。
コードをもう少し読みやすくしたい場合は、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
もっと複雑なループがあり、ロジックを追跡しようとしている場合、これはおそらくより関連性があります。前述のようにループは高価ですので、可能であれば他の方法を試してみてください。
WhileループのみがSQLサーバーで正式にサポートされています。 DO whileループ中にすでに 答え があります。 SQLサーバーでさまざまな種類のループを実現する方法についての回答を詳述しています。
ご存知の場合は、とにかく最初のループの反復を完了する必要があります。その後、DO..WHILEまたはREPEAT..UNTILバージョンのSQLを試すことができます。サーバ。
DECLARE @X INT=1;
WAY: --> Here the DO statement
PRINT @X;
SET @X += 1;
IF @X<=10 GOTO WAY;
DECLARE @X INT = 1;
WAY: -- Here the REPEAT statement
PRINT @X;
SET @X += 1;
IFNOT(@X > 10) GOTO WAY;
DECLARE @cnt INT = 0;
WHILE @cnt < 10
BEGIN
PRINT 'Inside FOR LOOP';
SET @cnt = @cnt + 1;
END;
PRINT 'Done FOR LOOP';