ChatGPT解决这个技术问题 Extra ChatGPT

替换 TSQL 中的换行符

我想替换(或删除)TSQL 字符串中的换行符。有任何想法吗?

显而易见的

REPLACE(@string, CHAR(13), '')

就是不会做...


R
RBarryYoung

实际上,SQL 命令或脚本字符串中的新行可以是 CR、LF 或 CR+LF 中的任何一个。为了得到它们,你需要这样的东西:

SELECT REPLACE(REPLACE(@str, CHAR(13), ''), CHAR(10), '')

@NielsBrinch 只要这是字符串中唯一的换行符类型,它就可以正常工作。但 SQL Server 确实支持所有三种类型。事实上,如果您曾经提取过所有系统存储过程和脚本视图,您可以找到 Microsoft 自己使用的所有三个实例。
在我进行此更改复制并粘贴列数据之前,这对我有用 b/c 将使光标位于文本末尾并带有两个空格。在进行此更改后,复制并粘贴到记事本中时,光标直接位于文本的末尾。它在我们的前端 GUI 中给我 b/c 造成了一个问题,新行字符出现了。
如果列数据类型是文本,那么您需要先转换为 nvarchar,然后替换 SELECT REPLACE(REPLACE(cast(@str as nvarchar(max)), CHAR(13), ''), CHAR(10), '')
@Slint 是的,好点。实际上,要从客户端代码中使用它,您应该添加一个列名。虽然确实很多时候您可以使用 .columns[0] 来代替。
对于我使用的 Oracle 版本,语句是 CHR,而不是 CHAR。以防万一有人试图从 Oracle 进行调试。否则,其他一切都适用。
M
Mitch Wheat
REPLACE(@string, CHAR(13) + CHAR(10), '')

这是我首先尝试的方法,但它对所有数据都不能可靠地工作。 @RBarryYoung 就在上面。
谢谢,我必须稍微修改一下才能为我工作,在我的情况下:replace(REPLACE(@string, CHAR(13), ''),CHAR(10), '')
谢谢,这有效,最佳答案由于某种原因没有
N
NateJ

我可能迟到了一年,但我每天都在处理查询和 MS-SQL,我厌倦了内置函数 LTRIM() 和 RTRIM()(并且总是不得不一起调用它们),并且没有捕捉到最后有换行符的“脏”数据,所以我决定是时候实现更好的 TRIM 函数了。我会欢迎同行的反馈!

免责声明:这实际上删除(替换为单个空格)扩展形式的空格(制表符、换行符、回车符等),因此从我的原始答案中将其重命名为“CleanAndTrim”。这里的想法是您的字符串不需要在其中包含这些额外的特殊空白字符,因此如果它们没有出现在头部/尾部,则应该将它们替换为纯空格。如果您故意将此类字符存储在字符串中(例如,您将要运行它的数据列),请不要这样做!改进此函数或编写您自己的函数,从字面上删除字符串端点中的这些字符,而不是从“正文”中删除。

好的,现在免责声明已更新,这是代码。

-- =============================================
-- Description: TRIMs a string 'for real' - removes standard whitespace from ends,
-- and replaces ASCII-char's 9-13, which are tab, line-feed, vert tab,
-- form-feed, & carriage-return (respectively), with a whitespace
-- (and then trims that off if it's still at the beginning or end, of course).
-- =============================================
CREATE FUNCTION [fn_CleanAndTrim] (
       @Str nvarchar(max)
)
RETURNS nvarchar(max) AS
BEGIN
       DECLARE @Result nvarchar(max)

       SET @Result = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
              LTRIM(RTRIM(@Str)), CHAR(9), ' '), CHAR(10), ' '), CHAR(11), ' '), CHAR(12), ' '), CHAR(13), ' ')))

       RETURN @Result
END

干杯!

另一个免责声明:您的典型 Windows 换行符是 CR+LF,因此如果您的字符串包含这些,您最终会用“双”空格替换它们。

2016 年更新:新版本让您可以选择用您选择的其他字符替换这些特殊空白字符!这还包括评论和 Windows CR+LF 配对的解决方法,即用单个替换替换特定的字符对。

IF OBJECT_ID('dbo.fn_CleanAndTrim') IS NULL
    EXEC ('CREATE FUNCTION dbo.fn_CleanAndTrim () RETURNS INT AS BEGIN RETURN 0 END')
GO
-- =============================================
-- Author: Nate Johnson
-- Source: http://stackoverflow.com/posts/24068265
-- Description: TRIMs a string 'for real' - removes standard whitespace from ends,
-- and replaces ASCII-char's 9-13, which are tab, line-feed, vert tab, form-feed,
-- & carriage-return (respectively), with a whitespace or specified character(s).
-- Option "@PurgeReplaceCharsAtEnds" determines whether or not to remove extra head/tail
-- replacement-chars from the string after doing the initial replacements.
-- This is only truly useful if you're replacing the special-chars with something
-- **OTHER** than a space, because plain LTRIM/RTRIM will have already removed those.
-- =============================================
ALTER FUNCTION dbo.[fn_CleanAndTrim] (
    @Str NVARCHAR(MAX)
    , @ReplaceTabWith NVARCHAR(5) = ' '
    , @ReplaceNewlineWith NVARCHAR(5) = ' '
    , @PurgeReplaceCharsAtEnds BIT = 1
)
RETURNS NVARCHAR(MAX) AS
BEGIN
    DECLARE @Result NVARCHAR(MAX)

    --The main work (trim & initial replacements)
    SET @Result = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
        LTRIM(RTRIM(@Str))  --Basic trim
        , NCHAR(9), @ReplaceTabWith), NCHAR(11), @ReplaceTabWith)   --Replace tab & vertical-tab
        , (NCHAR(13) + NCHAR(10)), @ReplaceNewlineWith) --Replace "Windows" linebreak (CR+LF)
        , NCHAR(10), @ReplaceNewlineWith), NCHAR(12), @ReplaceNewlineWith), NCHAR(13), @ReplaceNewlineWith)))   --Replace other newlines

    --If asked to trim replacement-char's from the ends & they're not both whitespaces
    IF (@PurgeReplaceCharsAtEnds = 1 AND NOT (@ReplaceTabWith = N' ' AND @ReplaceNewlineWith = N' '))
    BEGIN
        --Purge from head of string (beginning)
        WHILE (LEFT(@Result, DATALENGTH(@ReplaceTabWith)/2) = @ReplaceTabWith)
            SET @Result = SUBSTRING(@Result, DATALENGTH(@ReplaceTabWith)/2 + 1, DATALENGTH(@Result)/2)

        WHILE (LEFT(@Result, DATALENGTH(@ReplaceNewlineWith)/2) = @ReplaceNewlineWith)
            SET @Result = SUBSTRING(@Result, DATALENGTH(@ReplaceNewlineWith)/2 + 1, DATALENGTH(@Result)/2)

        --Purge from tail of string (end)
        WHILE (RIGHT(@Result, DATALENGTH(@ReplaceTabWith)/2) = @ReplaceTabWith)
            SET @Result = SUBSTRING(@Result, 1, DATALENGTH(@Result)/2 - DATALENGTH(@ReplaceTabWith)/2)

        WHILE (RIGHT(@Result, DATALENGTH(@ReplaceNewlineWith)/2) = @ReplaceNewlineWith)
            SET @Result = SUBSTRING(@Result, 1, DATALENGTH(@Result)/2 - DATALENGTH(@ReplaceNewlineWith)/2)
    END

    RETURN @Result
END
GO

过去的用户,请注意更改和免责声明——对于最初关于使用和目的的假设,我深表歉意。
新的更新!可以在这里找到测试用例:sqlfiddle.com/#!6/585a2/1/0 -- SQLFiddle 似乎在我实际运行测试用例时卡住了,所以相反,我构建了一个“测试用例查询构建器”表 &给你 9 条语句复制粘贴到你自己的 SSMS 窗口中运行(当然是在创建模式之后,即函数和 TestStrings 表)。
Microsoft 非常喜欢您的 TRIM 功能,他们将其包含在 SQL Server 2017 中;)
不,你没有迟到:),谢谢你的超级 SQL 功能。我有一个标签和一个新行,这有效
C
Cerebrus

T-SQL 中的换行由 CHAR(13) & CHAR(10) 表示(回车 + 换行)。因此,您可以使用要替换换行符的文本创建一个 REPLACE 语句。

REPLACE(MyField, CHAR(13) + CHAR(10), 'something else')

这与公认的答案不太一样;接受的答案会删除 {13, 10} 的任何组合。这只会删除 13 和 10 的特定组合。它不会对 windows 行结尾产生差异,但这里会遗漏其他编码。
D
David Cary

要执行大多数人想要的操作,请创建一个不是实际换行符的占位符。然后,您实际上可以结合以下方法:

REPLACE(REPLACE(REPLACE(MyField, CHAR(13) + CHAR(10), 'something else'), CHAR(13), 'something else'), CHAR(10), 'something else')

这样您只需更换一次。方法:

REPLACE(REPLACE(MyField, CHAR(13), ''), CHAR(10), '')

如果您只想摆脱 CRLF 字符,但如果您想要一个占位符,例如

<br/>

什么的,那么第一种方法更准确一点。


我所做的不是 '' 我用空格替换了换行符。如果你有 CR 或 LF,那很好,你只会得到一个空格,但如果你有 CRLF,那么你会得到两个。所以我用另一个空格替换了两个空格:REPLACE(REPLACE(REPLACE(ClientName, CHAR(13), ' '), CHAR(10), ' '),' ',' ')
a
akd

如果您的列数据类型是“文本”,那么您将收到一条错误消息

消息 8116,级别 16,状态 1,第 2 行 参数数据类型文本对于替换函数的参数 1 无效。

在这种情况下,您需要将文本转换为 nvarchar 然后替换

SELECT REPLACE(REPLACE(cast(@str as nvarchar(max)), CHAR(13), ''), CHAR(10), '')

好的,这看起来很棒。现在,如果我要替换的是“!crlf”,是的,那是!crlf 之后的空格字符。问题是这发生在字符串的中间,我可以逃脱吗: SELECT REPLACE(REPLACE(cast(@str as nvarchar(MAX)), CHAR(33), CHAR(13), CHAR(10), CHAR (32), '') 还是我写错了?字符串看起来像这样:允许远程攻击者绕过沙盒保护机制并通过精心制作的网站获取权限 t! 使用 Internet Explorer 访问,关注word t! hat...那是我的麻烦点。
R
Rm558

在 SQL Server 2017 &稍后,使用 Trim

Select Trim(char(10) + char(13) from @str)

它在开始和结束时修剪,而不是在中间 \r 和 \n 的顺序无关紧要

我用它来修剪文件名的特殊字符

Select Trim(char(10) + char(13) + ' *<>' from @fileName)

D
Dmitry Kuzminov

有时

REPLACE(myString, CHAR(13) + CHAR(10), ' ')

不会工作。在这种情况下,请使用以下代码段:

REPLACE(REPLACE(myString, CHAR(13),''), CHAR(10), ' ')

D
DaveX

如果您遇到只想删除尾随字符的问题,可以尝试以下操作:

WHILE EXISTS
(SELECT * FROM @ReportSet WHERE
    ASCII(right(addr_3,1)) = 10
    OR ASCII(right(addr_3,1)) = 13
    OR ASCII(right(addr_3,1)) = 32)
BEGIN
    UPDATE @ReportSet
    SET addr_3 = LEFT(addr_3,LEN(addr_3)-1)
    WHERE 
    ASCII(right(addr_3,1)) = 10
    OR ASCII(right(addr_3,1)) = 13
    OR ASCII(right(addr_3,1)) = 32
END

这解决了我遇到的地址问题,其中程序创建了具有固定行数的字段,即使这些行是空的。为了节省 SSRS 报告中的空间,我将它们删减了。


R
Rohan

如果您有使用 sp_helptext 的打开过程,则只需复制新 sql 查询中的所有文本并按 ctrl+h 按钮使用正则表达式替换并将 ^\n 放入查找字段替换为空白。有关更多详细信息,请查看图片。enter image description here


G
Grigory Kislin

@Cerebrus 解决方案:不支持字符串“+”的 H2。所以:

REPLACE(string, CHAR(13) || CHAR(10), 'replacementString')

a
andrew pate

我想清理列的内容以生成 csv 文件,所以想去掉 varchar 中的逗号 (,) 以及换行符和回车符。

我还想最终使用生成的 csv 创建另一个脚本(将行插入另一个数据库),因此还需要将 varchar 中的 ' 更改为 '' 所以最终得到了这个......

REPLACE(REPLACE(REPLACE(REPLACE(ErrorMessage, CHAR(13), ''), CHAR(10), ''),',',''),'''','''''')

可能还有其他更好的方法,但它完成了工作。


S
Simon.S.A.

上面/之前发布的答案被报告为替换 CHAR(13)CHAR(10) 回车:

REPLACE(REPLACE(REPLACE(MyField, CHAR(13) + CHAR(10), 'something else'), CHAR(13), 'something else'), CHAR(10), 'something else')

永远不会到达代码的 REPLACE(MyField, CHAR(13) + CHAR(10), 'something else') 部分,并将返回不需要的结果:

'something else''something else'

而不是一个单一的预期结果:

'something else'

这将需要这样重写 REPLACE 脚本:

REPLACE(REPLACE(REPLACE(MyField, CHAR(10), 'something else'), CHAR(13), 'something else'), CHAR(13) + CHAR(10), 'something else')

由于流程首先测试第一个/最左的 REPLACE 语句,然后在失败时将继续测试下一个 REPLACE 语句。