再献100分求:如何将dataGridView1里的数据批量插入、更新到SQL数据库

时间:2021-09-29 11:55:21
dataGridView1里有10列数据,分别为:A、B、C、D、E、F、G、H、I、J列,现只需要将A、B、C、D、I、J这6列数据写到数据库,其余4列只是界面显示时所用。另外还单独加3列数据分别为X、Y、Z列,这3列数据分别为0001,ABC01,2011010608,每行都显示一样的数据。
对于这些要求,已经采用一个方法将需要的数据得到单独的一个DataSet。

(之前问过说SqlCommandBuilder 类可以实现,也在网上搜了很多,但几乎都是要绑定dataGridView1数据源才可以,但由于程序设计需要不能绑定数据源,故再次向大家求助,看有没有希望解决。如果方面,可QQ联系我:516920313)


现在的问题是:

1、如何将得到的DataSet数据批量更新到数据库中,最好能有更新时考虑数据库锁与数据回滚机制。

2、得到的DataSet数据与数据库现在数据相比,有可能有新增行,或删除行,更新能否一并处理?

30 个解决方案

#1


for example

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {

                SqlConnection con = DB.CreateCon();

                con.Open();

                string[] test ={ "a", "b", "c" };
                string[] arr ={"1","2","3" };
                string[] ok ={"m","n","o" };

                String SqlStr = "select * from test";

                //新建内存表dt
                DataTable dt = new DataTable("test");

                dt.Columns.Add("test", System.Type.GetType("System.String"));
                dt.Columns.Add("arr", System.Type.GetType("System.String"));
                dt.Columns.Add("ok", System.Type.GetType("System.String"));

                //增加数组里的数据
                for (int i = 0; i < arr.Length; i++)
                {
                    DataRow row = dt.NewRow();

                    row["test"] = test[i];
                    row["arr"] = arr[i];
                    row["ok"] = ok[i];

                    dt.Rows.Add(row);

                    //显示当前行的状态

                    Console.Write(row[0].ToString());

                }

                //建立sql适配器

                SqlDataAdapter dap = new SqlDataAdapter(SqlStr,con);

                SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(dap);
                
                //建立sql数据集 并且更新数据库
                  DataSet ds = new DataSet();
                  
                  ds.Tables.Add(dt);
                  
                  int val = dap.Update(ds, "test");

                  ds.AcceptChanges();

            }
            catch(SqlException ex)
            {
                Console.Write(ex.Errors);
            }


        }
    }

    class DB
    {
      public static SqlConnection CreateCon()
      {
        return new SqlConnection("server=WWW-16EA86D80FF;uid=sa;Pwd=1;database=test");
      }

    }
}

#3


foreach循环每一行,即可.

#4


在程序中遍历DataSet 然后构造sql语句,使用Transation 提交

#5


入库的时候用事务啊......

#6


dataset使用sqltransaction操作
SqlConnection conn = new SqlConnection("");   
adapter.UpdateCommand.Transaction = Trans;  
adapter.Update(ds);  
  Trans.Commit();  
    

#7


郁闷,就是搞不定。

我根据现在dataGridView1里的数据,重新生成一个DataSet ds=需要更新到数据库里的数据(跟数据库的字段完全一致)

我想将这个ds数据集更新到SQL中,总也不成功!

#8


1. 遍历DataSet中DataTable的每一行DataRow
2. 根据当前DataRow的状态决定是应该insert,delete还是update,然后构造sql语句
3. 使用transaction执行sql语句

这是我能想到的最笨的方法

#9


该回复于2011-01-11 08:35:19被版主删除

#10


我自己写了一个方法,可是执行没有任何反应,数据库的数据也没有更新,请大家帮我看一看:
public bool OperateSqlDatabase(DataSet dataSet,string sqlStr, string tableName)
{
   using (SqlConnection con = new SqlConnection(connectionStr))
   {
       SqlDataAdapter adapter = new SqlDataAdapter(sqlStr, con);
       SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
       con.Open();
       using (SqlTransaction myTrans = con.BeginTransaction())   
       try
            {                        
               adapter.UpdateCommand.Transaction = yTrans;                             
                 adapter.Update(dataSet, tableName);
               myTrans.Commit();           
               return true;
             }
             catch (Exception ex)
             {
                 try
                 {
                     myTrans.Rollback();                                 //事务回滚
                        throw new Exception("SQL数据库连接失败,操作数据库产生错误: " + ex.Message);
                 }
                 catch (Exception er)
                 {
                     if (myTrans.Connection != null)
                     {
                         throw new Exception("数据回滚事务遇到一个异常类型 : " + er.GetType());
                      }
                  }
                  return false;
            }
            finally
            {
                con.Close();        //断开连接
              }
}
        }

#11


下面这个方法可以实现新增数据了,不知道能不能同时更新两个数据表?

更新数据时会提示已存在记录不能重复,应该是直接更新语句,又不是插入数据,怎么会有这个提示?

另外就是整个过程缺少事务处理,不知道该怎么加上去?
    
public void DataSetUpdate(DataSet ds, string connectstr, string tablename, string sqlstr)
  {
  try
  {
  SqlDataAdapter adapter = new SqlDataAdapter(sqlstr, connectstr);

  //使用SqlCommandBuilder 对像填充SqlDataAdapter 的InsertCommand、DeleteCommand、UpdateCommand对像
  SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(adapter);


  int val = adapter.Update(ds, tablename);
  ds.AcceptChanges();
  }
  catch
  {
  throw;
  }
  }

#12


using (SqlTransaction myTrans = con.BeginTransaction())  
  try
  {  
  adapter.UpdateCommand.Transaction = yTrans;   


 myTrans     yTrans?

#13


学习 我要弄access数据库的 也纠结着捏 关注下你这个。。应该对我有帮助

#14


adapter.Update(ds, tablename);
为什么会有插入相同数据,提行数据重复,按理有相同主键的只会更新动作,不会有插入动作呀。

#15


这个简单,网上案例太多了,好好学习

#16


该回复于2011-01-11 09:32:04被版主删除

#17


该回复于2011-01-11 09:32:04被版主删除

#18


都让他们说没了...

#19


我代码是这样的,为什么在dataGridView1新增的数据可以正常到数据库,如果数据库有记录修改再保存就会报违反约束,感觉是重新插入数据到数据库一样。
using (SqlConnection connection = new SqlConnection(RunSqlClass.connectionStr))
                    {
                        SqlDataAdapter adapter = new SqlDataAdapter();
                        adapter.SelectCommand = new SqlCommand(sqlStr, connection);
                        SqlCommandBuilder builder = new SqlCommandBuilder(adapter);

                        connection.Open();                       

            
                        adapter.Fill(ds, ds.Tables[0].TableName);

                        adapter.Update(ds, ds.Tables[0].TableName);
                    }

#20


耐心看看这篇文章,会对你有帮助!
http://www.switchonthecode.com/tutorials/csharp-tutorial-binding-a-datagridview-to-a-database

by the user in the DataGridView will automically be made to the DataTable, dTable. Now we need a way to get the changes back into the database. All you have to do is call the Update function of the OleDbDataAdapter with the DataTable as the argument to accomplish this.

dAdapter.Update(dTable);

This call will use the OleDbCommandBuilder to create all of the necessary SQL code to synchronize your database with the changes made to dTable. But, when should you call this function? There's lots of different answers to that. If you have a save button, call it when the user pushes save. If you want the database updated in real-time, I like to call it on the DataGridView's Validating event.

#21


英文看不懂,我测试代码:
using (SqlConnection connection = new SqlConnection(RunSqlClass.connectionStr))
                    {
                        SqlDataAdapter myAdapter = new SqlDataAdapter();
                        SqlCommand myCommand = new SqlCommand(sqlStr, connection);
                        myAdapter.SelectCommand = myCommand;
                        SqlCommandBuilder myCommandBuilder = new SqlCommandBuilder(myAdapter);

                        myAdapter.Update(ds, ds.Tables[0].TableName);
                    }

没有搞懂,新增的数据保存时没有问题,修改数据保存就会提示:
违反了 PRIMARY KEY 约束 'PK_TC'。不能在对象 'dbo.TC' 中插入重复键。
语句已终止。

感觉修改数据时也插入了数据,不知道哪时错了?!!!

#22


这个问题郁闷好多天,感觉只是新增插入数据,没有修改动作!是哪里错了。

#23


感觉还是你的SQL语句或存储过程错误,你拿到SQL语句到查询分析器上跑跑试试

#24


我对这个理解不是很透彻,针对21楼我的理解是这样的:
我需要ds里的数据与数据库对应,是新增就插入数据,是修改的就直接修改,是删除的就删除数据库的内容。现在就只实现了插入,其余两个没有实现。

#25


引用 21 楼 yanele 的回复:
英文看不懂,我测试代码:
using (SqlConnection connection = new SqlConnection(RunSqlClass.connectionStr))
  {
  SqlDataAdapter myAdapter = new SqlDataAdapter();
  SqlCommand myCommand = new SqlCommand(sqlStr, ……

这句SqlCommand myCommand = new SqlCommand(sqlStr, connection);
这里的sqlStr我说的SQL语句说的就是这个

#26


我觉得可能是你在sqlStr里写的都是insert,update代码

#27


没有update 的语句可能是

#28


sqlStr语句我写的是SELECT * FROM table,难道还要写insert,update,delete代码?

具体该怎么写呢?update不是要写具体更新那个字段吗?delete也要写清删除哪一行。

#29


说明一下,
1.一定要有pramary index 在 select * from ....
2.一定是一个独立的表  select * from table ,不能是集合的query ,
3.编译此datagrid 时,只能一个人在操作,否则就冲突..

     DataTable dt;
        SqlDataAdapter sad;
        DataSet ds;
        SqlCommandBuilder scbBuilder = null;


//              string sqlStr = " execute fd_getWareData  '" +date1.Value.Date.ToString() + "','" + date2.Value .Date.ToString() + "','" + jinhouclasstext.Text +"','"+chuhouclasstext.Text +"','" +boolFallinFD.ToString ()+"','"+optionChoose+ "'";
                string sqlStr = "exec fd_fdTypeInvoice '" + FDWareClass.loginUserCode + "'";
                //MessageBox.Show(sqlStr );

                //SqlDataAdapter sad = new SqlDataAdapter(sqlStr, conn);
                sad = new SqlDataAdapter(sqlStr, conn);

                scbBuilder = new SqlCommandBuilder(sad);




                ds = new DataSet();
                sad.Fill(ds, "result");
                this.dt = ds.Tables["result"];
                conn.Close();


sad.Update(ds , "result");
            ds.AcceptChanges();

#30


http://topic.****.net/u/20110111/15/61eee9b2-7475-4875-8fe5-2ea0d0767db9.html
在这个贴中找到了答案。

#1


for example

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {

                SqlConnection con = DB.CreateCon();

                con.Open();

                string[] test ={ "a", "b", "c" };
                string[] arr ={"1","2","3" };
                string[] ok ={"m","n","o" };

                String SqlStr = "select * from test";

                //新建内存表dt
                DataTable dt = new DataTable("test");

                dt.Columns.Add("test", System.Type.GetType("System.String"));
                dt.Columns.Add("arr", System.Type.GetType("System.String"));
                dt.Columns.Add("ok", System.Type.GetType("System.String"));

                //增加数组里的数据
                for (int i = 0; i < arr.Length; i++)
                {
                    DataRow row = dt.NewRow();

                    row["test"] = test[i];
                    row["arr"] = arr[i];
                    row["ok"] = ok[i];

                    dt.Rows.Add(row);

                    //显示当前行的状态

                    Console.Write(row[0].ToString());

                }

                //建立sql适配器

                SqlDataAdapter dap = new SqlDataAdapter(SqlStr,con);

                SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(dap);
                
                //建立sql数据集 并且更新数据库
                  DataSet ds = new DataSet();
                  
                  ds.Tables.Add(dt);
                  
                  int val = dap.Update(ds, "test");

                  ds.AcceptChanges();

            }
            catch(SqlException ex)
            {
                Console.Write(ex.Errors);
            }


        }
    }

    class DB
    {
      public static SqlConnection CreateCon()
      {
        return new SqlConnection("server=WWW-16EA86D80FF;uid=sa;Pwd=1;database=test");
      }

    }
}

#2


#3


foreach循环每一行,即可.

#4


在程序中遍历DataSet 然后构造sql语句,使用Transation 提交

#5


入库的时候用事务啊......

#6


dataset使用sqltransaction操作
SqlConnection conn = new SqlConnection("");   
adapter.UpdateCommand.Transaction = Trans;  
adapter.Update(ds);  
  Trans.Commit();  
    

#7


郁闷,就是搞不定。

我根据现在dataGridView1里的数据,重新生成一个DataSet ds=需要更新到数据库里的数据(跟数据库的字段完全一致)

我想将这个ds数据集更新到SQL中,总也不成功!

#8


1. 遍历DataSet中DataTable的每一行DataRow
2. 根据当前DataRow的状态决定是应该insert,delete还是update,然后构造sql语句
3. 使用transaction执行sql语句

这是我能想到的最笨的方法

#9


该回复于2011-01-11 08:35:19被版主删除

#10


我自己写了一个方法,可是执行没有任何反应,数据库的数据也没有更新,请大家帮我看一看:
public bool OperateSqlDatabase(DataSet dataSet,string sqlStr, string tableName)
{
   using (SqlConnection con = new SqlConnection(connectionStr))
   {
       SqlDataAdapter adapter = new SqlDataAdapter(sqlStr, con);
       SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
       con.Open();
       using (SqlTransaction myTrans = con.BeginTransaction())   
       try
            {                        
               adapter.UpdateCommand.Transaction = yTrans;                             
                 adapter.Update(dataSet, tableName);
               myTrans.Commit();           
               return true;
             }
             catch (Exception ex)
             {
                 try
                 {
                     myTrans.Rollback();                                 //事务回滚
                        throw new Exception("SQL数据库连接失败,操作数据库产生错误: " + ex.Message);
                 }
                 catch (Exception er)
                 {
                     if (myTrans.Connection != null)
                     {
                         throw new Exception("数据回滚事务遇到一个异常类型 : " + er.GetType());
                      }
                  }
                  return false;
            }
            finally
            {
                con.Close();        //断开连接
              }
}
        }

#11


下面这个方法可以实现新增数据了,不知道能不能同时更新两个数据表?

更新数据时会提示已存在记录不能重复,应该是直接更新语句,又不是插入数据,怎么会有这个提示?

另外就是整个过程缺少事务处理,不知道该怎么加上去?
    
public void DataSetUpdate(DataSet ds, string connectstr, string tablename, string sqlstr)
  {
  try
  {
  SqlDataAdapter adapter = new SqlDataAdapter(sqlstr, connectstr);

  //使用SqlCommandBuilder 对像填充SqlDataAdapter 的InsertCommand、DeleteCommand、UpdateCommand对像
  SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(adapter);


  int val = adapter.Update(ds, tablename);
  ds.AcceptChanges();
  }
  catch
  {
  throw;
  }
  }

#12


using (SqlTransaction myTrans = con.BeginTransaction())  
  try
  {  
  adapter.UpdateCommand.Transaction = yTrans;   


 myTrans     yTrans?

#13


学习 我要弄access数据库的 也纠结着捏 关注下你这个。。应该对我有帮助

#14


adapter.Update(ds, tablename);
为什么会有插入相同数据,提行数据重复,按理有相同主键的只会更新动作,不会有插入动作呀。

#15


这个简单,网上案例太多了,好好学习

#16


该回复于2011-01-11 09:32:04被版主删除

#17


该回复于2011-01-11 09:32:04被版主删除

#18


都让他们说没了...

#19


我代码是这样的,为什么在dataGridView1新增的数据可以正常到数据库,如果数据库有记录修改再保存就会报违反约束,感觉是重新插入数据到数据库一样。
using (SqlConnection connection = new SqlConnection(RunSqlClass.connectionStr))
                    {
                        SqlDataAdapter adapter = new SqlDataAdapter();
                        adapter.SelectCommand = new SqlCommand(sqlStr, connection);
                        SqlCommandBuilder builder = new SqlCommandBuilder(adapter);

                        connection.Open();                       

            
                        adapter.Fill(ds, ds.Tables[0].TableName);

                        adapter.Update(ds, ds.Tables[0].TableName);
                    }

#20


耐心看看这篇文章,会对你有帮助!
http://www.switchonthecode.com/tutorials/csharp-tutorial-binding-a-datagridview-to-a-database

by the user in the DataGridView will automically be made to the DataTable, dTable. Now we need a way to get the changes back into the database. All you have to do is call the Update function of the OleDbDataAdapter with the DataTable as the argument to accomplish this.

dAdapter.Update(dTable);

This call will use the OleDbCommandBuilder to create all of the necessary SQL code to synchronize your database with the changes made to dTable. But, when should you call this function? There's lots of different answers to that. If you have a save button, call it when the user pushes save. If you want the database updated in real-time, I like to call it on the DataGridView's Validating event.

#21


英文看不懂,我测试代码:
using (SqlConnection connection = new SqlConnection(RunSqlClass.connectionStr))
                    {
                        SqlDataAdapter myAdapter = new SqlDataAdapter();
                        SqlCommand myCommand = new SqlCommand(sqlStr, connection);
                        myAdapter.SelectCommand = myCommand;
                        SqlCommandBuilder myCommandBuilder = new SqlCommandBuilder(myAdapter);

                        myAdapter.Update(ds, ds.Tables[0].TableName);
                    }

没有搞懂,新增的数据保存时没有问题,修改数据保存就会提示:
违反了 PRIMARY KEY 约束 'PK_TC'。不能在对象 'dbo.TC' 中插入重复键。
语句已终止。

感觉修改数据时也插入了数据,不知道哪时错了?!!!

#22


这个问题郁闷好多天,感觉只是新增插入数据,没有修改动作!是哪里错了。

#23


感觉还是你的SQL语句或存储过程错误,你拿到SQL语句到查询分析器上跑跑试试

#24


我对这个理解不是很透彻,针对21楼我的理解是这样的:
我需要ds里的数据与数据库对应,是新增就插入数据,是修改的就直接修改,是删除的就删除数据库的内容。现在就只实现了插入,其余两个没有实现。

#25


引用 21 楼 yanele 的回复:
英文看不懂,我测试代码:
using (SqlConnection connection = new SqlConnection(RunSqlClass.connectionStr))
  {
  SqlDataAdapter myAdapter = new SqlDataAdapter();
  SqlCommand myCommand = new SqlCommand(sqlStr, ……

这句SqlCommand myCommand = new SqlCommand(sqlStr, connection);
这里的sqlStr我说的SQL语句说的就是这个

#26


我觉得可能是你在sqlStr里写的都是insert,update代码

#27


没有update 的语句可能是

#28


sqlStr语句我写的是SELECT * FROM table,难道还要写insert,update,delete代码?

具体该怎么写呢?update不是要写具体更新那个字段吗?delete也要写清删除哪一行。

#29


说明一下,
1.一定要有pramary index 在 select * from ....
2.一定是一个独立的表  select * from table ,不能是集合的query ,
3.编译此datagrid 时,只能一个人在操作,否则就冲突..

     DataTable dt;
        SqlDataAdapter sad;
        DataSet ds;
        SqlCommandBuilder scbBuilder = null;


//              string sqlStr = " execute fd_getWareData  '" +date1.Value.Date.ToString() + "','" + date2.Value .Date.ToString() + "','" + jinhouclasstext.Text +"','"+chuhouclasstext.Text +"','" +boolFallinFD.ToString ()+"','"+optionChoose+ "'";
                string sqlStr = "exec fd_fdTypeInvoice '" + FDWareClass.loginUserCode + "'";
                //MessageBox.Show(sqlStr );

                //SqlDataAdapter sad = new SqlDataAdapter(sqlStr, conn);
                sad = new SqlDataAdapter(sqlStr, conn);

                scbBuilder = new SqlCommandBuilder(sad);




                ds = new DataSet();
                sad.Fill(ds, "result");
                this.dt = ds.Tables["result"];
                conn.Close();


sad.Update(ds , "result");
            ds.AcceptChanges();

#30


http://topic.****.net/u/20110111/15/61eee9b2-7475-4875-8fe5-2ea0d0767db9.html
在这个贴中找到了答案。