I have a simple query which loops and I want to see the PRINT messages during the execution. The query is something like this:
WHILE 1 = 1
BEGIN
WAITFOR DELAY '000:00:10'
PRINT 'here'
END
The PRINT 'here' does not output until I stop the process. However, I want to see it while it's running. Is this possible?
You can use RAISERROR with serverity 0 and the NOWAIT option
WHILE 1 = 1
BEGIN
WAITFOR DELAY '000:00:10'
RAISERROR ('here', 0, 1) WITH NOWAIT
END
I believe that the prints get buffered, releasing "chunks" as the buffer fills up.
try using raiserror:
How do I flush the PRINT buffer in TSQL?
Try this..
DECLARE #i INT = 1
WHILE ( #i <= 10)
BEGIN
--- do something
SELECT 'Completed ' + CAST(#i AS VARCHAR(50)) + ' : ' + CAST(GETDATE() AS VARCHAR(50));
SET #i = #i + 1
END
current suggestions don't work for SSMS 18 and above.
Print then raiserror(N'', 0, 1) seems to get around this.
Related
im trying the do a simple cursor that will give me data , executing the cursor in a 5 seconds interval .
but it only shows 1 row and stop... im working on sybase interactive sql , this is the query:
DECLARE #codigo INTEGER
DECLARE alarm_history_cur CURSOR FOR
SELECT AlarmHistoryID FROM DBA.AlarmHistory
WHERE DBA.AlarmHistory.Area = '1'
AND DBA.AlarmHistory.DateTimeOccurred < '2021-01-01 00:00:00.000'
OPEN alarm_history_cur
FETCH NEXT alarm_history_cur INTO #codigo
while ##sqlstatus = 0
BEGIN
WAITFOR DELAY '00:00:05'
SELECT * FROM DBA.AlarmHistory WHERE AlarmHistoryID = #codigo
END
BEGIN
FETCH NEXT alarm_history_cur
INTO #codigo
END
CLOSE alarm_history_cur
DEALLOCATE CURSOR alarm_history_cur
thanks in advance for further help.
Update :
im using sybase central - sql anywhere ..i will let some pictures to you
-##version pictureenter image description here
-original select
-what actually the syntax shows
enter image description here
enter image description here
The fetch command needs to be in the same begin/end pair associated with the while loop.
Instead of this:
while ##sqlstatus = 0
BEGIN
WAITFOR DELAY '00:00:05'
SELECT * FROM DBA.AlarmHistory WHERE AlarmHistoryID = #codigo
END
BEGIN
FETCH NEXT alarm_history_cur INTO #codigo
END
Try this:
while ##sqlstatus = 0
BEGIN
WAITFOR DELAY '00:00:05'
SELECT * FROM DBA.AlarmHistory WHERE AlarmHistoryID = #codigo
FETCH NEXT alarm_history_cur INTO #codigo
END
is there anyway to breakline and continue on next line in RaiseError?
<br/> and /n aren't working
Below is my code:
BEGIN
BEGIN TRY
SELECT 16/0
END TRY
BEGIN CATCH
WHILE(#Count != 0)
BEGIN
SET #MaterialName = (SELECT Material FROM #T WHERE Quantity = 0 AND ID = #Count)
SET #MSG = 'Material %s was not offered.'
RAISERROR(#MSG,16,1,#MaterialName);
SET #Count = #Count - 1
END
END CATCH
END
I dont want to make changes in the data access layer, we only support web, not window app. I want each loop msg to be printed on next line using sql only.
Is it possible?
if you include the line break in the text it will work.
SET #MSG = 'Material %s was not offered.
'
Note that the end quote is on a new line.
I'm no pro in sql but I think this will help
Char(10)
Inserts a new line break a good guide about it is here: https://www.itsupportguides.com/knowledge-base/sql-server/sql-how-to-insert-new-lineline-break-in-string/
I've also seen \n used before but I don't know if that can be used in your circumstance
retry:
exec xxxxxxxxx
if #csvfilecount < 16
begin
waitfor delay '00:05:00'
goto retry
end
else
begin
send email
end
I like to use go to retry for 2 try only and then go to send email.
Not sure to how do this. Please help. Thanks
Can you use a while loop with a counter?
declare #counter as int
set #counter = 0
while #counter <= 2
begin
#counter = #counter + 1
-- your code here
-- update #csvfilecount
if #csvfilecount < 16
begin
waitfor delay '00:05:00'
end
else
begin
send email
-- do you want to BREAK here?
end
end
I have a stored procedure that has a loop based on a counter. When the counter becomes NULL the loop ends without any error. Why doesn't SQL Server at least display a warning or error message like other programming languages?
Here is a code sample which exhibits the problem:
DECLARE #MasterCount int = 0;
DECLARE #Count int; -- initialized to NULL by SQL Server
PRINT 'Starting'
IF (#MasterCount IS NULL)
PRINT '#MasterCount IS NULL';
ELSE
PRINT '#MasterCount ' + CAST(#MasterCount AS varchar(10))
IF (#Count IS NULL)
PRINT '#Count IS NULL';
WHILE (#MasterCount IS NOT NULL)
BEGIN
SET #MasterCount += #Count;
IF ##ERROR <> 0 PRINT 'Error occured!'
PRINT 'Loop #Count ' + CAST(#Count AS varchar(10))
SET #Count -= 1;
END
IF ##ERROR <> 0 PRINT 'Error occured!'
IF (#MasterCount IS NULL)
PRINT '#MasterCount IS NULL';
ELSE
PRINT '#MasterCount ' + CAST(#MasterCount AS varchar(10))
PRINT 'Ending'
Produces the following output:
Starting
#MasterCount 0
#Count IS NULL
#MasterCount IS NULL
Ending
It doesn't raise an error because this is defined, documented behaviour.
If you have two apples and you know the weight of only one then it makes sense that the weight of both of them added together is not known.
You can actually get a warning to appear if you slightly alter the formulation.
Instead of
SET #MasterCount += #Count;
You could use
SELECT #MasterCount = SUM(C)
FROM (VALUES(#Count),
(#MasterCount )) V(C);
In which case it gives
Warning: Null value is eliminated by an aggregate or other SET
operation.
This does change the semantics however. As the null value was entirely ignored you would end up with #MasterCount simply being assigned back its original value rather than being set to null in your scenario.
I want to use infinite WHILE loop in SQL Server 2005 and use BREAK keyword to exit from it on certain condition.
while true does not work, so I have to use while 1=1.
Is there a better way to organize infinite loop ?
I know that I can use goto, but while 1=1 begin ... end looks better structurally.
In addition to the WHILE 1 = 1 as the other answers suggest, I often add a "timeout" to my SQL "infintie" loops, as in the following example:
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
I found the above technique useful within a stored procedure that gets called from a long polling AJAX backend. Having the loop on the database-side frees the application from having to constantly hit the database to check for fresh data.
Using While 1 = 1 with a Break statement is the way to do it. There is no constant in T-SQL for TRUE or FALSE.
If you really have to use an infinite loop than using while 1=1 is the way I'd do it.
The question here is, isn't there some other way to avoid an infinite loop? These things just tend to go wrong ;)
you could use the snippet below to kick a sp after soem condition are rised. I assume that you ahev some sort of CurrentJobStatus table where all the jobs/sp keeps their status...
-- *** 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
*/
Note the code is flexibile you can add as many condition checks on the #FileNameSet table var
Mario