【问题标题】:Execute SQL command and output result to DataGridView in C#在 C# 中执行 SQL 命令并将结果输出到 DataGridView
【发布时间】:2013-07-16 10:44:30
【问题描述】:

我正在尝试使用 C# 通过 OleDbConnection 在 Access 数据库上执行 SQL 命令,并使用该信息在 Windows 窗体上填充 DataGridView。我已经打开了连接、陈述了查询并执行了它,但是我找不到如何将结果输出到 windows 窗体上的 DataGridView(名为 dataOutput)。

    private void Query()
    {
        string cmdText = "SELECT * FROM RetentionTable " +
            "WHERE [DateTime] BETWEEN '" + getDateTimeFrom("") + "' AND '" + getDateTimeTo("") + "'";

        string ConnectionPath = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=RetentionDB.mdb";

        try
        {
            OleDbConnection cn = new OleDbConnection(ConnectionPath);
            DataSet objDataSet = new DataSet();
            OleDbDataAdapter objDataAdapter = new OleDbDataAdapter();

            if (cn.State.Equals(ConnectionState.Closed))
            {
                cn.Open();
            }

            OleDbCommand OleDbSearch = new OleDbCommand(cmdText, cn);
            OleDbSearch.ExecuteNonQuery();

            objDataAdapter.Fill(objDataSet);
            dataOutput.DataSource = objDataSet;
            cn.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message.ToString());
            MessageBox.Show(ex.StackTrace.ToString());
        }

    }

据我所知,查询正在正确执行,但在尝试使用 objDataAdapter.Fill 时出现问题。我想我不明白如何用查询的输出填充数据集。任何帮助将非常感激。谢谢!

【问题讨论】:

    标签: c# sql winforms ms-access


    【解决方案1】:

    替换为ExecuteDataSet method

    ..
    OleDbSearch.ExecuteDataSet();
    objDataAdapter.Fill(objDataSet);
    dataOutput.DataSource = objDataSet;
    ...
    

    我建议您使用 blok 或尝试使用 finally of your try catch 设置您的紧密连接

    最佳实践

     using( var cn = new OleDbConnection(ConnectionPath))
     {
        ... 
     }
    

    【讨论】:

      【解决方案2】:

      几个cmets:

      1. 您的查询受到 SQL 注入的影响。请改用参数化查询。
      2. 您不需要打开/关闭连接; DataAdapter 会为您做到这一点。
      3. 您应该将OleDbConnectionOleDbCommand 对象包装在using 块中,以确保清理它们的资源。
      4. 您不需要在命令上调用ExecuteNonQuery 或任何其他Execute... 方法;
      5. 您需要将命令分配给OleDbDataAdapterSelectCommand 属性,或者将其传递给构造函数。

      试试这样的:

      private void Query()
      {
         const string ConnectionPath = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=RetentionDB.mdb";
      
         try
         {
            using (var cn = new OleDbConnection(ConnectionPath))
            using (var cmd = new OleDbCommand("SELECT * FROM RetentionTable WHERE [DateTime] BETWEEN ? And ?"))
            {
               // Parameter names don't matter; OleDb uses positional parameters.
               cmd.Parameters.AddWithValue("@p0", getDateTimeFrom(""));
               cmd.Parameters.AddWithValue("@p1", getDateTimeTo(""));
      
               var objDataSet = new DataSet();
               var objDataAdapter = new OleDbDataAdapter(cmd);
               objDataAdapter.Fill(objDataSet);
      
               dataOutput.DataSource = objDataSet;
            }
         }
         catch (Exception ex)
         {
            MessageBox.Show(ex.Message.ToString());
            MessageBox.Show(ex.StackTrace.ToString());
         }
      }
      

      【讨论】:

      • 所以我这样做了,它似乎执行正确,但网格视图中没有显示数据。它只是显示没有条目。我有 AutoGenerateColuns = true,但没有数据。有什么想法吗?
      【解决方案3】:

      我认为您也可以将数据加载到 DataTable 中并将 DataGridView 指向该表:

      DataTable dt = new DataTable();
      dt.Fill(OleDbSearch.ExecuteReader());
      dataOutput.DataSource = dt;
      

      【讨论】:

        【解决方案4】:

        您不应执行OleDbSearch.ExecuteNonQuery,这仅用于修改数据的查询(INSERT/UPDATE)。而是将您的命令分配给 dataadatper:

        objDataAdapter.SelectCommand = OleDbSearch;
        

        然后执行Fill 和数据源分配。

        【讨论】:

          【解决方案5】:

          使用OleDbDataAdapter 检索DataSet 的正确方法是将OleDbCommand 关联到OleDbDataAdapter 的SelectCommand 属性。您只需将 OleDbCommand 传递给 OleDbDataAdapter 的构造函数。

          您的代码还应该对命令文本使用参数化查询,而不是字符串连接。使用参数化查询可以避免 Sql 注入,并且正确解析文本、日期、小数变量由框架代码完成。

             string cmdText = "SELECT * FROM RetentionTable WHERE [DateTime] BETWEEN ? AND ?";
             string ConnectionPath = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=RetentionDB.mdb";
             try
             {
                  using(OleDbConnection cn = new OleDbConnection(ConnectionPath))
                  using(OleDbCommand OleDbSearch = new OleDbCommand(cmdText, cn))
                  using(OleDbDataAdapter objDataAdapter = new OleDbDataAdapter(OleDbSearch))
                  {
                      OleDbSearch.Parameters.AddWithValue("@p1", getDateTimeFrom(""));
                      OleDbSearch.Parameters.AddWithValue("@p2", getDateTimeTo(""));
                      DataSet objDataSet = new DataSet();
                      cn.Open();
                      objDataAdapter.Fill(objDataSet);
                      dataOutput.DataSource = objDataSet;
                  }
              }
              catch (Exception ex)
              {
                   MessageBox.Show(ex.Message.ToString());
                   MessageBox.Show(ex.StackTrace.ToString());
              }
          

          using statement 是另一个需要注意的地方。这将确保在出现异常时正确关闭和处理连接、命令和适配器。

          【讨论】:

          • 这给了我一个错误,显示“在调用“填充”之前,SelectCommand 属性没有被初始化。
          • 这真的很奇怪。从这里的文档中可以看到msdn.microsoft.com/en-us/library/0wz82t73.aspx 将 OleDbCommand 传递给 OleDbDataAdapter 的构造函数分配 SelectCommand 属性
          猜你喜欢
          • 2015-01-07
          • 2016-03-21
          • 1970-01-01
          • 2013-03-27
          • 2016-06-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-01
          相关资源
          最近更新 更多