SqlDataReader和SQL Server 2016 FOR JSON以2k字节的块分割json
最近我玩了Azure SQL数据库的新功能for json auto
。SqlDataReader和SQL Server 2016 FOR JSON以2k字节的块分割json
当我选择,例如大量的记录与此查询:
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
,然后做一个选择用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);
我得到了很多的数据块。
为什么我们有这个限制?为什么我们不能把所有东西都放在一个大块里?
当我阅读nvarchar(max)
列时,我会将所有内容都放在一个块中。
感谢解释
从Format Query Results as JSON with FOR JSON:
的FOR JSON子句
结果集包含单个列的输出。
一个小的结果集可能包含一行。
一个较大的结果集将长JSON字符串分割成多行。 默认情况下,当输出设置为结果为 网格时,SQL Server Management Studio(SSMS)将结果连接成单行。 SSMS状态栏显示实际的行数。
其他客户端应用程序可能需要代码才能将冗长的结果重新组合为单个有效的JSON字符串,方法是连接多行的 内容。有关C# 应用程序中此代码的示例,请参阅C#客户端应用程序中的使用FOR JSON输出。
我会说这是严格的性能原因,类似于XML。更SELECT FOR XML AUTO and return datatypes和What does server side FOR XML return?
在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类型的一列 - “XML_F52E2B61-18A1-11d1-B105-00805F49916B” - 以UTF-16编码指示分块的XML行集。这需要API对XML块行集进行特殊处理,以将其作为客户端上的单个XML实例公开。在ADO.Net中,需要使用ExecuteXmlReader,而在ADO/OLEDB中,应该使用ICommandStream接口。