中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [原创]BCP IN出错回滚及错误捕捉
作者:
标题: [原创]BCP IN出错回滚及错误捕捉 上一主题 | 下一主题
zyz0304360
中级用户




积分 257
发帖 123
注册 2008-1-5
来自 烟台
状态 离线
『楼 主』:  [原创]BCP IN出错回滚及错误捕捉

最近开发了一个小系统,遇到了很多的困难,曾经在网上试图收集了一部份解决资料,但都无功而返,只好把问题点发到论坛上大家一起研究,现在,我就把一些问题点及解决方法总结一下。 首先十分感谢在我工作生活中给我很大帮助的三大论坛及论坛中的各位老师: 1. CSDN社区中心 community.csdn.net/ 2. 中国DOS联盟 www.cn-dos.net/forum/index.php 3. 51CTO技术论坛 bbs.51cto.com/ ZYZ0304360(稳,勤学) 希望大家常去看看 由于语文学得不好,如有影响理解之处,还请大家见谅: 新系统开发遇到的问题以及解决方法 开发时,BCPIN的问题要远远多于BCPOUT,因为毕竟BCPIN实现的功能对数据库中的对象有所改动。 问题1:BCPIN回滚问题 BCP中有一个参数 -b MS-SQLSERVER2000是这样描述的: -b batch_size 指定所复制的每批数据中的行数。每个批处理作为一个事务复制至服务器。SQL Server 提交或回滚(在失败时)每个批处理的事务。默认情况下,指定的数据文件中的所有数据都作为一批复制。 也就是说 BCPIN 会把一次导入-b参数行的数据作为一个事务,由于事务具有原子性(事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。)所以,一旦导入出错,整个事务回滚。而在-b默认情况下,指定的数据文件中的所有数据都作为一批复制。也就是说-b默认情况下,BCPIN会把全部数据的导入作为一个事务,所以在BCPIN时,不加-b参数时,如果导入出错,则数据全部回滚。 例: 两张同样的表(字段,主键都相同):table1,table2 BCP “select top 200 * from dbdaily..table1 union all select top 200 * from dbdaily..table1” queryout “table.dat” -S. -Usa -P -n -q 1.有-b参数 BCP “dbdaily..table2”in “table.dat” -S. -Usa -P -n -q -b30 执行后倒入了180条,因为每30条作为一个事务进行导入,在第180条到210条是出错(主键重复),此事务回滚,前6次共导入180条数据 2.无-b参数 BCP “dbdaily..table2”in “table.dat” -S. -Usa -P -n -q 执行后导入了0条数据,无-b情况下所有数据的导入作为一个事务,(导入的速度特别快,因为不需要像有-b那样每次都停顿等待事务提交,但是数据全部导入之后的事务提交是很慢的。)在第201条数据导入时主键重复,数据全部回滚。(事务原子性) 问题2:BCPIN错误信息捕捉 还是用相同的例子 @echo off echo _____________begin_____________ >>test.log date /T >>test.log time /T >>test.log BCP “select top 200 * from dbdaily..table1 union all select top 200 * from dbdaily..table1” queryout “table.dat” -S. -Usa -P -n -q BCP “dbdaily..table2”in “table.dat” -S. -Usa -P -n -q if errorlevel 1 goto :error goto :end :error time /T >>test.log echo here is an error >>test.log goto :end :end time /T >>test.log echo end >> test.log echo ___________________BYE_______________>>test.log 此批处理中,BCPIN出现的主键重复错误是无法用errorlevel捕捉到的,无论BCPIN执行成功或失败errorlevel都是0。微软已经承认这个是微软公司的产品问题(详见:support.microsoft.com/kb/92266 ...) 所以我们不得不想另外一种方法来捕捉BCPIN的错误信息,本人曾经试过很多方法,失败了太多次,终于找到了解决方法 解决方法如下: 1. 将BCPIN的内容生成文本文件(.txt .log)在文件中查找相应错误信息字符串,如果文件中有错误信息字符串,则跳转到:error。 BCP “dbdaily..table2”in “table.dat” -S. -Usa -P -n -q >>ErrGet.txt Type ErrGet.txt| findstr "Error = "&&goto :error (或者 Type ErrGet.txt| findstr "SQLState = 23000, NativeError = 2627"&&goto :error 2627是主键重复的错误号) 在最后:end可以删掉ErrGet.txt :end if exist ErrGet.txt del /f ErrGet.txt (午睡刚醒,不清醒。。。) 2. 直接在命令行解释器中捕捉反馈信息,每次执行时,BCP的执行相关信息,都会显示在命令行解释器中,直接捕捉错误反馈信息的关键字符串。 BCP “dbdaily..table2”in “table.dat” -S. -Usa -P -n -q |find /i "Error = "&&goto :error 好了,有这两个方法就够用了,虽然说原理是一样的,但用法是因人而异,因系统而异的。 问题3 开发时,上面是两个相对来说大一点的问题 现在,整理一些细琐的 (1) 批处理中的延时设置 Ping 127.0.0.1 -n 6 >nul -n 后面的6 自己改,上面的例子延时5秒(6-1=5) (2) 备份日志文件 备份时,需要精确到分钟 例: Set folder_bk=D:\NEWSYStest\ copy test.log %date:/=%%time:~0,2%%time:~3,2%test.log del test.log 在小时是两位数(10点到24点)时是对的,是个位数是就错了 例如,当前时间2008/01/12 09:50:35.345 备份后的文件名应该是200801120950test.log 但,用上面的例子就会出错 原因是无法生成中间有空格的文件名20080112 950test.log 解决方法: 把空格替换成0 Set folder_bk=D:\NEWSYStest\ set newtime=%date:/=%%time:~0,2%%time:~3,2% copy test.log %folder_bk%%newtime: =0%test.log del test.log %newtime: =0%此处“ =0”是把空格替换成0 生成200801120950test.log 或者 在目标文件名上加“” Set folder_bk=D:\NEWSYStest\ copy test.log “%folder_bk%%date:/=%%time:~0,2%%time:~3,2%test.log” del test.log 生成20080112 950test.log(注:2和9之间有空格) 。。。。。。 新系统的功能是: 在A地B地无法直接数据传输的情况下: 在A地,用BCP取出数据传送到FTP上, 在B地,在FTP上取下数据导入数据库 A地:BCPOUT > MAKECAB >FTP >DEL B地:FTP > EXPAND >BCPIN >BACKUP >DEL 全部每天自动执行,有任何一步出错,自动给负责系统的人发邮件,要求检查数据,邮件的内容为出错时的信息,附带日志文件及ERROR日志 由于是公司财产,所以无法与大家分享, 但如果有在开发过程中有此类困难的朋友,我可以帮助您 邮件:saintasia@163.com OVER 2008/01/12




路 是自己选的 学习 是为了具备解决问题的能力
2008-1-12 15:33
查看资料  发短消息  网志  OICQ (625621812)  编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: