Функция замены T-SQL, пропущенная в некоторых случаях, с помощью nvarchar (max) - PullRequest
0 голосов
/ 05 апреля 2019

С учетом следующего кода T-SQL:

declare @lf char(1) set @lf = char(10);
declare @cr char(1) set @cr = char(13);

select  replace(isnull(note,''), @cr+@lf,@lf)  from T

Существуют ли обстоятельства, при которых не каждое вхождение @ cr + @ lf в столбце note будет заменено на @lf?

Я пытаюсь разобраться в ситуации, когда это действительно происходит.

Столбец note определяется как nvarchar(max). документация гласит:

Если string_expression не относится к типу varchar (max) или nvarchar (max), REPLACE усекает возвращаемое значение до 8000 байт. Чтобы возвращать значения, превышающие 8000 байт, выражение string_expression должно быть явно приведено к типу данных большого значения.

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

Я подумал, что, возможно, функция isnull не возвращает nvarchar(max), но в документации говорится, что она возвращает тип тестируемого значения:

... Типы возврата
Возвращает тот же тип, что и check_expression.

И возвращаемое значение не усекается; просто некоторые пары crlf упускаются из виду.

Должно быть, я что-то упускаю.

declare @t table( notes nvarchar(max));

insert @t(notes)
values
(
'From: kkkkkkk@aaaaaaaaa.com <kkkkkkk@aaaaaaaaa.com> 
Sent: Monday, May 00, 0008 00:55 PM
To: Jan Zzzz <sZzzz@dddd.dd.com>
Subject: RE: [Secure Message] aaaaaaaaa ABC ddddddddddddd--XXXXX-X

Hi Jan, 

The ddddddddddddd is valid for one year.  I have attached the Zzzzzzz Rrrrrrrr which you will find behind the  blank cover page and ddddddddddddd form.  Please let me know if this is what you need.  

Best Regards, 

Yyyyyy 

Kkkkkkkk Kkkkkk, ABC, DEF
ABC Mmmmmmmm
P 800.007.0000 ext 000 | F 600.000.0070 



Electronic mail is not considered to be a secure form of communication for Protected Health Information. If you are concerned about privacy, please call aaaaaaaaa directly at 0-800-007-0000. If you would like to review our privacy policy, it can be found on our website: www.ddddddddddddd.com.

This email, including any attached files, may contain confidential and privileged information for the sole use of the intended recipient(s). Any review, use, distribution or disclosure by others is strictly prohibited. If you are not the addressee indicated in this message (or authorized to receive information for the recipient), please contact the sender by reply e-mail and delete all copies of this message (including any attachments).

From: Jan Zzzz <sZzzz@dddd.dd.com> 
Sent: Monday, May 00, 0008 8:56 AM
To: Kkkkkkkk Kkkkkk <kkkkkkk@aaaaaaaaa.com>; Jan Zzzz <sZzzz@dddd.dd.com>
Subject: Re: [Secure Message] aaaaaaaaa ABC ddddddddddddd--XXXXX-X

Hi, this expired, I need a copy of the aaaaaaa aaaa so I can submit my aaaaaaa aaa aaaaaaaa. Thank you. SZzzz

On 0/00/0008 8:00 AM, Jan Zzzz wrote:
Thank you for the dddddddd, I am mmmmmmm mmm today.

On 0/0/0008 6:05 PM, Kkkkkkkk Kkkkkk wrote:

[Secure Message] aaaaaaaaa ABC ddddddddddddd--XXXXX-X    

Kkkkkkkk Kkkkkk has sent you a secure message.
Subject:    aaaaaaaaa ABC ddddddddddddd--XXXXX-X
From:   Kkkkkkkk Kkkkkk <kkkkkkk@aaaaaaaaa.com>

To: Jan Zzzz <sZzzz@dddd.dd.com>

Expires:    May 00, 0008

View Secure Message 



Note: If you have any concerns about the authenticity of this message please contact the original sender directly.'   
)

select notes from @t;
select replace(notes, char(13),'') from @t;

Redacted Record Shown in Notepad++

Ответы [ 4 ]

1 голос
/ 05 апреля 2019

если это просто одна строка, это должно сделать это, удалить их все и вернуть обратно

set @note =  replace(replace(isnull(@note,''),@cr,''),@lf,'')+@lf . //or whatever line endings you want

если его многострочный код попытается сделать что-то вроде этого

declare @note as nvarchar(max)
declare @lf char(1) set @lf = char(10);
declare @cr char(1) set @cr = char(13);

set @note = 'A'+char(10)+char(13)+char(10)+char(13)+char(10)+char(13)+char(10)+char(13)+'A'+char(10)+char(13)

set @note = replace(isnull(@note,''),@cr,'')

--not sure if you want to keep all the user lf's but if you want only one try this?
if (patindex(isnull(@note,''),@lf+@lf) >= 0)
begin
set @note = replace(isnull(@note,''),@lf+@lf,@lf)
end 

select @note
select cast(@note as VARBINARY(100))
select len(@note)
1 голос
/ 05 апреля 2019

Вы остались бы с @cr+@lf в SELECT, если @cr+@cr+@lf встречается в note, если только вам не нужно @cr, когда это происходит само по себе, вам, вероятно, лучше сделать:

declare @cr char(1) set @cr = char(13);

select  replace(isnull(note,''), @cr,'')  from T
0 голосов
/ 06 апреля 2019

Полагаю, я нашел частичный ответ.В SSMS:

Tools->Options->SQL Server->Results to Grid

[ x ]  Retain CR/LF on copy or save

фактически восстановит CR, который был удален вашим вызовом replace().

0 голосов
/ 05 апреля 2019

Каждое обстоятельство будет заменено, но вы можете создавать некоторые CrLfs с помощью замены.Пожалуйста, посмотрите пример ниже и как его смягчить.

DECLARE @Cr CHAR(1)=CHAR(13)
DECLARE @Lf CHAR(1)=CHAR(10)
DECLARE @CrLf CHAR(2)=CHAR(13)+CHAR(10)
DECLARE @NoteTbl TABLE(Note NVARCHAR(MAX))
INSERT INTO @NoteTbl (Note) SELECT @Cr + @CrLf

--example can result in CrLF being created
SELECT [NewNote],LEN([NewNote]) FROM (SELECT replace(isnull(note,''), @CrLf,@lf) AS [NewNote] FROM @NoteTbl) AS a

--Option 1: Replace all Cr with nothing; this is effectively the same as replacing CrLf with Lf
SELECT [NewNote],LEN([NewNote]) FROM (SELECT replace(isnull(note,''), @Cr,'') AS [NewNote] FROM @NoteTbl) AS a

--Option 2: insert the notes into a table and loop until CrLf is gone, this might be useful if you need to do multiple different  data scrubs
DECLARE @NotesCleaned TABLE(Note NVARCHAR(MAX))
INSERT INTO @NotesCleaned (Note) SELECT Note FROM @NoteTbl
WHILE EXISTS(
    SELECT * FROM @NotesCleaned WHERE Note Like '%' + @CrLf + '%'
)
    BEGIN
        UPDATE @NotesCleaned SET Note=replace(isnull(note,''), @CrLf,@lf)
    END

SELECT Note,LEN(Note) FROM @NotesCleaned 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...