Czy istnieje metoda implementacji do whilepętli w SQL Server 2008?
Czy istnieje metoda implementacji do whilepę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 GOZestaw wyników:
1 2 3 4 5Przykł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 GOZestaw wyników:
1 2 3Przykł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 GOZestaw wyników:
1 2 3 4 5
Ale staraj się unikać pętli na poziomie bazy danych. Odniesienie .
Jeśli GOTOsłowo kluczowe nie jest bardzo urażone , może zostać użyte do symulacji znaku DO/ WHILEw 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 GOTOwłączonym rozwiązaniem a oryginalnym DO/ WHILEpseudokodem. Podobna implementacja wykorzystująca WHILEpę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ą WHILEpę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/ WHILEsą rzadkie.
POWTARZAJ / DO KOGOŚ (NIE działa w T-SQL)?
SET I=1
REPEAT
PRINT I
SET I=I+1
UNTIL I>10
... i GOTOrozwią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 GOTOi inwersji logiki za pomocą NOTsłowa kluczowego istnieje bardzo ścisły związek między oryginalnym pseudokodem a GOTOrozwiązaniem bazowym . Podobne rozwiązanie z wykorzystaniem WHILEpę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, WHILErozwią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 WHILEw 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';