From curiosity and eternal hunger for a deeper understanding :)
This CLR procedure is stored here, which sends the results back to the client using the following code. The SqlMetaData array is bound to SqlDataRecord. Each SqlDataRecord receives values that are sent to clients through the channel.
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();
client code:
SqlCommand cmd = new SqlCommand("CLR_SPROC", connection)
SqlDataReader reader = cmd.ExecuteReader();
int b = reader.GetOrdinal("bool");
Thus, the serial number "bool" becomes zero, since it is found first in the first index. Interesting.
Now the question is:
Does SqlServer support this under the hood for every request? I mean, when the query is executed, the query analyzer extracts the column names in the final select, builds an SqlMetaData array from it, attaches it to SqlDataRecord and sends it back down the stream?
, "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);
}