gpt4 book ai didi

c# - SqlDataReader 和元数据的内部工作

转载 作者:行者123 更新时间:2023-11-30 12:27:48 25 4
gpt4 key购买 nike

出于好奇和对更多见解的永恒渴望:)

这里有一个 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);
}

最佳答案

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

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

关于c# - SqlDataReader 和元数据的内部工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24426666/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com