SqlDataReader 和 SQL Server 2016 FOR JSON 将 json 拆分为 2k 字节的块

VSD*_*kar 6 c# t-sql sql-server sql-server-2016 azure-sql-database

最近,我尝试for json auto了 Azure SQL 数据库的新功能。

例如,当我使用此查询选择大量记录时:

Select
    Wiki.WikiId
    , Wiki.WikiText
    , Wiki.Title
    , Wiki.CreatedOn
    , Tags.TagId
    , Tags.TagText
    , Tags.CreatedOn
From
    Wiki
Left Join
    (WikiTag
Inner Join 
    Tag as Tags on WikiTag.TagId = Tags.TagId) on Wiki.WikiId = WikiTag.WikiId
For Json Auto
Run Code Online (Sandbox Code Playgroud)

然后用 C# 做一个选择SqlDataReader

var connectionString = ""; // connection string
var sql = "";  // query from above
var chunks = new List<string>();

using (var connection = new SqlConnection(connectionString)) 
using (var command = connection.CreateCommand()) {
    command.CommandText = sql;
    connection.Open();

    var reader = command.ExecuteReader();

    while (reader.Read()) {
            chunks.Add(reader.GetString(0)); // Reads in chunks of ~2K Bytes
    }
}

var json = string.Concat(chunks);
Run Code Online (Sandbox Code Playgroud)

我得到了很多数据块。

为什么我们有这个限制?为什么我们不把所有东西都放在一个大块里?

当我阅读一nvarchar(max)栏时,我会把所有内容都放在一个块中。

谢谢你的解释

Luk*_*zda 4

使用FOR JSON 将查询结果格式化为 JSON

\n\n
\n

FOR JSON 子句的输出

\n\n

结果集包含单个列。

\n\n

小型结果集可能包含单行。

\n\n

大型结果集会将长 JSON 字符串拆分为多行。\n 默认情况下,当输出设置为“结果到网格”时,SQL Server Management Studio (SSMS) 将结果连接到一行中。\n SSMS 状态栏显示实际行数。

\n\n

其他客户端应用程序可能需要代码通过连接多行内容将冗长的结果重新组合成单​​个有效的 JSON 字符串。有关 C#\n 应用程序中此代码的示例,请参阅在 C# 客户端应用程序中使用 FOR JSON 输出。

\n
\n\n

我想说这完全是出于性能原因,类似于 XML。更多SELECT FOR XML AUTO 并返回数据类型以及服务器端 FOR XML 返回什么?

\n\n
\n

在 SQL Server 2000 中,服务器端 XML 发布 - FOR XML(请参阅http://msdn2.microsoft.com/en-us/library/ms178107(SQL.90).aspx) - 是在查询之间的代码层中实现的处理器和数据传输层。如果没有 FOR XML,则查询处理器将执行 SELECT 查询,并且结果行集将由服务器端 TDS 代码发送到客户端。当 SELECT 语句包含 FOR XML 时,查询处理器以与不包含 FOR XML 相同的方式生成结果,然后 FOR XML 代码将行集格式化为 XML。为了获得最大的 XML 发布性能,FOR XML 对生成的行集进行流式 XML 格式化,并将其输出以小块的形式直接发送到服务器端 TDS 代码,而无需在服务器空间中缓冲整个 XML。块大小为 2033 个 UCS-2 字符。因此,大于 2033 个 UCS-2 字符的 XML 会以多行的形式发送到客户端,每行都包含 XML 块。SQL Server 为此行集使用预定义的列名称,其中一列类型为 NTEXT - \xe2\x80\x9cXML_F52E2B61-18A1-11d1-B105-00805F49916B\xe2\x80\x9d \xe2\x80\x93 来指示 UTF 格式的分块 XML 行集-16编码。这需要 API 对 XML 块行集进行特殊处理,以将其公开为客户端上的单个 XML 实例。在ADO.Net中,需要使用ExecuteXmlReader,而在ADO/OLEDB中,应该使用ICommandStream接口。

\n
\n