Если вы не очень обижены ключевым словом GOTO
, его можно использовать для имитации DO
/ WHILE
в T-SQL.Рассмотрим следующий довольно бессмысленный пример, написанный в псевдокоде:
SET I=1
DO
PRINT I
SET I=I+1
WHILE I<=10
Вот эквивалентный код T-SQL с использованием goto:
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
... и решение на основе GOTO
в T-SQL:
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
решение на основе WHILE
является более простым, посколькуусловие if не инвертируется.С другой стороны, это также более многословно.
Если бы не было всего презрения к использованию GOTO
, это могло бы быть даже идиоматическим решением для тех немногих раз, когда эти конкретные (злые)Для ясности циклические конструкции необходимы в коде T-SQL.
Используйте их по своему усмотрению, стараясь не подвергать гневу своих коллег-разработчиков, когда они поймают вас, используя очень клеветнические GOTO
.