【问题标题】:SQL Server truncation and 8192 limitationSQL Server 截断和 8192 限制
【发布时间】:2010-10-31 10:27:48
【问题描述】:

在 SQL Server 2005 中,我试图查询一个 varchar(MAX) 列,该列的某些行的文本数据超过 8192。然而,在 Management Studio 中,我在 Tools --> Options --> Query结果 --> 结果到文本 --> 每列中显示的最大字符数 = 8192,这是最大值。因此,这些行的截断似乎只是由于文本输出所施加的限制。

我看到解决这个问题的唯一方法是使用 SUBSTRING 函数来抓取前 8000 个字符,然后是接下来的 8000 个字符等等。但这很丑陋且容易出错。

我应该提到 SSIS 和 BCP 不是我的选择。

有人有更好的建议吗?谢谢!

【问题讨论】:

  • 您是否关心查询分析器中的输出显示方式?如果您只是用它来查看数据,那么我不会太沉迷于“容易出错”和“丑陋”的代码。如果您将它用于生产工作,那么这完全是另一个问题。
  • Tom:我不只是在看数据。我正在使用查询输出为远程服务器生成新的存储过程调用,因此结果必须是“完美的”。
  • 但是为什么要使用 SSMS 来执行查询呢?如果您从程序中执行相同的查询会发生什么?
  • SSMS2008 甚至在我选择输出到文件时截断。哈!!!
  • 对我来说最简单的方法是将字符串转换为 xml(如 stackoverflow.com/a/2760023/278044 所示)。 Management Studio 可以配置为允许无限的 XML 大小。

标签: sql-server truncation


【解决方案1】:

您可以将数据导出到不会被截断的平面文件中。为此:

  1. 右键单击数据库
  2. 点击任务 -> 导出数据
  3. 选择您的数据源(默认应该没问题)
  4. 为目标类型选择“平面文件目标”。
  5. 为输出选择一个文件名。
  6. 在“指定表复制或查询”中,选择“编写查询以指定要传输的数据”
  7. 粘贴您的查询

剩下的步骤应该是不言自明的。这会将文件输出为文本,您可以在您喜欢的文本编辑器中打开它。

【讨论】:

  • +1 表示无需编写自定义工具即可工作的解决方案。我需要在不更改格式(间距)的情况下导出 XML 数据,因此不能选择导出为 XML。
  • 谢谢@Torre .. 它拯救了我的一天 :)
  • 对我不起作用。还在截断。是否还有其他我可能遗漏的关键步骤(不言自明)?
  • 是的。在输出文件中,每个超过 4k 个字符的单元格都将被截断。无论如何,我必须通过查询获得每个存储过程的定义。有一个解决方法..
  • 导出期间的默认设置不起作用;我手动选择了数据源“.Net Framework Data Provider for SQL Server”...手动指定数据源初始目录,集成安全;并使用 Unicode 平面文件输出;就我而言,我使用了FOR JSON PATH
【解决方案2】:

我也使用 XML,但 a slightly different method 可以解决 XML 实体化的大部分问题。

declare @VeryLongText nvarchar(max) = '';

SELECT top 100 @VeryLongText = @VeryLongText + '

' + OBJECT_DEFINITION(object_id) 
FROM sys.all_objects 
WHERE type='P' and is_ms_shipped=1

SELECT LEN(@VeryLongText)

SELECT @VeryLongText AS [processing-instruction(x)] FOR XML PATH('')

PRINT @VeryLongText /*WILL be truncated*/

确保 SSMS 中的“XML 数据”限制设置得足够高!

【讨论】:

  • 有没有办法让非 xml 数据显示为无限制并放弃限制?我可以看到下限是30,更高的是65535。
  • @BabekoofCoder - 不幸的是没有。因此需要将非 xml 转换为 XML 解决方法。
  • 这是一个很好的答案,但令人困惑。你只需要一行'XML PATH'。
  • 更改查询选项后打开一个新的查询窗口 - 现有窗口不受影响。
  • select @variable for xml path('') 对我来说效果很好,绕过了我得到的 65536 个字符的限制。谢谢!
【解决方案3】:

我的解决方案有点迂回,但我做到了(只要输出少于 65535 个字符)

  1. 在 SQL Management Studio 中,将网格结果的限制设置为 65535(工具 > 选项 > 查询结果 > SQL Server > 结果到网格 > 非 XML 数据)
  2. 运行查询,输出到网格
  3. 右键单击结果,选择“将结果另存为...”并将结果保存到文件中
  4. 在记事本或类似工具中打开文件以获取输出

更新:为了证明这是可行的,这里有一些选择单个 100,000 个字符列的 SQL。如果我将网格输出保存到 csv 文件,则所有 100,000 个字符都在那里,没有截断。

DECLARE @test nvarchar(MAX), @i int, @line nvarchar(100)
SET @test = ''; SET @i = 100
WHILE @i < 100000
BEGIN
    SET @test = @test + STUFF(REPLICATE('_', 98) + CHAR(13) + CHAR(10), 1, LEN(CAST(@i AS nvarchar)), CAST(@i AS nvarchar))
    SET @i = @i + 100
END
SELECT @test

注意事项:

  1. 我最初认为,字符长度设置似乎没有任何区别。
  2. 我正在使用 SQL 2008 R2(服务器和 Management Studio)
  3. 如果长列存储在局部变量中(如本例所示)或从实际表中选择,似乎没有什么区别

【讨论】:

  • 很抱歉听到它对您不起作用。我添加了一些代码来展示我是如何测试它是否工作的,并添加了一些关于我知道它工作的条件的注释。
  • 对我也不起作用。 MS SQL 管理工作室 2008 R2。
  • 这在 SQL Server Management Studio 2016 中非常适合我!
【解决方案4】:

您尝试过这个简单的解决方案吗?只需点击 2 次!

在查询窗口,

  1. 将查询选项设置为“结果到网格”,运行您的查询
  2. 右键单击网格角的结果选项卡,将结果另存为任何文件

你会得到你想在文件中看到的所有文本!!!我可以看到 varchar(MAX) 字段的结果有 130,556 个字符

【讨论】:

    【解决方案5】:

    我在尝试导出 XML 时遇到了这个问题。这是我使用的解决方案:

    选择“结果到网格”选项,右键单击“结果”窗格中显示的链接,然后选择“结果另存为”,选择“所有文件”文件类型,为文件命名并单击“保存”。所有 xml 数据都正确保存到文件中。

    我正在使用 SSMS 10,但无法让 Torre 的解决方案正常工作。导出向导一直认为输入列是图像:

    “输入列“XML_F52E2B61-18A1-11d1-B105-00805F49916B”(26)”的数据类型为DT_IMAGE

    【讨论】:

    • 我也遇到了 DT_IMAGE 问题,但通过在我的 XML 生成语句周围添加另一个 , type、一个外部 select() as columnname 并检查导出向导中的 Unicode 复选框来解决它。
    【解决方案6】:

    在 SSMS 中,如果您从一行中选择数据,则它仅限于少量字符,但如果您从一行中编辑数据,则完整的值将在那里。它可能并不总是存在,但如果你按 ctrl-a、ctrl-c 然后在编辑器中将其传递过去,它就会全部存在。

    【讨论】:

      【解决方案7】:

      如果给定一个选择,我会让查询将数据返回为“For XML Auto”或“For XML Raw”或“For XML explicit”,这样限制要高得多,您可以对输出的结果做更多​​的事情.

      【讨论】:

      • @Jaco - 但是您可以在 SSMS 中配置 XML 限制来避免这种情况。看我的回答。
      【解决方案8】:

      我通常使用 XML 来获取巨大的调试字符串作为输出(使用来自 Luke 的测试工具):

          declare @test nvarchar(max), @i int, @line nvarchar(100)
          set @test = ''; set @i = 100
          while @i < 100000
          begin
              set @test = @test + stuff(replicate('_', 98) + char(13) + char(10), 1, len(cast(@i as nvarchar)), cast(@i as nvarchar))
              set @i = @i + 100
          end
          -- ctrl+d for "results to grid" then click the xml output
          --select cast('<root>' + @test + '</root>' as xml)
      
      -- revised
      select @test for xml path(''), type;
      

      【讨论】:

      • 如果@test 包含2 &lt; 3 会爆炸
      • 好点。您可以让 xml 路径替换它们……但不确定这就是您所追求的。至少没有爆炸:) 请检查修订版。
      • 没有爆炸,但它会改变结果!
      【解决方案9】:

      另一种解决方法,使用HeidiSql 处理这个棘手的查询。它没有视场长度的限制。

      【讨论】:

        【解决方案10】:

        您所说的截断只发生在 Management Studio 中。如果将列拉到另一个应用程序中,它不会被截断。

        您无法使用查询分析器与 SQL Server 2005 对话。您是指 Management Studio 吗?

        【讨论】:

        • 我认为他的意思是 Management Studio。如果您切换到“结果到网格”,它会将每列的最大值显示为 65535。不过,不确定这是否会让您更接近 - 听起来您正在尝试在 SQL 中进行代码生成?
        • 抱歉,我的意思是 Management Studio。
        猜你喜欢
        • 2012-11-18
        • 1970-01-01
        • 1970-01-01
        • 2016-09-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-30
        相关资源
        最近更新 更多