Как организовать бесконечный цикл while в SQL Server?
Я хочу использовать бесконечный цикл WHILE
в SQL Server 2005 и использовать ключевое слово BREAK
для выхода из него при определенных условиях.
while true
не работает, поэтому я должен использовать while 1=1
.
Есть ли лучший способ организовать бесконечный цикл?
Я знаю, что могу использовать goto
, но while 1=1 begin ... end
выглядит конструктивно.
Ответы
Ответ 1
В дополнение к WHILE 1 = 1
, как показывают другие ответы, я часто добавляю "тайм-аут" в мои циклы "infintie" SQL, как в следующем примере:
DECLARE @startTime datetime2(0) = GETDATE();
-- This will loop until BREAK is called, or until a timeout of 45 seconds.
WHILE (GETDATE() < DATEADD(SECOND, 45, @startTime))
BEGIN
-- Logic goes here: The loop can be broken with the BREAK command.
-- Throttle the loop for 2 seconds.
WAITFOR DELAY '00:00:02';
END
Я нашел этот метод полезным в хранимой процедуре, которая вызывается из длинного опроса AJAX. Наличие цикла на стороне базы данных освобождает приложение от необходимости постоянно ударять по базе данных, чтобы проверить свежие данные.
Ответ 2
Использование While 1 = 1
с инструкцией Break
- это способ сделать это. В T-SQL нет константы для TRUE или FALSE.
Ответ 3
Если вам действительно нужно использовать бесконечный цикл, чем использовать while 1=1
, я бы это сделал.
Вопрос в том, есть ли другой способ избежать бесконечного цикла? Эти вещи просто имеют тенденцию идти не так;)
Ответ 4
вы можете использовать сниппет ниже, чтобы выскочить sp после того, как условие soem будет увеличено. Я предполагаю, что вы ahev какой-то таблицы CurrentJobStatus, где все задания /sp сохраняют свой статус...
-- *** reload data on N Support.usp_OverrideMode with checks on Status
/* run
Support.usp_OverrideMode.Number1.sql
and
Support.usp_OverrideMode.Number2.sql
*/
DECLARE @FileNameSet TABLE (FileName VARCHAR(255));
INSERT INTO @FileNameSet
VALUES ('%SomeID1%');
INSERT INTO @FileNameSet
VALUES ('%SomeID2%');
DECLARE @BatchRunID INT;
DECLARE @CounterSuccess INT = 0;
DECLARE @CounterError INT = 0;
-- Loop
WHILE WHILE (@CounterError = 0 AND @CounterSuccess < (select COUNT(1) c from @FileNameSet) )
BEGIN
DECLARE @CurrenstStatus VARCHAR(255)
SELECT @CurrenstStatus = CAST(GETDATE() AS VARCHAR)
-- Logic goes here: The loop can be broken with the BREAK command.
SELECT @CounterSuccess = COUNT(1)
FROM dbo.CurrentJobStatus t
INNER JOIN @FileNameSet fns
ON (t.FileName LIKE fns.FileName)
WHERE LoadStatus = 'Completed Successfully'
SELECT @CounterError = COUNT(1)
FROM dbo.CurrentJobStatus t
INNER JOIN @FileNameSet fns
ON (t.FileName LIKE fns.FileName)
WHERE LoadStatus = 'Completed with Error(s)'
-- Throttle the loop for 3 seconds.
WAITFOR DELAY '00:00:03';
select @CurrenstStatus = @CurrenstStatus +char(9)+ '@CounterSuccess ' + CAST(@CounterSuccess AS VARCHAR(11))
+ char(9)+ 'CounterError ' + CAST(@CounterError AS VARCHAR(11))
RAISERROR (
'Looping... @ %s'
,0
,1
,@CurrenstStatus
)
WITH NOWAIT;
END
-- TODO add some codition on @CounterError value
/* run
Support.usp_OverrideMode.WhenAllSuceed.sql
*/
Обратите внимание, что код flexibile вы можете добавить столько проверок условий в таблице @FileNameSet var
Марио