防止任何表上的意外更新/删除

Posted

技术标签:

【中文标题】防止任何表上的意外更新/删除【英文标题】:Prevent accidental updates/deletes on any table 【发布时间】:2013-01-21 11:54:07 【问题描述】:

我有好几次意外更新了生产表的所有记录。 缺乏关注等等......

我听说 mysql 中有一个编译/运行时开关来防止此类事故。 就像,如果我会做一个

UPDATE Table SET Field=0

由于缺少 WHERE 子句,这将无法编译/运行。 如果你真的想要全部更新,你可以

UPDATE Table SET Field=0 WHERE 42=42

对 MS SQL 有什么想法吗?

我在网上找到了一些关于触发器的答案。我想那会有点贵。 这意味着我必须将触发器放在每个必要的表上。

【问题讨论】:

简单的解决方案:不要让开发人员访问生产!我们是一切生产的邪恶破坏者。 仅供参考,在 MySQL 中称为 安全更新模式 dev.mysql.com/doc/refman/5.6/en/mysql-tips.html#safe-updates - 养成在事务中包装语句的习惯可能会有所帮助。 一个最佳实践是不要在您的生产数据库上执行任意 SQL。创建一个包含您的 SQL 的文件,针对生产数据库的副本执行它,然后假设它没问题,针对您的生产数据库执行它。 是的,在 MySQL 中就是这样。我也想要 MS SQL 中的白痴证明功能:) 在 Jamiec,对于世界上大多数数据库,无论是开发人员还是 DBA,您都需要在某个时候让人工运行某种临时查询。拥有某种简单、可选的安全性确实没有任何明显的缺点。如果“永远不要犯错”是一个有效的论点,我们就不需要安全带和枪支安全开关。 【参考方案1】:

如果您尝试为所有人设置此设置,您可以通过打开 IMPLICIT_TRANSACTIONS 来关闭 SQL Server 的自动提交功能。 See here.

如果您只关心您,上述内容也可以在您的会话中使用SET IMPLICIT_TRANSACTIONS ON。然后,您必须实际调用 COMMIT 以使任何东西粘住。 See here.

【讨论】:

This article 用截图演示了这个效果。需要注意的最重要的事情是,如果有其他人在同一张表上工作并且正在对他们的(不相关的)事务发出(隐式或显式)提交,那么我们未提交的事务也将被提交。【参考方案2】:

在这种情况下,您始终可以在发出命令之前启动事务,但不要在末尾添加COMMIT。这样您就可以验证查询是否具有所需的效果,如果是,请手动发出COMMIT。如果您犯了错误,只需发送ROLLBACK

您还可以向表中添加触发器以防止发生 INSERTS 或 UPDATES,但这会影响所有人,而不仅仅是您。

最重要的是,您永远不应该在生产系统上运行未经测试的查询;) 改用数据库的快照副本。

【讨论】:

通常,我对生产数据库运行的命令包含在 BEGIN TRAN 和 ROLLBACK TRAN 块中。但是对于粗心的用户——他们可能有权访问数据库——这个过程是非常危险的。【参考方案3】:

除了别人说的(MySQL安全更新模式,限制生产,先在开发服务器上测试),训练自己在SQL窗口写这样的更新语句并不难。

update
set
where

然后回溯到顶部,并填写详细信息。这可以防止您省略 WHERE 子句,但不会阻止您编写错误的 WHERE 子句。我现在一直这样做,即使我在本地机器上的 SQL 窗口中编写 SQL,错误更新的惩罚为零。

最好的办法可能是在您选择的文本编辑器emacs 中编写您的SQL,并对其进行编程以将“UPDATE”扩展为带有WHERE 子句的部分语句。

在有人问之前,我也写了这样复杂的 WHERE 子句。

where ()

紧随其后

where (() or ())

然后通过

where ((() and ()) or ())

那我回去填条件。

几年前,当我不得不用 C 编写大量代码时,我养成了这个习惯。它源于训练自己编写这样的“if”语句。省略括号和大括号让其他人很头疼,所以我消除了这种可能性。

if () 

【讨论】:

【参考方案4】:

如何养成经常使用的习惯:

UPDATE TOP (2) dbo.table set name = etc

假设您知道您只想更新 1 行。如果您返回“受影响的 2 行”,您就知道您打错了,但至少您还没有破坏 enire 表。

【讨论】:

【参考方案5】:

正如之前所说的其他良好做法:不允许访问 prod db,不要在没有 where 的情况下执行更新;我为他们添加了使用不同的用户和安全策略。保持良好的日志,以便您可以恢复它以防万一。整个表的更新,取决于它的大小,可能会锁定整个表!

【讨论】:

以上是关于防止任何表上的意外更新/删除的主要内容,如果未能解决你的问题,请参考以下文章

防止 API 调用时意外删除

防止在 iPad 上意外关闭 U​​IActionSheet

Windows 2008 R2 域控制器防止意外删除现有OU的设置

由于编辑器没有自动更新,有没有办法防止在 git pull 后意外覆盖?

防止意外选择/拖动突出显示

锁定机制和数据并发管理(笔记)