带有百分号(%)的THROW会产生奇怪的错误消息

时间:2015-02-12 20:37:29

标签: sql-server tsql throw

在SSMS 1 中执行以下T-SQL语句会出现一条错误消息,其中只包含一个空格 2

THROW 50000, 'abc%de', 0;

Msg 50000, Level 16, State 0, Line 1

但是,如果我通过加倍来逃避%,我会收到预期的错误消息:

THROW 50000, 'abc%%de', 0;

Msg 50000, Level 16, State 0, Line 1
abc%de

我还注意到,当%后跟空格时,它只是被跳过:

THROW 50000, 'abc% de', 0;

Msg 50000, Level 16, State 0, Line 1
abc de

出于某种原因,THROW正在以特殊的方式解释%。

  1. 有人知道为什么吗?
  2. 还有其他特别的"字符?
  3. 是否记录在任何地方?
  4. 我在MS SQL Server 2012和2014下观察到了这种行为。我还没有尝试过其他版本。


    1 我也尝试过ADO.NET,效果相同。

    2 这里显而易见,但我已经仔细检查过:错误信息确实不是空字符串,而只是一个空格。

1 个答案:

答案 0 :(得分:1)

THROW的文档说明:

  

message参数不接受printf样式格式

https://msdn.microsoft.com/en-us/library/ee677615.aspx

这应该解释为什么它无法打印文本。

在RAISERROR文档(msg_str)中有关于SQL Server中printf样式格式化的更多信息:

https://msdn.microsoft.com/en-us/library/ms178592.aspx

这将测试0-255之间的字符,以检查它们是否会返回某些内容:

DECLARE @errors TABLE(CharNumber INT, CharValue CHAR(1), ErrorText NVARCHAR(4000));
DECLARE @i INT = 0;

WHILE (@i <= 255)
BEGIN
    DECLARE @c CHAR(1) = CHAR(@i);

    DECLARE @m VARCHAR(50) = 'abc%' + @c + 'de';
    BEGIN TRY
        THROW 50000, @m, 0;
    END TRY
    BEGIN CATCH
        INSERT INTO @errors
        SELECT @i, @c, ERROR_MESSAGE();
    END CATCH

    SET @i = @i + 1;
END

SELECT * FROM @errors WHERE ErrorText > '' ORDER BY CharNumber

<强>输出:

CharNumber  CharValue   ErrorText
32      abc de
33  !   abc!de
37  %   abc%de
46  .   abc.de
48  0   abcde
110 n   abc
nde --<- This adds a new line. 

%n =新行,但它不会删除n,这有点滑稽。