Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 带有百分号(%)的抛出会产生奇怪的错误消息_Sql Server_Tsql_Throw - Fatal编程技术网

Sql server 带有百分号(%)的抛出会产生奇怪的错误消息

Sql server 带有百分号(%)的抛出会产生奇怪的错误消息,sql-server,tsql,throw,Sql Server,Tsql,Throw,在SSMS1中执行以下T-SQL语句会给出一条错误消息,其中正好包含一个空格2: 但是,如果通过将%加倍来转义,则会收到预期的错误消息: 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以

在SSMS1中执行以下T-SQL语句会给出一条错误消息,其中正好包含一个空格2:

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

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以一种特殊的方式解释了%

  • 有人知道为什么吗
  • 还有其他“特殊”字符吗
  • 这有文件记录吗
  • 我在MS SQL Server 2012和2014下观察到了这种行为。我没有试过其他版本


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


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

    抛出状态的文档:

    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. 
    
    消息参数不接受printf样式的格式

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

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

    这将测试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. 
    
    DECLARE@errors表(CharNumber INT,CharValue CHAR(1),ErrorText NVARCHAR(4000));
    声明@i INT=0;
    WHILE(@i''按字符编号排序
    
    输出:

    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. 
    
    CharNumber CharValue ErrorText
    32 abc de
    33!abc!de
    37%abc%de
    46.abc.de
    48 0 abcde
    110N美国广播公司
    
    nde——这个答案可能很有趣:我猜它要么连接到formatmessage函数,要么是引入throw时raiserror遗留下来的东西。它看起来不像是故意的行为。@JodyT:但这没有真正意义,不是吗?它应该是formatmessage函数(在此上下文中未调用)执行(可能错误)那么,替换。其他一些有趣的尝试是
    %r
    %n
    。我有一篇关于这一点的博文,写了一半;感谢完成的动机。我完成后会发布一个链接。-仍在等待我在Microsoft的联系人提供一些见解,了解THROW在幕后到底做了什么。我听说了d从Microsoft返回,并更新了我的博客文章。从本质上说,这是由带有RAISERROR的部分共享代码路径引起的,您应该习惯这种行为。他们不会修复它,但他们已同意在抛出文档中添加注释,以指示%字符存在问题。是的,我知道“不接受printf样式的格式”,那么为什么它会在流行之后“接受”它呢?好吧,这一定是微软有意识地做出的设计选择。因为他们在文档中清楚地说明了“prinf格式”不接受。这可能是因为他们希望我们以不同的方式使用它,也可能是SQL Server的内部技术难题。但是,由于他们不接受它,他们必须清空消息(或抛出另一个错误,这可能会让人困惑)。如果他们写了“不支持”我原以为它会打印您的邮件。%%works之所以有效,是因为您告诉函数不使用“printf格式”,这应该被接受。那么为什么
    abc%de
    会产生
    abc de
    ?更一般地说:“不接受”可能意味着“忽略”或“错误”显然,THROW不会忽略它,有时返回一个空格字符串,有时返回另一个字符串来报告错误是一个非常奇怪的“设计选择”事实上,与使用NULL或空字符串或类似于指定的
    无效消息的内容相比,这似乎是一个错误。呵呵,您确实有一些优点。我们可能不得不将“不接受”解释为“如果您使用它,它可能会以某种方式失败”:我测试了0-255之间的所有字符,发现有六个字符不会返回空白:32(空格),33(!),37(%),46(.),48(0),110(n)。我将更新我的答案。