昨天在帮客户处理汇入资料的问题,因为资料量实在很庞大,加上汇到一半时客户又通知可能还会有更多资料需要汇入,小弟我就默默的关掉客户提供的EXCEL表,打算帮他写个汇入功能。
选择的方式是用NPOI读EXCLE档案(关于NPOI等假日比较有时间会写一篇简单的实作教学),再用迴圈把T-SQL串起来执行,这边相信各位大大都有一套自己的方式,而我昨天组合好的T-SQL需要新增的资料表有五个以上,指令也有上千行,资料量一大要发现错误就很困难,加上就算给客户範例格式,可能也还是会有一堆问题。
所以我在思考的是假设今天客户自行準备了一千多笔资料要汇入,但是汇入时在某一笔发生错误SQL还是会继续执行下一个INSERT指令一直到结束,这么一来在整份汇入资料中就会有廖廖几笔资料没有成功,而客户必须要把那些资料修正后抓出来,另存一份EXCEL档才能再次汇入,但是但是以上看起来很正常的流程其实并不是客户想要的,因为他们大多都会想要在原EXCEL修正后直接汇入(还是我遇到的客户都比较懒?XD),而这种方式也比较符合他们的作业方式。
以上说了那么多,接下来要开始进入正文了,针对这个方式我们会需要用到交易和Error Handle这两个语法,以下使用北风资料库的[Order Details]做测试:
首先第一段是比较一般的SQL:
INSERT INTO [Order Details] (OrderID,ProductID,UnitPrice,Quantity,Discount) VALUES('11078','11','14.00','10','0') INSERT INTO [Order Details] (OrderID,ProductID,UnitPrice,Quantity,Discount) VALUES('11078','1111111111111111111111111111111111111','14.00','10','0') INSERT INTO [Order Details] (OrderID,ProductID,UnitPrice,Quantity,Discount) VALUES('11078','12','14.00','10','0')
执行结果:
查询刚刚新增的资料,发现虽然第二笔资料错误了,但第三笔还是会执行
那假如我们把交易和Error Handle加进刚刚的语法里面,SQL会变成:
--在一开始先用TRY把主要的新增SQL包起来BEGIN TRY--之后开启交易BEGIN TRANSACTION --执行新增 INSERT INTO [Order Details] (OrderID,ProductID,UnitPrice,Quantity,Discount) VALUES('11078','11','14.00','10','0') INSERT INTO [Order Details] (OrderID,ProductID,UnitPrice,Quantity,Discount) VALUES('11078','1111111111111111111111111111111111111','14.00','10','0') INSERT INTO [Order Details] (OrderID,ProductID,UnitPrice,Quantity,Discount) VALUES('11078','12','14.00','10','0') --这边是利用TRY的特性,如果能跑到这一行的话代表以上的指令执行都没有错误,既然没有错误,就可以直接「确认交易」。 COMMIT TRANSACTIONEND TRYBEGIN CATCH--这边也是利用TRY在出错时会跑到CATCH的特性,让他一出错就到这CATCH里面执行「回复交易」的动作。ROLLBACK TRANSACTIONEND CATCH
执行结果,他不会执行第三段T-SQL,因为在执行第二段出错时就跳到CATCH了。
查询刚刚新增的资料,会发现什么都没有,因为他在第二笔报错时就回复了交易内所有的更动
以上是如何在发生错误时停止执行SQL,因为昨天查了一下资料似乎没有相关的资料,所以才拼出这个方式,如果各位大大有更好的做法也可以留言告诉我,我都会去尝试的!!
Function:
1.开启交易(BEGIN TRANSACTION):
[笔记][MSSQL]关于SQL的交易概念
2.Error Handle:
BEGIN TRY--监控在TRY里的指令,如果出错就会跳到CATCH中继续执行END TRYBEGIN CATCH--当TRY里执行的指令错误,就会执行CATCH内的指令END CATCH
因为这一篇还没有讲到发生错误时除错的处理,打在一起感觉又偏离主题,就下一篇在讲吧!应该明天就会打上来了,应该...XD
第二篇:
[笔记][MSSQL]执行多段指令时(2) - 发生错误后的除错方式
谢谢各位!!