Есть ли какой-либо метод для реализации цикла do while в SQL Server 2008?
Выполнять цикл while в SQL Server 2008
Ответ 1
Я не уверен в DO-WHILE в MS SQL Server 2008, но вы можете изменить логику цикла WHILE, чтобы ИСПОЛЬЗОВАТЬ, как цикл DO-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 GOResultSet:
1 2 3 4 5Пример цикла WHILE с ключевым словом BREAK
DECLARE @intFlag INT SET @intFlag = 1 WHILE (@intFlag <=5) BEGIN PRINT @intFlag SET @intFlag = @intFlag + 1 IF @intFlag = 4 BREAK; END GOResultSet:
1 2 3Пример цикла WHILE с ключевыми словами CONTINUE и BREAK
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 GOResultSet:
1 2 3 4 5
Но попробуйте избежать циклов на уровне базы данных. Ссылка.
Ответ 2
Если вы не очень обиделись на ключевое слово 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 enabled и исходным псевдокодом 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.
Ответ 3
Кажется, я вспоминаю эту статью несколько раз, и ответ близок к тому, что мне нужно.
Обычно, когда я думаю, что мне понадобится DO WHILE в T-SQL, потому что я повторяю курсор, и я ищу в значительной степени оптимальную ясность (по сравнению с оптимальной скоростью). В 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, по-видимому, не предлагает более чистого способа одномерного определения операции цикла, чем этот бесконечный цикл.
Ответ 4
Вы также можете использовать переменную 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
Это, вероятно, будет более актуальным, если у вас будет более сложный цикл и пытайтесь отслеживать логику. Поскольку указанные циклы дороги, поэтому попробуйте использовать другие методы, если сможете.
Ответ 5
Только пока Loop официально поддерживается сервером SQL. Уже есть answer для цикла DO while. Я подробно расскажу о способах достижения различных типов циклов на SQL-сервере.
Если вы знаете, вам нужно выполнить первую итерацию цикла в любом случае, тогда вы можете попробовать версию SQL Server DO..WHILE или REPEAT..UNTIL.
DO..WHILE Loop
DECLARE @X INT=1;
WAY:  --> Here the  DO statement
  PRINT @X;
  SET @X += 1;
IF @X<=10 GOTO WAY;
REPEAT..UNTIL Loop
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';