【问题标题】:internal working of SqlDataReader and metadataSqlDataReader 和元数据的内部工作
【发布时间】:2014-06-26 09:14:39
【问题描述】:

出于好奇和对更多洞察力的永恒渴望:)

这里有一个 CLR 存储过程,它通过以下代码将结果发送回客户端。 SqlMetaData 数组附加到 SqlDataRecord。每个 SqlDataRecord 获取通过管道发送给客户端的值。

SqlMetaData[] columns = new SqlMetaData[1];

columns[0] = new SqlMetaData("bool", SqlDbType.Bit);

SqlDataRecord record = new SqlDataRecord(columns);
SqlContext.Pipe.SendResultsStart(record);

foreach (bool b in bools)
{
     record.SetBoolean(0, b);

      SqlContext.Pipe.SendResultsRow(record);
}
SqlContext.Pipe.SendResultsEnd();

客户端代码:

SqlCommand cmd = new SqlCommand("CLR_SPROC", connection)

SqlDataReader reader = cmd.ExecuteReader();

int b = reader.GetOrdinal("bool"); // b == 0 because it was added in index 0 in the SqlMetaData array

所以“bool”的序数变为零,因为它首先在第一个索引中找到。很有趣。

现在的问题:

SqlServer 是否在每个查询的后台都这样工作?我的意思是当执行查询时,查询解析器是否会在最终选择中提取列名,从中构建一个 SqlMetaData 数组,将其附加到 SqlDataRecord 并通过流发送回?

所以查询“SELECT a,b,c FROM table”

变成

SqlMetaData[] columns = new SqlMetaData[3];

columns[0] = new SqlMetaData("a", SqlDbType.Int);
columns[1] = new SqlMetaData("b", SqlDbType.Int);
columns[2] = new SqlMetaData("c", SqlDbType.Int);

 SqlDataRecord record = new SqlDataRecord(columns);
 SqlContext.Pipe.SendResultsStart(record);

foreach(...)
{
  record.SetInt32(0, a);
  record.SetInt32(1, b);
  record.SetInt32(2, c);
  SqlContext.Pipe.SendResultsRow(record);
}

【问题讨论】:

标签: c# .net sql-server


【解决方案1】:

SQL Server 使用 TDS 协议(表格数据流)与客户端通信。 TDS 是一种流协议,包括描述结果集的元数据,后跟结果集数据流。结果集中的记录包含相同的列数、列名和数据类型,因此处理结果集所需的元数据只需发送一次,而不是附加到每条记录。

像 SqlClient 这样的客户端 API 将低级 TDS 结构公开为高级对象,如 SqlMetaData、SqlDataRecord 和 SqlDataReader。尽管您针对客户端 API 而不是直接针对 TDS 进行编码,但您可能会发现对 TDS 通信的粗略理解很有趣,因为它提供了 SQL Server 如何在幕后工作的视图。您可以在http://msdn.microsoft.com/en-us/library/dd304523.aspx 找到 TDS 协议的详细信息。

【讨论】:

  • 很有趣,连同参考源站点,我将花一些时间阅读这篇文章。谢谢
  • @Dan 我有一个可能与 sql 元数据有关的问题。 Can you please have a look? 看来问题是这样的:columnIndex >= _metaData.Length,但我不知道如何解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-27
  • 1970-01-01
  • 1970-01-01
  • 2021-09-12
  • 2010-09-15
相关资源
最近更新 更多