在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应该是if在stuff6,对吗?即使stuff4包含,例如,EXEC调用存储过程的INSERT INTO表?没有什么能够将堆栈混淆出层?
是的,我意识到这是丑陋的SQL。大多数指令都是在两个临时表上编辑的,我避免将它们来回传递给存储过程,否则会清理代码。
修改
我设法让它按照我想要的方式进行路由,在内部IF周围添加一个虚拟WHILE循环,我想首先突破。但我真的很想知道我是如何误解msdn信息的。似乎BREAK应该突破IF,只要它有END语句。
退出 WHILE语句中最内层循环或WHILE循环内的IF ... ELSE语句。将执行END关键字后面出现的任何语句,标记循环结束。
答案 0 :(得分:7)
我同意documentation有点令人困惑。这条线似乎暗示你可以突破IF。
退出WHILE语句或IF ... ELSE语句中的最内层循环 在WHILE循环中。 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'
仅打印“开始”和“结束”文本。因为BREAK存在WHILE,所以不打印1。
您还可以在此处看到此行为:
示例2
/* Anti-Pattern.
* Breaking outside a WHILE is not allowed.
*/
IF 1 = 1
BEGIN
BREAK
PRINT 1
END
此查询返回错误:
消息135,级别15,状态1,行4不能使用BREAK语句 超出WHILE声明的范围。
答案 1 :(得分:0)
如果您真的想要打破IF语句,打印“开始,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
GOTO skip2
PRINT '2'
END
skip2:
PRINT '1'
END
SET @X = @X + 1;
END
PRINT 'End'
现在您可以使用它来使用以下
来处理OP的示例WHILE ... BEGIN
stuff1
IF...BEGIN
stuff2
WHILE ... BEGIN
stuff3
IF .... BEGIN
stuff4
IF @NumberRecords=0
GOTO startstuff6
stuff5
END
startstuff6:
--stuff6
if @NumberRecords=0 and @loopBOMRowCount=@ResultsSOloopstart-1
GOTO startstuff7
--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
startstuff7:
stuff7 --nothing actually here
END
--stuff8
SET @periodloopcount=@periodloopcount+1
--this is where it ended up highlighting on that last occasion
END
stuff9
通常认为反转布尔逻辑的方法更好,例如:
IF NOT @NumberRecords=0
BEGIN
stuff5
END