繁体   English   中英

SQL 服务器 json 被截断(即使使用 NVARCHAR(max) )

[英]SQL Server json truncated (even when using NVARCHAR(max) )

DECLARE @result NVARCHAR(max);

SET @result = (SELECT * FROM table
               FOR JSON AUTO, ROOT('Data'))

SELECT @result;

这将返回约 43000 个字符的 json 字符串,其中一些结果被截断。

SET @result = (SELECT * FROM table
               FOR JSON AUTO, ROOT('Data'))

这将返回约 2000 个字符的 json 字符串。 有什么办法可以防止截断吗? 即使在处理一些大数据并且字符串是数百万个字符时?

我没有找到“官方”答案,但似乎这是新的“FOR JSON”语句的错误,该语句将结果拆分为 2033 个字符长的行。 正如这里推荐的那样,到目前为止,最好的选择是遍历连接返回行的结果:

string result = "";
while (reader.Read())
{
    result += Convert.ToString(reader[0]);                        
}

顺便说一句,似乎最新版本的 SSMS 已经在应用某种像这样的解决方法来将结果显示在一行中。

通过在 SQL Server 2017(版本 14.0.2027)中使用print而不是select ,我能够获得完整的、未截断的字符串:

DECLARE @result NVARCHAR(max);

SET @result = (SELECT * FROM table
           FOR JSON AUTO, ROOT('Data'))

PRINT @result;

另一种选择是下载和使用Azure Data Studio ,我认为这是 SSMS 的多平台重写(类似于 Visual Studio 被重写为 VS Code 的方式)。 它似乎开箱即用地吐出整个未截断的 json 字符串!

我们在 SSMS 中看到了类似的问题,但没有使用变量 SSMS 在 2033 处截断。

对于变量,当您使用 nvarcahr(max) 变量时,查询实际上可以正常工作,但它会在 43697 处截断查询结果视图中的输出。

我测试过的一个可能的解决方案是使用 BCP 将查询结果输出到文件:

bcp "DECLARE @result NVARCHAR(max); SET @result = (SELECT * FROM table FOR JSON AUTO, ROOT('Data')); SELECT @result as Result;" queryout "D:\\tmp\\exportOutput.txt" -S SQL_SERVER_NAME -T -w

请参阅 BCP 文档以指定服务器名称\\实例和身份验证选项

我知道这是一个旧线程,但是通过将结果发送到 XML 变量,我已经成功解决了这个问题。 使用 XML 变量的优点是大小不表示为字符长度,而是表示为内存中字符串的大小,可以在选项中更改。 因此,Brad C 的反应现在看起来像……

DECLARE @result XML
SET @result = (SELECT * FROM table
FOR JSON AUTO, ROOT('Data'))
SELECT @result

or...

PRINT @result;

如果您插入到临时表中,这也将起作用 - 不显示不适用 SSMS 的截断。 如果您需要计算多个值,可能会很有用。

declare @json table (j nvarchar(max));
insert into @json select * from(select* from Table where Criteria1 for json auto)a(j)
insert into @json select * from(select* from Table where Criteria2 for json auto)a(j)
select * from @json

在不发布数据的情况下很难准确确定您遇到的问题是什么,但是当我尝试以 JSON 格式导出查询时遇到了类似的问题。 对我有用的解决方案是转到查询/查询选项/结果/文本/将“每列中显示的最大字符数:”设置为 8192(最大值 AFAIK)。

这可能对您的第一个查询没有太大帮助,但可能会被分解为更小的查询并成功执行。 我预计您可以在更改该设置后有效地运行第二个查询。

以下是 JSON 截断的答案:

SQL将 JSON 结果分成大小为2k 的(至少我的 SQL 2016 安装是这样),结果集中每一行的第一列中有一个块。 要获得整个结果,您的客户端代码必须遍历结果集并连接每条记录的第一列。 当您到达行的末尾时,瞧,您的整个 JSON 结果将被检索,未删减。

当我第一次遇到截断问题时,我感到很困惑,几年来一直认为FOR JSON是一个不严肃的特性,只适用于最小的数据集。 我了解到我只需要从FOR XML文档中读取整个记录集,而实际上从未在FOR JSON文档中看到它提到过。

如果您的数据长度小于 65535,那么您应该使用@dfundako在第一篇文章中评论的建议:

尝试转到工具、选项、查询结果、SQL Server、结果到网格,并将非 XML 数据设置为最大数量(我认为 65535)

就我而言,数据长度为 21k 个字符,因此在导出到网格后,我复制了该值,结果很好,没有被截断。 对于那些数据量较大的人来说,它仍然没有解决问题。

我正在使用 SQL Server 2019,但问题仍然存在。 尝试了这篇文章的所有回复,但没有一个对我有用,它甚至不是一个大数据集。

尝试使用 Microsoft SQL 扩展的 Visual Studio Code。 我得到了 6800 个字符的 JSON 没有截断。 SSMS 似乎截断了结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM