SQL 批量写入数据SqlBulkCopy方式,怎么样在插入过程跳过不符合约束的数据?

back1999 2016-08-03 03:21:25
如果现在表中有主键约束或者唯一键约束或者检查约束,那么怎么样才能在批量插入时,忽略不符合这些约束的数据,将其他数据插入到数据库中?大神还是不要说经过临时表中转了,这样性能太差了。。。
另外SqlBulkCopyOptions.CheckConstraints这个属性究竟是什么意思?网上通篇都是复制粘贴,加了这个和不加这个到底区别在什么地方呢?
...全文
663 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
吉普赛的歌 2016-08-08
  • 打赏
  • 举报
回复
引用 12 楼 back1999 的回复:
肯定测试了啊,但是我问的不是快慢,我问的是检查约束有什么作用,测试程序不管是否加上这个属性,程序都会报错
贴出你的测试代码, 空口无凭
back1999 2016-08-08
  • 打赏
  • 举报
回复
引用 10 楼 yenange 的回复:
[quote=引用 9 楼 back1999 的回复:] [quote=引用 8 楼 yenange 的回复:] 你试验一下就知道了, 不可能避开主键约束。 最多只可能是默认约束。 唯一的好处就是能快一点。 数据库的增删改操作怕约束、触发器、索引, 有这些就快不起来。 没时间试验, 以前的一篇博客, 你在上面的基础上稍稍改一下就可以测试了。 http://blog.csdn.net/yenange/article/details/35837247
我就想知道一个问题,SqlBulkCopyOptions.CheckConstraints这个属性到底起什么作用,检查约束,检查什么约束?不使用又会怎么样?[/quote] 不要约束就快, 用的话慢一点但会受到限制 你花 5 分钟测试一下又如何?问问题都不止5分钟了[/quote] 肯定测试了啊,但是我问的不是快慢,我问的是检查约束有什么作用,测试程序不管是否加上这个属性,程序都会报错
吉普赛的歌 2016-08-05
  • 打赏
  • 举报
回复
用的话慢一点但会受到限制 => 用的话慢一点但约束方面会更完善
吉普赛的歌 2016-08-05
  • 打赏
  • 举报
回复
引用 9 楼 back1999 的回复:
[quote=引用 8 楼 yenange 的回复:] 你试验一下就知道了, 不可能避开主键约束。 最多只可能是默认约束。 唯一的好处就是能快一点。 数据库的增删改操作怕约束、触发器、索引, 有这些就快不起来。 没时间试验, 以前的一篇博客, 你在上面的基础上稍稍改一下就可以测试了。 http://blog.csdn.net/yenange/article/details/35837247
我就想知道一个问题,SqlBulkCopyOptions.CheckConstraints这个属性到底起什么作用,检查约束,检查什么约束?不使用又会怎么样?[/quote] 不要约束就快, 用的话慢一点但会受到限制 你花 5 分钟测试一下又如何?问问题都不止5分钟了
back1999 2016-08-05
  • 打赏
  • 举报
回复
引用 8 楼 yenange 的回复:
你试验一下就知道了, 不可能避开主键约束。 最多只可能是默认约束。 唯一的好处就是能快一点。 数据库的增删改操作怕约束、触发器、索引, 有这些就快不起来。 没时间试验, 以前的一篇博客, 你在上面的基础上稍稍改一下就可以测试了。 http://blog.csdn.net/yenange/article/details/35837247
我就想知道一个问题,SqlBulkCopyOptions.CheckConstraints这个属性到底起什么作用,检查约束,检查什么约束?不使用又会怎么样?
吉普赛的歌 2016-08-05
  • 打赏
  • 举报
回复
你试验一下就知道了, 不可能避开主键约束。 最多只可能是默认约束。 唯一的好处就是能快一点。 数据库的增删改操作怕约束、触发器、索引, 有这些就快不起来。 没时间试验, 以前的一篇博客, 你在上面的基础上稍稍改一下就可以测试了。 http://blog.csdn.net/yenange/article/details/35837247
back1999 2016-08-05
  • 打赏
  • 举报
回复
引用 6 楼 wwhtkill 的回复:
[quote=引用 5 楼 back1999 的回复:] [quote=引用 3 楼 wwhtkill 的回复:] 中间表 应该已经是最快的方法了 ,因为它可以让你做到 批量插入 批量比对约束。 你用的这个是开启事务模式 你没有设置BatchSize属性吧 这个是把几条数据作为一个事务插入 失败了只会回滚这个批次的事务 可以做到你的要求 但是你要 BatchSize=1 但是这样 会非常非常慢。。。。
SqlTransaction sqlbulkTransaction = conn.BeginTransaction(); try { using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn, option, sqlbulkTransaction)) { bulkCopy.BulkCopyTimeout = 100; bulkCopy.BatchSize = 1000; bulkCopy.DestinationTableName = tableName; bulkCopy.WriteToServer(table); sqlbulkTransaction.Commit(); } } 我想问下哈,这个Batchsize如果按照我这样设置成1000,那么如果我在table中写入超过1000行的数据的时候,内部是怎么操作的,我在外面显式开启一个事务,bulkCopy内部还会另外开启一些事务来应对这个BatchSize么?另外如果这地方捕获到异常,那么我对sqlbulkTransaction这个事务进行回滚,bulkCopy内部的所有操作都能够回滚?但是如果BUlkCopy按照之前说的,针对BatchSize进行多个事务提交的话,那么这个地方再回滚应该达不到目的了吧?[/quote] 比如说有1500行数据要写入数据库 Batchsize=1000 那么 1000条是一个事务 后500条是一个 这2个事务是单独回滚的 你可以简单理解为页的概念 每个页都是单独的事务。 但是这个并不能满足你的需求 因为你不能确定触发约束的行是如何分布的 它们的数量你都无法确定 最坏的结果就是 每页都触发了错误 。 你现在这个是把抽取数据和清洗数据给做到一步里面了 这个其实是不符合规范的,源数据来了是什么样子就是什么样子 清洗要单独处理 因为清洗数据一般都跟业务挂钩了。 问一下 你 目标表 和源的数量级能达到多少 批量比对约束效率应该是非常高的。[/quote] 那这个东东岂不是很鸡肋么,不可能每个表都是正常的啥约束啊都没有,万一有的话,就直接报错了。想不报错还需要使用临时表,用临时表的话还用这个有什么用。。。。 另外想问下上面问的,SqlBulkCopyOptions.CheckConstraints这个属性到底起什么作用,.net只说是检查约束,网上也是全复制粘贴,我想问用这个和不用这个的区别在什么地方呢?
wwhtkill 2016-08-04
  • 打赏
  • 举报
回复
引用 5 楼 back1999 的回复:
[quote=引用 3 楼 wwhtkill 的回复:] 中间表 应该已经是最快的方法了 ,因为它可以让你做到 批量插入 批量比对约束。 你用的这个是开启事务模式 你没有设置BatchSize属性吧 这个是把几条数据作为一个事务插入 失败了只会回滚这个批次的事务 可以做到你的要求 但是你要 BatchSize=1 但是这样 会非常非常慢。。。。
SqlTransaction sqlbulkTransaction = conn.BeginTransaction(); try { using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn, option, sqlbulkTransaction)) { bulkCopy.BulkCopyTimeout = 100; bulkCopy.BatchSize = 1000; bulkCopy.DestinationTableName = tableName; bulkCopy.WriteToServer(table); sqlbulkTransaction.Commit(); } } 我想问下哈,这个Batchsize如果按照我这样设置成1000,那么如果我在table中写入超过1000行的数据的时候,内部是怎么操作的,我在外面显式开启一个事务,bulkCopy内部还会另外开启一些事务来应对这个BatchSize么?另外如果这地方捕获到异常,那么我对sqlbulkTransaction这个事务进行回滚,bulkCopy内部的所有操作都能够回滚?但是如果BUlkCopy按照之前说的,针对BatchSize进行多个事务提交的话,那么这个地方再回滚应该达不到目的了吧?[/quote] 比如说有1500行数据要写入数据库 Batchsize=1000 那么 1000条是一个事务 后500条是一个 这2个事务是单独回滚的 你可以简单理解为页的概念 每个页都是单独的事务。 但是这个并不能满足你的需求 因为你不能确定触发约束的行是如何分布的 它们的数量你都无法确定 最坏的结果就是 每页都触发了错误 。 你现在这个是把抽取数据和清洗数据给做到一步里面了 这个其实是不符合规范的,源数据来了是什么样子就是什么样子 清洗要单独处理 因为清洗数据一般都跟业务挂钩了。 问一下 你 目标表 和源的数量级能达到多少 批量比对约束效率应该是非常高的。
back1999 2016-08-03
  • 打赏
  • 举报
回复
引用 3 楼 wwhtkill 的回复:
中间表 应该已经是最快的方法了 ,因为它可以让你做到 批量插入 批量比对约束。 你用的这个是开启事务模式 你没有设置BatchSize属性吧 这个是把几条数据作为一个事务插入 失败了只会回滚这个批次的事务 可以做到你的要求 但是你要 BatchSize=1 但是这样 会非常非常慢。。。。
SqlTransaction sqlbulkTransaction = conn.BeginTransaction(); try { using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn, option, sqlbulkTransaction)) { bulkCopy.BulkCopyTimeout = 100; bulkCopy.BatchSize = 1000; bulkCopy.DestinationTableName = tableName; bulkCopy.WriteToServer(table); sqlbulkTransaction.Commit(); } } 我想问下哈,这个Batchsize如果按照我这样设置成1000,那么如果我在table中写入超过1000行的数据的时候,内部是怎么操作的,我在外面显式开启一个事务,bulkCopy内部还会另外开启一些事务来应对这个BatchSize么?另外如果这地方捕获到异常,那么我对sqlbulkTransaction这个事务进行回滚,bulkCopy内部的所有操作都能够回滚?但是如果BUlkCopy按照之前说的,针对BatchSize进行多个事务提交的话,那么这个地方再回滚应该达不到目的了吧?
back1999 2016-08-03
  • 打赏
  • 举报
回复
引用 1 楼 roy_88 的回复:
把约束直接删除了,导入完检查没问题再加上约束 或先导入到(临时)实体表里
那SqlBulkCopyOptions.CheckConstraints这个到底是什么意思?实在是搞不懂这个参数到底什么用,加上或者不加上,违反约束的时候,都会报错、、、
wwhtkill 2016-08-03
  • 打赏
  • 举报
回复
中间表 应该已经是最快的方法了 ,因为它可以让你做到 批量插入 批量比对约束。 你用的这个是开启事务模式 你没有设置BatchSize属性吧 这个是把几条数据作为一个事务插入 失败了只会回滚这个批次的事务 可以做到你的要求 但是你要 BatchSize=1 但是这样 会非常非常慢。。。。
卖水果的net 2016-08-03
  • 打赏
  • 举报
回复
纯 SQL操作的话,可以使用 merge;
中国风 2016-08-03
  • 打赏
  • 举报
回复
把约束直接删除了,导入完检查没问题再加上约束 或先导入到(临时)实体表里

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧