Internal work of SqlDataReader and metadata

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"); // b == 0 because it was added in index 0 in the SqlMetaData array

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);
}
+4
1

SQL Server TDS ( ). TDS - , , , . , , , , , .

API, SqlClient, TDS , SqlMetaData, SqlDataRecord SqlDataReader. API- , TDS, TDS, , SQL Server . TDS http://msdn.microsoft.com/en-us/library/dd304523.aspx.

+2

Source: https://habr.com/ru/post/1546114/


All Articles