在我目前的工作中,我必须偶尔运行SQL脚本来更新我的数据库。大多数情况下,他们要更新某些无法正常工作的记录。是一个页面功能来做同样的事情,但这是一个更长的路线,所以我直接针对数据库。
我刚刚运行了更新查询并意外更新了我的所有30,000条记录。幸运的是我在我的测试数据库中工作。
//Particular query that I am talking about is this
update customers set
customer_id = 100 // where clause is missing and it will update all records
我想知道,有没有办法保护数据库免受此类批量更新,如果更新影响超过500条记录,可能会触发一半的触发器?有没有办法保护数据库免受意外格式错误的查询。我对更新特别感兴趣。
当我直接对我的生产服务器使用SQL Script时,我做错了吗确实错误。我是新人,我需要专家建议。
答案 0 :(得分:2)
当然,如果INSERTED / DELETED伪表有一定数量的行,则可以在表上放置更新触发器并抛出异常 - 这将导致尝试回滚任何事务。
通常,对于生产,您希望有一些控件,例如在测试过程中使用这些脚本,但显然每个控件最终都会有限制 - 否则您将永远无法插入或更改任何数据
答案 1 :(得分:2)
让我谈谈(2)。我认为你对(1)的建议可能有所帮助,但让我们先谈谈计划。
是否直接使用脚本“非常错误”取决于风险等级。这个数据任务是否关键?你有一个很好的备份,包括交易日志,所以你可以恢复到错误前一分钟?数据库可能会在一小时内停止运行吗?
评估风险并采取适当的措施。如果错误的可能性或错误的成本很高,则应更加努力地降低风险。如果这些因素中的任何一个很高,请强迫自己使用紧密编码的界面。中等级 - 使用适当的变量编写脚本并保存,以便下次不会意外删除WHERE子句,或确保在运行脚本之前拍摄备份。如果从错误中恢复过来便宜又容易,请继续编写一次性查询并希望获得最佳结果。
答案 2 :(得分:1)
对生产数据库进行更新访问通常不是一个好主意。应使用存储过程管理所有必要的更新。这样,在做这件事之前你真的要考虑你在做什么..
另外,正如@Neville K所说,交易很好。您可以设置存储过程以拒绝执行任何操作,除非事务正在进行中,并且如果您的过程中从未进行过提交,则可以始终回滚。也就是说,一旦你承诺,无论如何它的游戏......
这方面没有硬性和快速的方法,你能做的最好的事情就是让自己(以及其他人)难以搞砸......
答案 3 :(得分:0)
查看您的查询我假设您的Customers表没有为Customer_Id打开标识的主键,如果在表上设置这两个肯定会阻止该脚本完成。
我建议你将查询包装在一个事务中。最初使用rollback语句运行脚本,在调用Rollback之前测试输出。如果结果符合您的预期,请使用提交替换回滚并重新运行查询。
示例强>
BEGIN TRAN
UPDATE Customer SET Customer_ID = 100
SELECT * FROM Customer
ROLLBACK
--If results look OK comment out ROLLBACK and comment in the line below
--COMMIT
答案 4 :(得分:0)
您的查询应如下所示。
SET NOCOUNT ON
SET XACT_ABORT ON
Begin Try
Begin Tran
//SQL query
Commit Tran
End Try
Begin Catch
Rollback Tran
End Catch
通过执行异常处理会将数据库回滚到先前的状态,因为任何运行时错误......