Skip to main content
  1. Posts/

Retrieve Column Schema with GetSchemaTable

··2 mins

The Microsoft KB example code or class library documentation do not explain how to efficiently return a table’s schema. For example, this code follows the documentation:

DataTable dataTable = null;
using (IDbConnection dbConnection = (IDbConnection)database.Unwrap()) {
  dbConnection.Open();
  using (IDbCommand dbCommand = dbConnection.CreateCommand()) {
    dbCommand.CommandType = CommandType.Text;
    dbCommand.CommandText = "SELECT * FROM SomeLargeTable;";
    using (IDataReader dataReader = dbCommand.ExecuteReader(CommandBehavior.KeyInfo)) {
      dataTable = dataReader.GetSchemaTable();
      dataReader.Close();
    }
  }
  dbConnection.Close();
}

// look at table schema stored in dataTable

Results in the following SQL executed on SQL Server:

SET FMTONLY OFF; SET NO_BROWSETABLE ON;
SELECT * FROM SomeLargeTable; SET NO_BROWSETABLE OFF;

If you add | CommandBehavior.SchemaOnly to the ExecuteReader method call:

SET FMTONLY OFF; SET NO_BROWSETABLE ON; SET FMTONLY ON;
SELECT * FROM SomeLargeTable; SET NO_BROWSETABLE OFF; SET FMTONLY OFF;

According to the documentation:

CommandBehavior.SchemaOnly #

The query returns column information only. When using SchemaOnly, the .NET Framework Data Provider for SQL Server precedes the statement being executed with SET FMTONLY ON. — .NET Docs1

FMTONLY ON #

Returns only metadata to the client. Can be used to test the format of the response without actually running the query. — SQL Docs2

As expected, I had a significant performance increase with (CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly). Querying 100,000,000 rows to retrieve table schema is inefficient, to say the least.

George Tsiokos
Author
George Tsiokos

Comments

yeah, I came across this very issue when I was helping someone write a data migrator that takes one table at a time from one database and moves it to another. Kind of like SQL and Data Compare from red-gate but customized for some app.

If you ask me, that seems like a roundabout way to get something when they should have explicitly included a method to grab the schema without having to do a select statement first (even if the method just did this behind the scenes). Oh well, maybe someday they’ll get with the program and pay me truckloads of cash to design their stuff for them ;-)

Leave a comment

Preview

Comments are reviewed before publishing.