【问题标题】:line breaks lost in sql serversql server 中的换行符丢失
【发布时间】:2011-12-05 15:53:02
【问题描述】:

我正在将错误信息输入到我的数据库中的 ErrorLog 表中。我有一个实用程序类来执行此操作:

ErrorHandler.Error("Something has broken!!\n\nDescription");

这很好用。但是,当我尝试访问此表时,似乎不再存在换行符。

如果我SELECT桌子:

SELECT * from ErrorLog ORDER BY ErrorDate

日志中没有换行符。这是意料之中的,因为单行行中的换行符会破坏格式。但是,如果我将数据复制出来,则换行符已经丢失,并且数据都在一行上。

当我插入换行符时,如何在查询结束时获取数据中的换行符?不知道是不是字符串在进入表格的时候去掉了换行符,还是SQL Server Management Studio中的查看器去掉了换行符。

错误消息所在列的数据类型是nvarchar(Max),如果有区别的话。

编辑:出乎意料的是,Pendri 的解决方案不起作用。

这是字符串在传递到 SQL 服务器之前的摘录:

POST /ipn/paymentResponse.ashx?installation=272&msgType=result HTTP/1.0\n\rContent-Length: 833\n\rContent-Type: 

当我从 SQL Server Management Studio 的网格查看器中提取它时,这是相同的字符串:

POST /ipn/paymentResponse.ashx?installation=272&msgType=result HTTP/1.0  Content-Length: 833  Content-Type:

应该换行的地方是双倍行距的。

有什么想法吗?

【问题讨论】:

  • 当您说换行符丢失时,是因为当您从 SSMS 运行查询时它们没有出现在网格结果视图中吗?我相信 SSMS 会在结果中去除换行符,即使您复制和粘贴也是如此。您可以通过转换为 varbinary 并查看二进制表示中是否存在相关字符代码或编写一个小型 c# 应用程序来验证这一点。

标签: sql-server


【解决方案1】:

无需替换字符串输入\输出,只需选择正确的选项:

Tools -> Options...

> Query Results 
  > SQL Server 
    > Results to Grid 

set "Retain CR\LF on copy or save" to true.

别忘了重启你的管理工作室!

根据Charles Gagnon answer

【讨论】:

  • 我必须在更改此设置后重新启动 SSMS,然后它才能工作。我认为这比公认的答案更直接地解决了这个问题。
  • 这个答案需要更多投票。 p.s.您只需要创建新的查询窗口;更改选项后无需重新启动。
  • 这只是为新的查询窗口设置默认值。如果要为现有查询窗口更改它,请右键单击查询窗格,选择查询选项,然后转到结果 > 网格并选中“在复制或保存时保留 CR/LF”。 (您也可以从“查询”菜单进入“查询选项”。)
  • 起初这对我不起作用(SSMS 13.0.15500.91)。我看到了重新启动 SSMS 以使更改生效的评论,但我不想这样做,因为我有很多未保存的工作。我打开了一个新的 SSMS 实例,所做的更改没有关闭任何已经打开的窗口。
  • 你救了我,感激不尽!
【解决方案2】:

SSMS 在网格输出中用空格替换换行符。如果您使用打印来打印值(将转到您的消息选项卡),那么如果它们与数据一起存储,则回车将显示在那里。

例子:

SELECT 'ABC' + CHAR(13) + CHAR(10) + 'DEF'
PRINT 'ABC' + CHAR(13) + CHAR(10) + 'DEF'

第一个将显示在网格中的单个单元格中,没有中断,第二个将在消息窗格中打印,并带有中断。

一种快速简便的打印值的方法是选择一个变量:

DECLARE @x varchar(100);
SELECT @x = 'ABC' + CHAR(13) + CHAR(10) + 'DEF';
PRINT @x;

【讨论】:

  • 太棒了!这行得通。只是为了获取数据而这样做有点不方便。
  • 更简单:在查询窗口中单击鼠标右键,“Results To | Results to Text”
【解决方案3】:

几年后更新。

here 所述,在 SSMS 中保留查看换行符的一种解决方案是将输出转换为 XML:

SELECT * FROM (
  SELECT * from ErrorLog ORDER BY ErrorDate
) AS [T(x)] FOR XML PATH

幸运的是,如果您有 SSMS 2012,这不再是问题,因为保留了换行符。

【讨论】:

【解决方案4】:

我回显David C's answer,但您应该使用“TYPE”关键字,以便您可以单击以在新窗口中打开数据。

请注意,任何不安全的 XML 字符都不适用于我们的任一解决方案。

这是一个概念证明:

DECLARE @ErrorLog TABLE (ErrorText varchar(500), ErrorDate datetime);
INSERT INTO @ErrorLog (ErrorText, ErrorDate) VALUES
    ('This is a long string with a' + CHAR(13) + CHAR(10) + 'line break.', getdate()-1),
    ('Another long string with' + CHAR(13) + CHAR(10) + '<another!> line break.', getdate()-2);
SELECT
    (
        SELECT  ErrorText AS '*'
        FOR XML PATH(''), TYPE
    ) AS 'ErrorText',
    ErrorDate
FROM        @ErrorLog
ORDER BY    ErrorDate;

我可以确认在 SSMS 2012 中从网格中复制时会保留换行符。

【讨论】:

    【解决方案5】:

    尝试在你的字符串中使用char(13) + char(10)而不是'\n'(定义一个常量并连接到你的sql)

    【讨论】:

    • 如果我在我的message.replace('\n',char(13) + char(10)) 方法中执行类似message.replace('\n',char(13) + char(10)) 的操作,它是否适用于所有情况?
    • 数据正在进入表中。问题在于 SSMS 显示和处理数据的方式。
    【解决方案6】:

    另一个简单的解决方案是单击 SSMS 中的“结果为文本”按钮。它不是超级干净,但可以让您在大约半秒的工作时间内看到换行符。

    【讨论】:

      【解决方案7】:

      对于 SQL Server 2008,没有规定将“Retain CR\LF on copy or save”设置为 true。

      对于这个问题,我所做的是,将 char(13) 替换为“\r”,并将 char(10) 替换为“\n”,如下所示。

      REPLACE(REPlACE([COLUMN_NAME],char(13), '\r'),CHAR(10),'\n')
      

      在代码隐藏中,我再次用中断标记替换了“\r\n”。

      我以这种方式解决了上述问题,因为 SQL 2008 中没有提供任何选项。不过,这个答案可能是另一种选择。

      谢谢

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-12
        • 2015-08-29
        • 1970-01-01
        相关资源
        最近更新 更多