9

SQL Server 2012 ストアド プロシージャには、ネストされた構造がいくつかあります。それらの単一のレイヤーから抜け出したいです。

msdn https://msdn.microsoft.com/en-CA/library/ms181271.aspxの BREAK の説明は私の味方だと思いました。しかし、デバッグを介してシングルステップで実行しているときに、奇妙な動作が発生します。一貫性がないので、私は奇妙だと言います。時々それは私が期待する層に逃げます..時々それはいくつかスキップします。

WHILE ... BEGIN
  stuff1
  IF...BEGIN
    stuff2
    WHILE ... BEGIN
      stuff3
      IF .... BEGIN
        stuff4
        IF @NumberRecords=0 BREAK
        stuff5
      END
      --stuff6
      if @NumberRecords=0 and @loopBOMRowCount=@ResultsSOloopstart-1 break
      --on the last occasion I observed, @loopBOMRowCount was 6 and @ResultsSOloopstart 71 and it never highlighted this section, either way

      SET @loopBOMRowCount = @loopBOMRowCount + 1
    END
    stuff7 --nothing actually here
  END
  --stuff8
  SET @periodloopcount=@periodloopcount+1 
  --this is where it ended up highlighting on that last occasion
END
stuff9

NumberRecords=0 の場合、次の op は stuff6 の if になるはずですよね? たとえば、stuff4 に、EXEC 呼び出しからストアド プロシージャへの INSERT INTO テーブルが含まれていたとしても? スタックをそのレイヤーから混乱させることはできませんか?

はい、それは醜い SQL だと思います。命令のほとんどは 2 つの一時テーブルに対する編集であり、ストアド プロシージャとの間でコードをやり取りすることを避けていました。

編集

最初に抜け出したい内部IFの周りにダミーのWHILEループを追加することで、希望どおりにルーティングすることができました。しかし、msdn 情報をどのように誤解しているのかを本当に知りたいです。END ステートメントがある限り、BREAK は IF から抜け出す必要があるようです。

WHILE ステートメントまたは WHILE ループ内の IF…ELSE ステートメントの最も内側のループを終了します。ループの終わりを示す END キーワードの後に​​あるすべてのステートメントが実行されます。

4

2 に答える 2

7

ドキュメントが少しわかりにくいことに同意します。この行は、IF から BREAK できることを示唆しているようです。

WHILE ステートメントまたは WHILE ループ内の IF…ELSE ステートメントの最も内側のループを終了します。ループの終わりを示す END キーワードの後に​​あるすべてのステートメントが実行されます。BREAK は、常にではありませんが、頻繁に IF テストによって開始されます。

しかし、そうではありません。BREAK は、その位置から最も内側の WHILE を終了します。ドキュメントの重要な部分は、「ループの終わりを示すEND キーワードの後に​​現れるすべてのステートメントが実行される」ということです。

この例はこれを示しています。

例 1

DECLARE @X INT = 1;

PRINT 'Start'

/* WHILE loop required to use BREAK.
 */
WHILE @X = 1
BEGIN

    /* Outer IF.
     */
    IF 1 = 1 
    BEGIN
        /* Inner IF.
         */
        IF 2 = 2
        BEGIN
            BREAK
            PRINT '2'
        END

        PRINT '1'
    END

    SET @X = @X + 1;
END

PRINT 'End'

Start と End のテキストのみが印刷されます。WHILE に BREAK が存在するため、1 は出力されません。

この動作は、次の場所でも確認できます。

例 2

/* Anti-Pattern.
 * Breaking outside a WHILE is not allowed.
 */
IF 1 = 1 
BEGIN
    BREAK 
    PRINT 1
END

このクエリは次のエラーを返します。

メッセージ 135、レベル 15、状態 1、行 4 WHILE ステートメントの範囲外で BREAK ステートメントを使用することはできません。

于 2016-01-04T15:25:44.170 に答える