【问题标题】:How to Populate a DataTable from a Stored Procedure [duplicate]如何从存储过程中填充数据表 [重复]
【发布时间】:2018-07-30 16:01:42
【问题描述】:

可能重复:
How can i retrieve a table from stored procedure to a datatable

我正在尝试填充我的数据表。我创建了一个数据表 tmpABCD,但我需要使用存储过程中的值填充它。我无法继续。

SqlConnection sqlcon = new SqlConnection(ConfigurationManager.ConnectionStrings["DB"].ConnectionString);
sqlcon.Open();
SqlCommand cmd = new SqlCommand("usp_GetABCD", sqlcon);

DataTable dt = new DataTable("tmpABCD");

dt.Columns.Add(new DataColumn("A"));
dt.Columns.Add(new DataColumn("B"));
dt.Columns.Add(new DataColumn("C"));
dt.Columns.Add(new DataColumn("D"));

【问题讨论】:

  • 不能。没有足够的代表。无论如何,这里的答案最终会更好。

标签: c# asp.net .net ado.net


【解决方案1】:

您无需手动添加列。只需使用DataAdapter,它就很简单:

DataTable table = new DataTable();
using(var con = new SqlConnection(ConfigurationManager.ConnectionStrings["DB"].ConnectionString))
using(var cmd = new SqlCommand("usp_GetABCD", con))
using(var da = new SqlDataAdapter(cmd))
{
   cmd.CommandType = CommandType.StoredProcedure;
   da.Fill(table);
}

请注意,您甚至不需要打开/关闭连接。这将由DataAdapter 隐式完成。

与 SELECT 语句关联的连接对象必须是 有效,但不需要打开。如果连接关闭 在调用 Fill 之前,打开它以检索数据,然后关闭它。如果 在调用 Fill 之前连接是打开的,它保持打开状态。

【讨论】:

    【解决方案2】:

    改用SqlDataAdapter,方便多了,不需要自己定义列名,它会从查询结果中获取列名:

    using (SqlConnection sqlcon = new SqlConnection(ConfigurationManager.ConnectionStrings["DB"].ConnectionString))
    {
        using (SqlCommand cmd = new SqlCommand("usp_GetABCD", sqlcon))
        {
            cmd.CommandType = CommandType.StoredProcedure;
    
            using (SqlDataAdapter da = new SqlDataAdapter(cmd))
            {
                DataTable dt = new DataTable();
    
                da.Fill(dt);
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用SqlDataAdapter

          SqlDataAdapter adapter = new SqlDataAdapter();
          SqlCommand cmd = new SqlCommand("usp_GetABCD", sqlcon);
          cmd.CommandType = CommandType.StoredProcedure;
          adapter.SelectCommand = cmd;
          DataTable dt = new DataTable();
          adapter.Fill(dt);
      

      【讨论】:

      • 我也是,虽然这段代码行不通,但数据适配器应该在它的构造函数中使用 cmd 或者在构建命令后设置。在当前状态下,这个数据适配器会抛出一个错误,首先告诉你连接没有初始化,然后一旦你修复它,它没有选择命令的命令文本。 ;]
      • -1 表示没有 using 块。 “两错不投赞成票”。
      • @JohnSaunders 跛脚的人,很跛脚。答案的重点是表明这可以使用 DataAdapter 来完成。这与 SQL 连接的正确资源处理无关。也许我还应该解释如何硬编码 SPROC 名称是一个坏主意?或者短变量名也不是最好的。 “两错不投赞成票”是什么意思?
      • @BFree:不,您根本不应该发布一些不知情的读者会复制并粘贴到他的实际应用程序中的错误代码。我也反对糟糕的异常处理。
      • @JohnSaunders 推动你的体重的方式......我可以负担 -2 代表点,但原则上我不能不同意更多。我的代码回答了这个问题,正确处理资源是每个人都应该熟悉的;对人们进行教育超出了这个有针对性的答案的范围。
      【解决方案4】:

      使用 SqlDataAdapter,这将简化一切。

      //Your code to this point
      DataTable dt = new DataTable();
      
      using(var cmd = new SqlCommand("usp_GetABCD", sqlcon))
      {
        using(var da = new SqlDataAdapter(cmd))
        {
            da.Fill(dt):
        }
      }
      

      只要您存储的过程返回数据集(光标),您的 DataTable 就会包含您要查找的信息。

      【讨论】:

      • @JohnSaunders 已修复。请删除,因为我对数据适配器对象而不是实现更感兴趣。不过你是完全正确的
      • using SqlDataAdapter 也请,然后我会删除。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-28
      • 2014-07-21
      • 2011-03-11
      相关资源
      最近更新 更多