当前位置:编程学习 > C#/ASP.NET >>

C#怎么把数据完整的插入到sql

C#怎么把数据完整的插入到sql,你们都是怎么做的?
我一个dataset里有三个表,如何保证数据的完整性?也就是要么全部插入,要么不插入任何数据。
由于我有的用户网络不稳定,经常断网,造成数据不完整,用事务的话,会独占,执行事务的时候,其他操作就不能执行。等待事务结束后,才能操作,这样会使并发操作的用户出现问题的。



如下面的图所示,我要把他改成什么形式,可以保证数据的完整性呢?我今天试用事务,但是事务没结束时,断网了,然后再连上网时,涉及到的表好像都被锁住了,都不能进行操作了。



用下图这种方式插入数据,也有断网,数据没能完全插入的可能,这种方式插入的速度比上图一条条插入的快。



大家都贴一下你们是怎么保证数据的完整性,把数据都插入到服务器的。提供商一下思路。 --------------------编程问答-------------------- 用事务啊

如果全部保存就提交,反之回滚 --------------------编程问答-------------------- 使用事务
具体参考:
http://msdn.microsoft.com/zh-cn/library/vstudio/86773566.aspx --------------------编程问答-------------------- Transaction应该可以吧,不Commit就是rollback. --------------------编程问答-------------------- 我是这样用的~


String ConnStr = "Data Source=.\\SQLEXPRESS;Database=DB;User ID=sa;Password=***";  //宣告_ConnStr為字串

//C#  SQLtransaction的使用方法
//步驟1:引用[System.Data.SqlClient],在C#中想對資料庫存取都要用到這個class,所以請記得Using 
//using System.Data.SqlClient

//步驟2: 建立SqlConnection,SqlCommand,SqlTransaction
//建立資料庫的連線
//(connstr為連線的字串,可以使用web.config中的connectionstring Tag設定)
SqlConnection conn = new SqlConnection(ConnStr);

//建立第一個cmd物件,用以執行SQL的指令
//(sqlstr為SQL語法,EX:select getdate(),conn為剛建立的資料庫連線物件)
SqlCommand cmd = new SqlCommand(@"INSERT INTO TableName( USER_001,USER_002,USER_003) VALUES ('test111','test111','test111') ", conn);

//建立第二個cmd物件,用以執行SQL的指令
//(sqlstr1為另一個SQL語法,EX:select getdate(),conn為剛建立的資料庫連線物件)
SqlCommand cmd1 = new SqlCommand(@"INSERT INTO TableName( USER_001,USER_002) VALUES ('test111','test111') ", conn);

//開始和DB做連線
conn.Open();

//建立交易物件
SqlTransaction trans1 = conn.BeginTransaction("trans1");

//從此行開始使用conn            
using (conn)
{
try
{
cmd.Transaction = trans1;    //指定cmd透過trans1做交易
cmd1.Transaction = trans1;   //指定cmd1透過trans1做交易
cmd.ExecuteNonQuery();
cmd1.ExecuteNonQuery();
trans1.Commit();             //完成交易
}
catch (SqlException ex)
{
trans1.Rollback();           //取消交易
MessageBox.Show(ex.ToString());
}
finally
{
DataTable dt = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter(@"Select * from TableName", conn);
adapter.Fill(dt);
dataGridView1.DataSource = dt;
}
}// 從此行會dispose conn

--------------------编程问答-------------------- 学习ing --------------------编程问答-------------------- 事务时必须的,在这种网络条件下,如果你想更好的确保性能和安全性,就不应该让客户端直接去操作数据库,
可以写个web服务,DataSet.GetChange()得到需要更新的数据或者传入sql语句的集合到web服务,让它去执行更新 --------------------编程问答-------------------- 当然这个web服务需要和db有良好的通信,最好是同一台服务器上 --------------------编程问答-------------------- 楼主的情况是典型的事务操作
建议将逻辑封装在存储过程里面 要么一起执行 要么一起回滚
让数据库去搞 程序不用关心 只要把数据传对了就行了
一般情况都采用存储过程封装 --------------------编程问答--------------------
引用 6 楼 glint 的回复:
事务时必须的,在这种网络条件下,如果你想更好的确保性能和安全性,就不应该让客户端直接去操作数据库,
可以写个web服务,DataSet.GetChange()得到需要更新的数据或者传入sql语句的集合到web服务,让它去执行更新

用事务的话,要独占资源诶,在他用这张表的时候,其他用户就不能同时操作这张表了,要等事务结束了,其他用户才能插入数据。 --------------------编程问答--------------------
引用 8 楼 lhx527099095 的回复:
楼主的情况是典型的事务操作
建议将逻辑封装在存储过程里面 要么一起执行 要么一起回滚
让数据库去搞 程序不用关心 只要把数据传对了就行了
一般情况都采用存储过程封装

我是插完上面的数据,然后才执行存储过程的,但是有时候数据没插完就断网了,也没执行到存储过程,就出现数据不完整。您能给个简单的例子吗? --------------------编程问答--------------------
引用 6 楼 glint 的回复:
事务时必须的,在这种网络条件下,如果你想更好的确保性能和安全性,就不应该让客户端直接去操作数据库,
可以写个web服务,DataSet.GetChange()得到需要更新的数据或者传入sql语句的集合到web服务,让它去执行更新

怎么来?能写个例子吗?我是在winform下的。 --------------------编程问答--------------------
引用 10 楼 lala133 的回复:
我是插完上面的数据,然后才执行存储过程的,但是有时候数据没插完就断网了,也没执行到存储过程,就出现数据不完整。您能给个简单的例子吗?


我的理解是你有三张表要一起插入 要么一起回滚数据对么?
这样的话 你就写一个存储过程
在存储过程里面先插第一张表 再插入第二张表 再插入第三张表
这样 要么三个表一起成功 要么都插入不成功
你要做的就是把三个表的数据一起通过参数传入就行了
其他的数据库做
你程序只调用一个存储过程
参数如果很多的话 建议用xml当参数吧
里面数据结构各种自己定义
到了数据库的存储过程在解析下 插入表即可
不知道讲清楚了么 --------------------编程问答-------------------- 没看到楼主代码里用事务。。。
方法上面已经说了,自己试吧,最好先查下事务的用法吧。 --------------------编程问答-------------------- 单一数据库 比如sql:SqlTransaction
多个数据库 比如同时插入到sql oracle:TransactionScope --------------------编程问答--------------------
引用 14 楼 zxy397472251 的回复:
单一数据库 比如sql:SqlTransaction
多个数据库 比如同时插入到sql oracle:TransactionScope

事务回滚时,相应的触发器数据会不会回滚啊?因为我这每次插入数据都会触发一个触发器。 --------------------编程问答--------------------
引用 12 楼 lhx527099095 的回复:
Quote: 引用 10 楼 lala133 的回复:

我是插完上面的数据,然后才执行存储过程的,但是有时候数据没插完就断网了,也没执行到存储过程,就出现数据不完整。您能给个简单的例子吗?


我的理解是你有三张表要一起插入 要么一起回滚数据对么?
这样的话 你就写一个存储过程
在存储过程里面先插第一张表 再插入第二张表 再插入第三张表
这样 要么三个表一起成功 要么都插入不成功
你要做的就是把三个表的数据一起通过参数传入就行了
其他的数据库做
你程序只调用一个存储过程
参数如果很多的话 建议用xml当参数吧
里面数据结构各种自己定义
到了数据库的存储过程在解析下 插入表即可
不知道讲清楚了么


清楚了,参数太多了。 --------------------编程问答-------------------- 用事务来插入数据,事务回滚时,相应的触发器数据会不会回滚啊?因为我这每次插入数据都会触发一个触发器。代码如下

 public void shuju()
        {
            using (SqlConnection conn = new SqlConnection(lianjie.sqcon))
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = conn;
                SqlTransaction tx = conn.BeginTransaction();
                cmd.Transaction = tx;
                try
                {
                   
                   int hangs = int.Parse(hangshu);

                    //销售出库表单
                    string xsckd2 = "insert into ERP_XSCKD (jbrj,danhj,kdsjj,xsmdj,bmbmj,xsckj,ckbmj,jinej,bdlxj,bdlxbmj,jbrghj) values ('" + denglu.name + "','" + shouyin.danhao + "',CONVERT(varchar(100), GETDATE(), 120),'" + xsmd + "','" + bmbm + "','" + cangkuming + "','" + cangkubianhao + "','0','销售出库单','300116','" + denglu.account + "')";
                    cmd.CommandText = xsckd2;
                    cmd.ExecuteNonQuery();
                    for (int i = 0; i < hangs; i++)
                    {

                        //----------------------------------------------------------【销售单、销售支付信息表和销售明细单】-----------------------------------------------------------------------------------       

                        #region//销售出库表单
                        if (i == 0)
                        {
                            #region//销售支付信息表
                            

                            //销售支付信息表
                            for (int j = 0; j < dataGridView1.RowCount; j++)
                            {
                                string XSZF = "insert into ERP_XSZF (danhj,xsckmxidj,zffsj,zffsbmj,zfjej) values ('" + shouyin.danhao + "','xsckmxid','" + dataGridView1.Rows[j].Cells[0].Value + "','" + dataGridView1.Rows[j].Cells[4].Value + "','" + dataGridView1.Rows[j].Cells[3].Value + "')";
                                cmd.CommandText = XSZF;
                                cmd.ExecuteNonQuery();
                            }
                            #endregion

                        }
                        #endregion

                        #region//销售出库明细表
                        string xsckd3 = "insert into ERP_XSCKMX (danhj,spmcj,sptmj,shulj,xfjej,cpbjj,xfzkj,hykj,kykdjj,hykdedmj,kdsjj,xsmdj,bmbmj,xsckj,ckbmj) values ('" + shouyin.danhao + "','" + ListP[i].Name.Trim() + "','" + ListP[i].Code.Trim() + "','" + ListP[i].Amount.Trim() + "','" + ListP[i].shifu.Trim() + "','" + ListP[i].yuanjia.Trim() + "','" + ListP[i].Discount.Trim() + "','" + huiyuan.hyk + "','" + huiyuan.kykdj + "','" + huiyuan.hykdedm + "',CONVERT(varchar(100), GETDATE(), 120),'" + xsmd + "','" + bmbm + "','" + cangkuming + "','" + cangkubianhao + "')";
                        cmd.CommandText = xsckd3;
                        cmd.ExecuteNonQuery();
                        #endregion
                    }
              

                    tx.Commit();
                    done = true;
                   
                }
                catch (Exception ex)
                {
                    tx.Rollback();
                    done = false;
                    throw new Exception(ex.ToString());
                }
            }
        }
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,