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

Bra*_*vic 5 t-sql sql-server throw

在 SSMS 1中执行以下 T-SQL 语句会给出一条仅包含一个空格2 的错误消息:

THROW 50000, 'abc%de', 0;

Msg 50000, Level 16, State 0, Line 1
Run Code Online (Sandbox Code Playgroud)

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

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

Msg 50000, Level 16, State 0, Line 1
abc%de
Run Code Online (Sandbox Code Playgroud)

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

THROW 50000, 'abc% de', 0;

Msg 50000, Level 16, State 0, Line 1
abc de
Run Code Online (Sandbox Code Playgroud)

由于某种原因,THROW 以特殊方式解释 %。

  1. 有人知道为什么吗?
  2. 还有其他“特殊”角色吗?
  3. 这有记录在任何地方吗?

我在 MS SQL Server 2012 和 2014 下观察到了这种行为。我没有尝试过其他版本。


1我也尝试过 ADO.NET,具有相同的结果。

2这里看不清楚,但我仔细检查过:错误消息确实不是空字符串,而是恰好有一个空格。

Jar*_*eth 1

THROW 的文档指出:

message 参数不接受 printf 样式格式

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

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

有关 SQL Server 中 printf 样式格式的更多信息,请参阅 RAISERROR 文档 (msg_str):

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
Run Code Online (Sandbox Code Playgroud)

输出:

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. 
Run Code Online (Sandbox Code Playgroud)

%n = 新行,但它不删除 n,这有点有趣。