【发布时间】: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);
}
【问题讨论】:
-
这是一款复杂的软件。 SQL 客户端的所有参考源都可从 Microsoft 获得,例如 SQLCommand.cs:referencesource.microsoft.com/#System.Data/data/System/Data/…
-
上面的链接已经失效(404),你可以看看SqlCommand.cs或者SqlClient
标签: c# .net sql-server