出于好奇和对更多见解的永恒渴望 :)
这里有一个CLR存储过程,通过以下代码将结果发送回客户端。 SqlDataRecord附加了SqlMetaData数组。每个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);
}