Чи є який-небудь метод для виконання do whileциклу на SQL сервері 2008?
Чи є який-небудь метод для виконання do whileциклу на SQL сервері 2008?
Відповіді:
Я не впевнений у 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 GOНабір результатів:
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 GOНабір результатів:
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 GOНабір результатів:
1 2 3 4 5
Але намагайтеся уникати циклів на рівні бази даних. Довідково .
Якщо ви не дуже ображаєтеся на 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рішення на основі простіше, тому що , якщо умова не інвертується. З іншого боку, це також більш багатослівно.
Якщо б не було зневаги навколо використання GOTO, це може бути навіть ідіоматичним рішенням для тих кількох разів, коли ці конкретні (злі) циклічні конструкції необхідні в коді T-SQL для наочності.
Використовуйте їх на власний розсуд, намагаючись не зазнавати гніву ваших колег-розробників, коли вони зловили вас, використовуючи сильно злісних GOTO.
Здається, я не раз згадував, як читав цю статтю, і відповідь близький лише до того, що мені потрібно.
Зазвичай, коли я думаю, що мені знадобиться DO WHILET-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, здається, не пропонує більш чіткого способу однозначного визначення циклу, ніж цей нескінченний цикл.
Ви також можете використовувати змінну виходу, якщо хочете, щоб ваш код був трохи більш читабельним:
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
Це, мабуть, буде більш актуальним, коли у вас є складніший цикл і ви намагаєтесь відслідковувати логіку. Як зазначено, петлі дорогі, тому спробуйте скористатися іншими способами.
Тільки поки цикл офіційно підтримується сервером SQL. Вже є відповідь за DO while loop. Я деталізую відповідь про способи досягнення різних типів циклів на 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';