Czy istnieje metoda implementacji do while
pętli w SQL Server 2008?
Czy istnieje metoda implementacji do while
pętli w SQL Server 2008?
Odpowiedzi:
Nie jestem pewien co do DO-WHILE W MS SQL Server 2008, ale możesz zmienić logikę pętli WHILE, tak aby UŻYWAĆ jak pętla DO-WHILE.
Przykłady są pobierane stąd: http://blog.sqlauthority.com/2007/10/24/sql-server-simple-example-of-while-loop-with-continue-and-break-keywords/
Przykład pętli WHILE
DECLARE @intFlag INT SET @intFlag = 1 WHILE (@intFlag <=5) BEGIN PRINT @intFlag SET @intFlag = @intFlag + 1 END GO
Zestaw wyników:
1 2 3 4 5
Przykład pętli WHILE ze słowem kluczowym BREAK
DECLARE @intFlag INT SET @intFlag = 1 WHILE (@intFlag <=5) BEGIN PRINT @intFlag SET @intFlag = @intFlag + 1 IF @intFlag = 4 BREAK; END GO
Zestaw wyników:
1 2 3
Przykład pętli WHILE ze słowami kluczowymi CONTINUE i 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
Zestaw wyników:
1 2 3 4 5
Ale staraj się unikać pętli na poziomie bazy danych. Odniesienie .
Jeśli GOTO
słowo kluczowe nie jest bardzo urażone , może zostać użyte do symulacji znaku DO
/ WHILE
w T-SQL. Rozważmy następujący, raczej bezsensowny przykład zapisany w pseudokodzie:
SET I=1
DO
PRINT I
SET I=I+1
WHILE I<=10
Oto odpowiednik kodu T-SQL przy użyciu goto:
DECLARE @I INT=1;
START: -- DO
PRINT @I;
SET @I+=1;
IF @I<=10 GOTO START; -- WHILE @I<=10
Zwróć uwagę na mapowanie jeden do jednego między GOTO
włączonym rozwiązaniem a oryginalnym DO
/ WHILE
pseudokodem. Podobna implementacja wykorzystująca WHILE
pętlę wyglądałaby następująco:
DECLARE @I INT=1;
WHILE (1=1) -- DO
BEGIN
PRINT @I;
SET @I+=1;
IF NOT (@I<=10) BREAK; -- WHILE @I<=10
END
Teraz możesz oczywiście przepisać ten konkretny przykład jako prostą WHILE
pętlę, ponieważ nie jest to dobry kandydat na konstrukcję DO
/ WHILE
. Nacisk położono na przykład raczej na zwięzłość niż możliwość zastosowania, ponieważ uzasadnione przypadki wymagające a DO
/ WHILE
są rzadkie.
POWTARZAJ / DO KOGOŚ (NIE działa w T-SQL)?
SET I=1
REPEAT
PRINT I
SET I=I+1
UNTIL I>10
... i GOTO
rozwiązanie oparte na T-SQL:
DECLARE @I INT=1;
START: -- REPEAT
PRINT @I;
SET @I+=1;
IF NOT(@I>10) GOTO START; -- UNTIL @I>10
Dzięki kreatywnemu użyciu GOTO
i inwersji logiki za pomocą NOT
słowa kluczowego istnieje bardzo ścisły związek między oryginalnym pseudokodem a GOTO
rozwiązaniem bazowym . Podobne rozwiązanie z wykorzystaniem WHILE
pętli wygląda następująco:
DECLARE @I INT=1;
WHILE (1=1) -- REPEAT
BEGIN
PRINT @I;
SET @I+=1;
IF @I>10 BREAK; -- UNTIL @I>10
END
Można argumentować, że w przypadku REPEAT
/ UNTIL
, WHILE
rozwiązanie bazowe jest prostsze, ponieważ warunek if nie jest odwrócony. Z drugiej strony jest też bardziej szczegółowy.
Gdyby nie cała pogarda związana z używaniem programu GOTO
, mogłyby to być nawet idiomatyczne rozwiązania na te kilka razy, gdy te szczególne (złe) konstrukcje pętli są konieczne w kodzie T-SQL ze względu na przejrzystość.
Używaj ich według własnego uznania, starając się nie cierpieć gniewu innych programistów, gdy złapią cię na bardzo oczernianym GOTO
.
Wydaje mi się, że czytałem ten artykuł więcej niż raz, a odpowiedź jest tylko bliska tego, czego potrzebuję.
Zwykle, gdy myślę, że będę potrzebować DO WHILE
w T-SQL, dzieje się tak, ponieważ iteruję kursor i szukam w dużej mierze optymalnej przejrzystości (w porównaniu z optymalną prędkością). W T-SQL wydaje się pasować do WHILE TRUE
/ IF BREAK
.
Jeśli to jest scenariusz, który Cię tu sprowadził, ten fragment może Ci zaoszczędzić chwilę. W przeciwnym razie witaj z powrotem, ja. Teraz mogę być pewien, że byłem tu więcej niż raz. :)
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
Niestety, T-SQL nie wydaje się oferować czystszego sposobu pojedynczego zdefiniowania operacji pętli niż ta nieskończona pętla.
Możesz także użyć zmiennej wyjścia, jeśli chcesz, aby Twój kod był nieco bardziej czytelny:
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
Byłoby to prawdopodobnie bardziej istotne, gdy masz bardziej skomplikowaną pętlę i próbujesz śledzić logikę. Jak wspomniano, pętle są drogie, więc jeśli możesz, spróbuj użyć innych metod.
Tylko While Loop jest oficjalnie obsługiwany przez serwer SQL. Jest już odpowiedź na pętlę DO while. Szczegółowo opisuję sposoby uzyskiwania różnych typów pętli w serwerze SQL.
Jeśli wiesz, i tak musisz ukończyć pierwszą iterację pętli, możesz wypróbować wersję DO..WHILE lub REPEAT..UNTIL serwera 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';