带有临时表的存储过程的SqlDataAdapter.FillSchema

时间:2013-09-24 18:32:52

标签: stored-procedures sqldataadapter temp-tables

我遇到了类似于这个问题的问题(Display DataType and Size of Column from SQL Server Query Results at Runtime),这个问题没有一个可靠的解决方案。

我想知道是否有人找到了解决方案或解决方案。我可以使用SqlDataAdapter.Fill()没有问题,但.FillSchema()将报告我在存储过程中创建的临时表不存在的错误。

我的目标是能够使用数据和来自源的架构填充DataTable。

3 个答案:

答案 0 :(得分:0)

我遇到了SqlDataAdapter的同一问题。我可以通过将代码改为使用SqlDataReader来解决此问题。

如果您根本不需要修改架构

如果您不需要操纵DataTable对象的架构,并且还计划使用从存储过程返回的数据,则以下代码段将正常工作。

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);

这两个方法都将使用与存储过程调用返回的名称和类型相对应的列名称和类型填充数据表。如果您需要有关架构的信息,则可以通过DataTable.Columns属性对其进行访问。

如果您需要修改架构

如果仅需要模式信息,或者需要先在DataTable对象中操作模式,然后再用数据填充,即使SqlDataAdapter.FillSchema不需要,也可以使用以下方法。

>
var command = new SqlCommand("stored procedure name")
{
    CommandType = CommandType.StoredProcedure 
};

var reader = command.ExecuteReader();

var schemaTable = reader.GetSchemaTable();

SqlDataReader.GetSchemaTable()将返回一个DataTable对象,其列元数据填充为行。

您可以枚举结果来构建和/或操作DataTable对象中的列,这些对象将保存SqlDataReader返回的记录。

对于我来说,我需要将每一列都作为字符串,以避免在将数据导出到电子表格时使用Microsoft Excel的任何格式的“帮助”。例如,我的代码如下:

var dt = new DataTable();

foreach(DataRow row in schemaTable.Rows)
{
    dt.Columns.Add((string)row["ColumnName"], typeof(string));
}

dt.Load(reader);

答案 1 :(得分:0)

存储过程和临时表通常与数据库对象的强类型实现不能很好地融合。

如果将#temp表更改为应该解决问题的表@variable。

如何从临时表更改为表变量的示例如下:

    CREATE TABLE #tempTable (ID INT, Val VARCHAR(50))

    DECLARE @tempTable TABLE(ID INT, Val VARCHAR(50))

答案 2 :(得分:-1)

如果您不需要DataSet,只需要一个DataTable,则可以使用

DataTable dt= new DataTable();

dt.Load(cmd.ExecuteReader());

对于DataSet,您必须至少告诉SP返回的表的名称(这意味着数字)。

DataSet ds = new DataSet();
SqlDataReader sdr = cmd.ExecuteReader();
ds.Load(sdr, LoadOption.OverwriteChanges,"Table1");