Monday, 10 August 2015

MSSQL - Immediately PRINT big messages - more then 8000 bytes (4000 unicode characters)

Transact-SQL function PRINT has two disadvatages:
- is limited for 8000 bytes - 8000 VARCHAR characters or 4000 NVARCHAR (unicode) characters
- does not send messages immediately to the client, usually user have to wait until the procedure is complete before seeing messages

We can use alternate method - the RAISERROR function, this function can send messages immediately, but is limited for 2047 characters.

There the stored procedure which send any messages immediately to client, also with length more then 2047 (or 8000) characters:
  1. CREATE PROCEDURE [dbo].[sp_print_big_message]
  2. @message NVARCHAR(MAX)
  3. AS BEGIN
  4.  
  5. -- SET NOCOUNT ON to prevent extra log messages
  6. SET NOCOUNT ON;
  7.  
  8. DECLARE
  9. @CRLF CHAR(2) = CHAR(13)+CHAR(10),
  10. @message_len INT = LEN(@message),
  11. @i INT,
  12. @part NVARCHAR(2000),
  13. @part_len INT;
  14.  
  15. IF @message_len <= 2000 BEGIN
  16. -- Message ist enough short
  17. RAISERROR (@message, 0,1) WITH NOWAIT;
  18. END ELSE BEGIN
  19. -- Message is too long
  20. SET @i = 1;
  21. WHILE @i < LEN(@message) BEGIN
  22. -- Split to parts end send them to client immediately
  23. SET @part = SUBSTRING(@message, @i, 2000);
  24. SET @part_len = 2000 - CHARINDEX(CHAR(10) + CHAR(13), REVERSE(@part)) - 1;
  25. SET @part = CASE @i
  26. WHEN 1
  27. THEN ''
  28. ELSE '/* CRLF ' + CAST(@i AS VARCHAR(20)) + ':'
  29. + CAST(@part_len AS VARCHAR(20)) + ' */' + @CRLF
  30. END
  31. + REPLACE(SUBSTRING(@message, @i, @part_len), '%', '%%');
  32. RAISERROR (@part, 0,1) WITH NOWAIT;
  33. SET @i = @i + @part_len + 2;
  34. END;
  35. END;
  36.  
  37. END;

Usage:
  1. -- Declare long message
  2. DECLARE @LongMessage NVARCHAR(MAX) = '';
  3. -- Fill message with test data
  4. DECLARE @i INT = 1;
  5. WHILE @i < 200 BEGIN
  6. SET @LongMessage = @LongMessage
  7. + CASE @i WHEN 1 THEN '' ELSE CHAR(13) + CHAR(10) END
  8. + CAST(@i AS VARCHAR(10))
  9. + '. Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
  10. SET @i = @i + 1;
  11. END;
  12.  
  13. -- Display length of generated message
  14. DECLARE @len INT = LEN(@LongMessage);
  15. RAISERROR('Message length: %i', 0, 1, @len);
  16.  
  17. -- Use SP to print long message
  18. EXEC sp_print_big_message @LongMessage;

No comments:

Post a Comment

Note: only a member of this blog may post a comment.