T-SQL替换函数使用nvarchar(max)缺少某些情况

时间:2019-04-05 14:40:52

标签: tsql replace sql-server-2012

给出以下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

在某些情况下,note列中不是所有出现的@ cr + @ lf都将被@lf代替吗?

我正在尝试解决确实发生这种情况的情况。

note列定义为nvarchar(max)documentation说:

  

如果string_expression不是varchar(max)或nvarchar(max)类型,则REPLACE会将返回值截断为8,000个字节。要返回大于8,000个字节的值,必须将string_expression显式转换为大值数据类型。

如果我正确理解,则无需进行强制转换,因为note已经具有适当的数据类型,允许返回值大于8000个字节。

我认为也许isnull函数没有返回nvarchar(max),但是documentation说它返回了要测试的值的类型:

  

...返回类型
  返回与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 个答案:

答案 0 :(得分:1)

如果@cr+@lf中出现SELECT,您将在@cr+@cr+@lf中留有note,除非您自己需要@cr时需要declare @cr char(1) set @cr = char(13); select replace(isnull(note,''), @cr,'') from T 做起来可能更好:

decimal

答案 1 :(得分:1)

如果只是一行,则应该这样做,将其全部删除并放回

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)

答案 2 :(得分:0)

每种情况都将被替换,但是您可能会通过替换创建一些CrLf。请参见下面的示例以及如何减轻它。

// JS event
button.on('click', function( this ){
if ( !this.hasAttribute( 'data-noclick' ) ) {
    // Here my AJAX calling
    this.setAttribute( 'data-noclick', 'true' );
    $.post(callMyBackend, {
       foo: bar // Parameters
    }, function (responseText) {
       // Here goes more stuff...
    this.removeAttribute( 'data-noclick' );
    });
});

答案 3 :(得分:0)

我相信我可能已经找到了部分答案。在SSMS中:

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

[ x ]  Retain CR/LF on copy or save

实际上会恢复您对replace()的呼叫已删除的CR。