I'd like to clear my queue in SQL Server Management Studio, but I don't want to delete the whole queue just the content in the queue (the messages).
-
12Do you want to clear all messages in all the queues in a database? The you should use `ALTER DATABASE ... SET NEW_BROKER WITH ROLLBACK IMMEDIATE;` – Remus Rusanu Jun 01 '12 at 05:05
6 Answers
Just combining the two previous answers (by Ben and Jānis) for clarity. This worked for me:
declare @c uniqueidentifier
while(1=1)
begin
select top 1 @c = conversation_handle from dbo.queuename
if (@@ROWCOUNT = 0)
break
end conversation @c with cleanup
end

- 775
- 1
- 6
- 14
-
1Another good thing with this answer is that using `SELECT` instead of `RECEIVE` makes it possible to cleanup the queue even if it's disabled. – jgauffin Feb 27 '15 at 08:04
-
2Worked for me when I changed the (@@ROWCOUNT=0) check with a (@c is null) condition. Thanks – earthling42 May 15 '15 at 11:27
Something like this should work:
while(1=1)
begin
waitfor (
receive top(1)
conversation_group_id
from dbo.yourQueue
), timeout 1000;
if (@@rowcount = 0)
break;
end

- 41,996
- 18
- 86
- 115

- 31,080
- 4
- 45
- 68
-
If you are using a [messaging pattern where the receiving endpoint cleans up the conversation](http://rusanu.com/2014/03/31/how-to-prevent-conversation-endpoint-leaks/), you may need to give special treatment to certain received messages (e.g. call END CONVERSATION on any messages whose type is EndOfStream). – Joey Adams Jul 25 '16 at 17:18
I would use end conversation (that will also remove all related messages from all queues) using statement:
End Conversation @c With CleanUp
if you just receive message, then you leave conversation open. End Conversation With CleanUp is for specific situations only.
If you are using SQL Server (starting with 2008) you can use RECEIVE
WHILE (0=0)
BEGIN
RECEIVE * FROM dbo.YourQueue;
IF (@@ROWCOUNT = 0) BREAK;
END

- 25,246
- 15
- 42
- 71

- 1,144
- 1
- 12
- 19
I had the same issue as the original poster, but I was needing to clear queues with millions of messages (failed message queues, especially in non production environments that had not been checked for years).
The solution above would have worked, but was processing at less than 10 messages per minute. By doing it in batches I was getting 30000 messages per minute.
The only noteworthy item in the code is where validation = 'N'
. This limits the conversation handles to the real messages. There is a duplicate conversation handle for the response/error which gets removed by the end conversation
. Without this clause the script would still work, but generate a lot of errors in the output.
declare @conversationBatch table (convH uniqueidentifier)
declare @conversationHandle uniqueidentifier
declare convCursor cursor for
select convH from @conversationBatch
insert into @conversationBatch
select top 1000 conversation_handle
from dbo.queuename WITH (NOLOCK)
where validation = 'N'
while @@rowcount > 0
begin
open convCursor
fetch next from convCursor into @conversationHandle
while @@FETCH_STATUS = 0
begin
end conversation @conversationHandle with cleanup
fetch next from convCursor into @conversationHandle
end
close convCursor
delete from @conversationBatch
insert into @conversationBatch
select top 1000 conversation_handle
from dbo.queuename WITH (NOLOCK)
where validation = 'N'
end
deallocate convCursor

- 11
- 1
while(1=1)
begin
waitfor (
receive top(1)
conversation_group_id
from kartokumaqueue2), timeout 1000;
if(@@ROWCOUNT = 0) break;
end
-
3This answer while potentially correct lacks context and would be improved by a code commentary stating why this answer works. See http://stackoverflow.com/help/how-to-answer – Jonnus Dec 10 '15 at 12:18