I ran into this same issue with SqlDataAdapter
. I was able to resolve the issue by changing my code to use SqlDataReader
instead.
If you do not need to modify the schema at all
The following code segments will work fine if you do not need to manipulate the schema of your DataTable
object and you also plan to use the data returned from the stored procedure.
var command = new SqlCommand("stored procedure name")
{
CommandType = CommandType.StoredProcedure
};
var adapter = new SqlDataAdapter(command);
var dt = new DataTable();
adapter.Fill(dt);
var command = new SqlCommand("stored procedure name")
{
CommandType = CommandType.StoredProcedure
};
var reader = command.ExecuteReader();
var dt = new DataTable();
dt.Load(reader);
Both methods will populate a data table with column names and types that correspond to the names and types returned from the stored procedure call. If you need information about the schema, you can access it via the DataTable.Columns
property.
If you need to modify the schema
If you need schema information only, or if you need to manipulate the schema in the DataTable
object before populating it with data, the following method will work, even if SqlDataAdapter.FillSchema
does not.
var command = new SqlCommand("stored procedure name")
{
CommandType = CommandType.StoredProcedure
};
var reader = command.ExecuteReader();
var schemaTable = reader.GetSchemaTable();
SqlDataReader.GetSchemaTable()
will return a DataTable
object with column metadata populated as rows.
You can enumerate the results to build and/or manipulate columns in a DataTable
object that will hold the records returned by the SqlDataReader
.
In my case, I needed every column to be a string to avoid any formatting "help" from Microsoft Excel when exporting the data to a spreadsheet. As an example, my code looks like this:
var dt = new DataTable();
foreach(DataRow row in schemaTable.Rows)
{
dt.Columns.Add((string)row["ColumnName"], typeof(string));
}
dt.Load(reader);