为什么SQL Server默认不强制使用WHERE子句?

时间:2009-05-17 00:24:49

标签: sql sql-server tsql

对我来说似乎没什么好事。我听过很多关于人们在UPDATE或DELETE中忘记WHERE子句并且废弃整个表的故事。我知道粗心的人不应该直接发出查询而且所有这些...并且存在您希望影响所有行的合法情况,但是默认情况下有一个选项需要这样的查询才有意义写得像:

UPDATE MyTable SET MyColumn = 0 WHERE *

或者不改变语言,

UPDATE MyTable SET MyColumn = 0 WHERE 1 = 1 -- tacky, I know

9 个答案:

答案 0 :(得分:10)

因为spec不需要它,所以你不应该直接针对生产数据运行ad hoc sql。

答案 1 :(得分:6)

为了安全起见,我们总是可以在交易中运行:

BEGIN TRAN

UPDATE MyTable SET MyColumn = 0

然后,如果行数看起来不错:

COMMIT TRAN

答案 2 :(得分:5)

是不是可以在客户端会话中将auto commit设置为false作为默认值?您必须发出“提交”以便以这种方式查看您的更改,几乎“您确定要执行此操作吗?”方式。

我认为这是前雇主的所有Oracle TOAD客户的默认设置。

答案 3 :(得分:4)

制造这个错误对于程序员来说是一个长期存在的仪式。我们都已经做到了 - 并且在制作数据的过程中学到了很多东西 - 并且很好地搞砸了生产数据。你只犯了一次这个错误,所以看着开发人员加入这个行列会很有趣。

防止它发生会破坏所有的乐趣!

:)

答案 4 :(得分:4)

乔尔,我认为Josh的问题是为什么规范不需要它,或者至少有一个选项设置会使特定的数据库需要它?

由于规范并不像您所说的那样需要它,因此有可能出现错误的查询(临时或简单的程序错误)来更改您不打算更改的数据库中的行。

隐含的“ALL ROWS”似乎比隐含的“NO ROWS”更危险。

答案 5 :(得分:4)

从我的观点来看,这是一个反感问题,我的意思是这是一种建议......

在行动中,我发现它是一个非常好的,可能有一些设置,如“SAFE_UPDATE”或类似的东西......

我通常做的,除了知更鸟的提示(ALLWAYS打开一个交易),是用select运行查询,只是为了查看将要更新的记录,这样的事情

update mytable set column = xx
-- select * from mytable
where mycondition = mycondition

在更新之前我只需从选择中选择并查看它返回的内容......

无论如何,你应该总是有备份(我听说sql 2005快照也很酷)并在交易中工作......

答案 6 :(得分:1)

MySQL DOES为即席查询提供该选项。它被称为 --safe-updates(或--i-am-a-dummy)。正如其他人所指出的那样,我们已经 一切都犯了这个错误。我们这些运行即席查询的人 所有的时间,有时是凌晨1点,都犯了不止一次的错误。

虽然我通常讨厌“白痴证明”系统和“你确定”的对话, 我喜欢这个选项。你应该小心,但要小心 你每千小时可能会犯一个错误。如果你花了50个小时 在生产系统上以root身份登录,每千小时一个错误 是每年2 1/2主要螺丝钉。出于这个原因,我们发现了另一个原因 --safe-updates非常有用。

有两个原因比大多数MS确认更有用 消息。首先它抓住了最有可能出错的东西, 不像“您确定要删除该文件吗?”。大多数文件删除 真的很需要,所以确认是一个烦恼。大多数“从中删除 用户“,如果错过了where子句,确实是一个错误。其次,它指出 究竟是什么问题 - 缺少where子句。它的 好像文件删除确认足够聪明,可以说“那就是品牌 新的更新副本,而不是您认为正在删除的旧副本。你真的 想要删除新副本,还是打算删除旧副本?“

无论如何,我一般都讨厌“白痴证明”,但我喜欢 - 安全更新,而且 如果它是一个选项,那些不想要它的人不需要使用它。我的一个问题 如果你经常在一个有这个功能的系统上工作, 当他们切换到系统时,有人可能会变得草率并陷入困境 没有它,比如从MySQL切换到MSSQL。

抓住最后一个警告 - 没有一个心智正常的人会在之后切换到MS 熟悉开源。 :)

答案 7 :(得分:0)

我从经验中知道,你只做了一次......一旦你发生了,你总是确保永远不会让它再次发生!!!

答案 8 :(得分:0)

Josh实际上,想要删除或更新表中的所有行并不是那么不寻常。