2015-02-12 3 views
2

Отработка следующее заявление T-SQL в SSMS выдает сообщение об ошибке, которое содержит ровно один пробел :БРОСОК с знаком процента (%) производит странное сообщение об ошибке

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. Является ли это документированным где угодно?

Я наблюдал это поведение в MS SQL Server 2012 и 2014 году. Я не пробовал другие версии.


Я также попытался ADO.NET, с аналогичными результатами.

Это не ясно видно здесь, но я перепроверил: сообщение об ошибке, действительно, не является пустой строкой, но ровно один пробел.

+0

Звучит как параметры форматирования printf,% s,% d и т. Д.Не похоже, что их можно использовать в любом случае :( –

+0

Вы можете использовать их с помощью функции FORMATMESSAGE. Https://msdn.microsoft.com/en-us/library/ee677615.aspx. Я предполагаю, что это является причиной того, почему% показывает это поведение. – JodyT

+1

Этот ответ может быть интересен: http://dba.stackexchange.com/a/74249/24734 Я предполагаю, что он либо подключен к функции formatmessage, либо что-то осталось – jpw

ответ

1

Документация Бросьте состояния:

Параметр сообщений не принимает Printf стиль форматирования

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

Это должно объяснить, почему он не может напечатать текст.

Существует более подробная информация о Printf стиле форматировании в SQL Server в документации 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 

Выход:

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, это немного смешно.

+0

Yup Я знаю, что «не принимает формат форматирования в формате printf», так почему он «принимает» его после моды? –

+0

Ну, это должен быть сознательный выбор дизайна, сделанный Microsoft. Поскольку они так четко излагают это в документации, что «форматирование prinf» не принимается. Возможно, это потому, что они хотят, чтобы мы использовали его по-другому или, возможно, это внутренняя техническая проблема в SQL Server. Но, так как они не принимают его, они должны вычеркнуть сообщение (или выбросить еще одну ошибку, что, вероятно, будет путать). Если бы они писали «не поддерживают», я бы ожидал, что он напечатает ваше сообщение. Причина, по которой работает %%, заключается в том, что вы указываете, что функция не использует «форматирование печати», которая должна быть принята. –

+0

Тогда почему 'abc% de' производит' abc de'? –

Смежные вопросы