当前位置: 代码迷 >> C# >> C#写数据库有关问题
  详细解决方案

C#写数据库有关问题

热度:60   发布时间:2016-05-05 04:18:06.0
C#写数据库问题
代码片段如下:
                for (int i = 0; i < this.dataGridView1.RowCount; i++)
                {
                    for (int w = 0; w < this.dataGridView1.ColumnCount; w++)
                    {

                        try
                        {
                            //明细数据存储于 ERP_CS_DATASAVE 中(临时明细数据)
                            ERP_M8.constring.DBHelper.con.Close();
                            ERP_M8.constring.DBHelper.con.Open();
                            string jhdatattzw = this.dataGridView1.Columns[w].HeaderText.ToString();
                            string jhdatattyw = this.dataGridView2.Columns[w].HeaderText.ToString();
                            string jhdata = this.dataGridView1.Rows[i].Cells[w].Value.ToString();
                            string str = "ERP_CS_P_DATASAVE_PROC  '" + gzidtext.Text + "','" + djbh.Text + "','" + djbs.Text + "','" + djlx.Text + "','" + i + "','" + jhdatattzw + "','" + jhdatattyw + "','" + jhdata + "'";
                            SqlCommand sqlcom = new SqlCommand(str, ERP_M8.constring.DBHelper.con);
                            //ERP_M8.constring.DBHelper.con.Open();
                            sqlcom.ExecuteNonQuery();
                        }
                        catch
                        {

                        }
                        finally
                        {
                            ERP_M8.constring.DBHelper.con.Close();
                        }
                    }
                }

原因:这样写的原因是因为我的 dataGridView 是动态生成的,生成之前我是不清楚到底有多少个字段的,所以才用了这种笨办法。其实是很不愿意这样写的

问题:该代码有缺陷,效率很低,是一格一格的往数据库存储,如果有10行,10个字段,那么就将调用100次存储过程,写100次表,这样导致存储很慢

求助:(1) dataGridView 动态生成的情况,有没有更好的办法处理?
            (2)如果 dataGridView  不是动态生成的,有没有更好的办法处理?

------解决思路----------------------
现成的代码可以这样修改下,效率可能会提高一点

try
 {
              ERP_M8.constring.DBHelper.con.Close();
                ERP_M8.constring.DBHelper.con.Open();
         //启用事务
 ERP_M8.constring.DBHelper.con.BeginTransaction();
               string str = "ERP_CS_P_DATASAVE_PROC '{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}'";
               for (int i = 0; i < this.dataGridView1.RowCount; i++)
                {
                    for (int w = 0; w < this.dataGridView1.ColumnCount; w++)
                    {
                            //明细数据存储于 ERP_CS_DATASAVE 中(临时明细数据)
                            string jhdatattzw = this.dataGridView1.Columns[w].HeaderText.ToString();
                            string jhdatattyw = this.dataGridView2.Columns[w].HeaderText.ToString();
                            string jhdata = this.dataGridView1.Rows[i].Cells[w].Value.ToString();
                            string sql=string.Format(str,gzidtext.Text,djbh.Text,djbs.Text,djlx.Text,i,jhdatattzw,jhdatattyw,jhdata);
                            SqlCommand sqlcom = new SqlCommand(sql, ERP_M8.constring.DBHelper.con);
                            sqlcom.ExecuteNonQuery();
                        
                    }
                }
//事务提交
 ERP_M8.constring.DBHelper.con.Commit();
}
catch
{
//事务回滚
 ERP_M8.constring.DBHelper.con.Rollback()
}
 finally
 {
       ERP_M8.constring.DBHelper.con.Close();
 }
------解决思路----------------------
strproc = str + strproc;
你这样拼接,最终还是2000条SQL语句,而不是200条
------解决思路----------------------
你的具体逻辑看不太懂,而且命名方式实在是。。
按照我的理解,你就是想在不清楚dateGridView的RowCount、ColCount情况下,实现同步的数据库更新和显示是吧?
你可以看下这样行不行
在你的两层循环中间,用二维数组记录你要更新的数据,不要操作数据库。
循环结束后最后统一使用数据库事务的方式解决
给你贴一下关键的代码。
        /// <summary>
        /// 执行多条SQL语句,实现数据库事务。
        /// </summary>
        /// <param name="SQLStringList"></param>
        public void ExecuteSqlTran(List< SqlTextParas> SQLStringList)
        {
            using (OleDbConnection connection = new OleDbConnection(connectionString))
            {
                connection.Open();  //打开连接
                //创建事务对象
                using (OleDbTransaction trans = connection.BeginTransaction())
                {
                    OleDbCommand cmd = new OleDbCommand();
                    cmd.Connection = connection;
                    cmd.Transaction = trans; //指定事务
                    try
                    {
                        foreach (SqlTextParas myDE in SQLStringList)
                        {
                            string cmdText = myDE.SqlText;
                            OleDbParameter[] cmdParms = myDE.SqlParas;
                            cmd.CommandText = cmdText;
                            cmd.Parameters.AddRange(cmdParms);
                            int val = cmd.ExecuteNonQuery();
                            cmd.Parameters.Clear();
                        }
                        trans.Commit(); //提交事务
                    }
                    catch
                    {
                        trans.Rollback(); //插入失败则回滚操作
                        throw new Exception("插入失败");
                    }
                }
            }
        }

这里 SqlTextParas 是我自己定义的结构,描述很简单如下
public struct SqlTextParas
    {
        public string SqlText;
        public OleDbParameter[] SqlParas;
    }
就用上面的方法,通过循环里记录数据的数组构造出一组SQL语句和参数,通过事务方式一起更新
  相关解决方案