Хранимая процедура усекает переменную с помощью функции CONCAT сразу после включения параметра в оператор CONCAT - PullRequest
3 голосов
/ 11 июня 2019

Я пытаюсь передать параметр [например, @X nvarchar(MAX)] в переменную [например, @message nvarchar(MAX)] внутри хранимой процедуры.Переменная использует CONCAT для объединения строковых значений и переменных, и в конечном итоге она становится как телом электронной почты, отправляемой с SQL Server, так и значением столбца в таблице.По какой-то причине, когда я устанавливаю переменную, CONCAT заканчивается сразу после того, как ей передан первый параметр.

Еще одна деталь в том, что она работает нормально, когда я запускаю хранимую процедуру вручную.В этом конкретном случае эта проблема появляется только тогда, когда хранимая процедура вызывается из внешнего приложения.

Я безуспешно пробовал следующие варианты:

  • Установка переменной без CONCAT с использованием тройных одинарных кавычек
  • Передача параметра в отдельную переменную допеременная @message
  • Установка параметра для разрешения ВЫХОДА исходному приложению (даже если исходное приложение не требует ВЫХОДА)
ALTER PROCEDURE [dbo].[TEST] 
    (@param NVARCHAR(MAX))
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @message NVARCHAR(MAX),
            @email NVARCHAR(MAX)

    SET @email = 'test@test.com'

    SET @message = CONCAT ('Some text.',CHAR(13) + CHAR(10)
        ,'Value of param: ', @param, CHAR(13) + CHAR(10)
        ,'Some more text.');

    INSERT INTO [database].[dbo].[table] ([Message], [Param])
    VALUES (@message, @param);

    EXEC msdb.dbo.sp_send_dbmail
            @recipients = @email,
            @body = @message,
            @subject = 'SUBJECT OF EMAIL',
            @profile_name = 'profile_name';

Письмо отправлено нормальнои сообщение сохраняется в [table], но в обоих случаях переменная @message заканчивается сразу после того, как ей передано @param.

Например, если бы значение @param было «paramTest», @message выглядело бы так:

Some text.
Value of param: paramTest

Кроме того, параметр отлично сохраняется в [table],поэтому я знаю, что параметр имеет допустимое значение.

Есть ли способ захвата и просмотра точных данных, которые передаются из внешнего приложения в хранимую процедуру?Мне было интересно, если он включает в себя какой-то специальный символ (ы) в конце данных, когда он назначает параметр.

Ответы [ 2 ]

1 голос
/ 12 июня 2019

Я предлагаю посмотреть на Сообщение как последовательность байтов. например:

select *, cast([Message] as varbinary(max)) as DataAsBytes 
from [database].[dbo].[table]

Это позволяет видеть байтовое представление всех символов.

Пример:

DECLARE @param NVARCHAR(MAX) = 'b' + CHAR(0); 
DECLARE @message NVARCHAR(MAX)
SET @message = CONCAT ('a', @param, 'c');
select  @message as RawMessage, CAST(@message as varbinary(max)) as MessageAsBytes, LEN(@message) as RawMessageLength, DATALENGTH(CAST(@message as varbinary(max))) as NumBytes

При запуске в SSMS показывает RawMessage как: ab, поэтому символ CHAR (0) заставил SSMS не отображать следующее «c». MessageAsBytes отображается как: 0x6100620000006300 где: «a» = 6100, «b» = 6200, CHAR (0) = 0000, «c» = 6300. Таким образом, вы можете «увидеть» символ CHAR (0).

Справочная информация о кодировке Unicode:

https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses

1 голос
/ 11 июня 2019

Проверьте, что передается в качестве значения параметра.

Демо

DECLARE @param NVARCHAR(MAX) = 'abc msg' + CHAR(0); -- all the rest is lost

DECLARE @message NVARCHAR(MAX)

SET @message = CONCAT ('Some text.',CHAR(13) + CHAR(10)
    ,'Value of param: ', @param, CHAR(13) + CHAR(10)
    ,'Some more text.');

select @message;

Возвращает

Some text.
Value of param: abc msg
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...