SSMS 允许表中存在重复记录,但不允许后续更新
编辑:当我说“SQL Server”时,我实际上是在谈论 Management Studio。 抱歉,如果这令人困惑。
哦,我讨厌发生这样的事情。 我昨天正在使用 SQL Server 并尝试使用 PIVOT 命令来尝试弄清楚它是如何工作的。 因此,我创建了一个包含四列的新表,第一列的前几行具有相同的值。
我将“value1”添加到第一行第一列,然后按回车键 - 由于尚未添加键或约束,它允许我向下输入到下一行,第一行上的其他列为 NULL(即美好的)。 令我惊讶的是,它还允许我在第二行输入“value1”并输入 down - 这应该是不可能的,因为现在有两个相同的行。 不过,由于我只是闲逛,所以这并没有打扰我。 因此,我继续创建四行,如下所示:
表 1
Col1 Col2 Col3 Col4
---------------------------------
Value1 NULL NULL NULL
Value1 NULL NULL NULL
Value1 NULL NULL NULL
Value1 NULL NULL NULL
显然,这很奇怪并且破坏了关系理论,但我并不太在意,因为这只是我创建的一个用来乱搞的表。 然而,接下来发生的事情让我差点抓狂。 输入这些数据后,我无法对表执行任何操作。 如果我尝试在任何行上填写 col2、col3 或 col4,SQL Server 会因重复行而对我大喊大叫:“没有更新任何行。第 1 行中的数据未提交......行值(s) 更新或删除要么不会使该行唯一,要么会更改多行(4 行)。”
换句话说,SQL Server 允许我输入重复的行,但是当我尝试更新这些行以使它们唯一时,它不允许我输入,理由是存在重复的行。 最糟糕的是我什至无法删除任何行(我收到相同的错误消息)。 在这种情况下,我发现的唯一解决方案是删除表并重新开始 - 这是荒谬的。
我的问题是,这种行为怎么可能存在于一个已经发展了十多年的众所周知的程序中? 我是不是一个无脑的人,我应该接受SQL Server的行为? 对我来说,这是不可接受的,SQL Server 要么从一开始就不允许我输入重复的行,要么应该允许我更新重复的行,直到它们都是唯一的,然后尝试保存。
这绝不意味着是某种讨厌 SQL Server 的帖子。 我很少遇到这样的行为,但当我遇到这种情况时,它真的会让我落后并让我发疯。 我只是不明白为什么程序有这样的内置行为。 就像如果它不打算让我修复它的话,为什么它首先让我输入重复的行?
我记得当时使用 MS Access 时,我会遇到同样奇怪、过时的行为。 有几次,我不得不复制大量数据,重新创建表,然后将其复制回来,只是因为 Access 允许我做一些不应该做的事情,并且现在阻止我进行任何更改来修复它- 有效地产生僵局。
那么这是怎么回事呢? 在使用 SQL Server 时,我是否需要进行某种范式更改? 是我的问题还是SQL Server的问题? (你可以说是我,我可以接受。)
Edit: When I say "SQL Server", I'm really talking about the Management Studio. Sorry if that was confusing.
Oh I hate when things like this happen. I was working with SQL Server yesterday and trying out the PIVOT command to try to figure out how it worked. So I created a new table with four columns, and the first column was going to have the same value for the first few rows.
I added the "value1" to the first row, first column, and hit enter - sine no keys or constraints were added yet, it allowed me to enter down to the next row with NULLs for the other columns on the first row (which is fine). To my surprise, it also allowed me to enter "value1" on the second row and enter down - this should be impossible since now there are two identical rows. However, since I was just messing around, this didn't bother me. So I proceed to create four rows as such:
Table 1
Col1 Col2 Col3 Col4
---------------------------------
Value1 NULL NULL NULL
Value1 NULL NULL NULL
Value1 NULL NULL NULL
Value1 NULL NULL NULL
Obviously this is strange and breaks relational theory, but I didn't really care since this is just a table I created to mess around with. However, I just about pulled my hair out at what happened next. After I had this data in, I could not do anything to the table. If I tried to fill in col2, col3, or col4 on any of the rows, SQL Server would scream at me for having duplicate rows: "No row was updated. The data in row 1 was not committed.... The row value(s) updated or deleted either do not make the row unique or they alter multiple rows(4 rows)."
So in other words, SQL Server allowed me to enter in duplicate rows, but when I tried to update the rows to make them unique, it wouldn't allow me, citing that there are duplicate rows as its reason. The worst part is I couldn't even delete any rows either (I get the same error message). The only solution I found once in this scenario was to delete the table and start over - which is ridiculous.
My question is, how can this sort of behavior exist in a well known program that has evolved over a decade? Am I the one being brainless and I should accept SQL Server's behavior? To me this is unacceptable and SQL Server should either never have allowed me to enter duplicate rows in the first place, or it should have allowed me to update the duplicate rows until they were all unique and and then try to save.
This is by no means meant to be some sort of SQL Server hating post. It's relatively rare I run into behavior like this, but when I do, it can really set me behind and drive me crazy. I just don't understand why the program has behavior built in like this. Like why in the world did it let me enter the duplicate rows in the first place if it didn't plan to let me fix it?
I remember working with MS Access back in the day and I would run into the same sort of strange, archaic behavior. A few times I had to copy out huge amounts of data, re-create the table, and copy it back in just because Access had allowed me to do something it shouldn't have, and is now blocking me from any changes to fix it - effectively producing a deadlock.
So what's going on here? Do I need some sort of paradigm change when approaching SQL Server? Is it me or SQL Server that's the problem? (You can say it's me, I can take it.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Management Studio 所做的所有工作就是提供一个 UI 来为您创建一些 SQL 并针对数据库运行它。
在您的例子中,每次添加一行时,它都会生成一个 INSERT 语句。 这是完全有效的。
然后,当您尝试使用 UI 从所有这些重复记录中删除或更新单个记录时,它无法生成执行此操作的 SQL。 原因是,由于表上没有键,因此无法生成代表您尝试更新或删除的记录的 WHERE 子句。
它的“错误”消息对我来说听起来非常清晰且有效。
至于你的评论:
拥有一个允许重复的数据库表并没有什么问题,如果你需要的话,这是一个完全有效的事情。 至于不“关心”或“打扰”您允许重复。 这就是错误所在。 这时您应该意识到您忘记添加主键。
All management studio ever does is provides a UI to create some SQL for you and runs it against the DB.
In your case, every time you added a row, it produced an INSERT statement. This is perfectly valid.
When you then tried to use the UI to DELETE or UPDATE a single record out of all these duplicate records it was unable to produce the SQL to do that. The reason being, as there was no key on the table, there is no way of producing a WHERE clause that would represent the record you were trying to UPDATE or DELETE.
It's "error" messages sound perfectly clear and valid to me.
As for your comments:
There is nothing wrong with having a database table that allows duplicates, it is a perfectly valid thing to do if it's what you need. As for not "caring" or being "bothered" that you had allowed duplicates. That is where the mistake lies. It is then that you should've realised you forgot to add a primary key.
是的,这是一个怪癖,但不是,这是一个缺陷。 拥有一个没有唯一键的表是完全合法的,但如果存在相同的行,则无法使用 SSMS 中的表编辑器(或之前的企业管理器)从中删除行。
不是 SSMS 允许您创建重复行,而是您在创建没有主键的表时允许这样做。 您始终可以创建一个自动递增的标识列来解决该问题。
我不会使用表编辑器来执行此类操作,我会编写 INSERT 语句脚本。
A quirk yes, but a flaw, no. It's perfectly legitimate to have a table with no unique key, but it's not possible to delete a row from it with the table editor in SSMS (or Enterprise Manager before it) if there are identical rows.
It isn't SSMS that let you create the duplicate rows, it is you that allowed it when you created your table with no primary key. You can always create an auto-incrementing identity column that would solve the problem.
I wouldn't use the table editor for this sort of stuff, I would script INSERT statements.
如果您没有唯一键,我不确定您如何期望该工具知道要删除哪一行。 您希望它只删除其中一个重复项还是全部删除? 如果只有一个,它应该使用什么密钥。
Management Studio 是一个工具。它的工作不是强制执行完美的表设计或基本数据库 101,其中包括在大多数情况下拥有一些唯一的键。 如果您确实有一些需要重复行的疯狂业务模型怎么办? 难道人们不会抱怨该工具阻止了重复的角色吗?
底线是
1. 无论如何,您都不应该使用该工具编辑或删除数据。 您应该为大多数事情编写语句。
2. 你应该有一个唯一的密钥
不能因为没有这些东西而责怪任何工具。
I'm not sure how you would expect the tool to know which row to delete if you did not have a unique key. Would you want it to delete just one of the duplicates or both? if just one, what is the key it should use.
The management studio is a tool. It's job is not to enforce perfect table design or basic database 101, which would include having some unique key the majority of the time. What if you did have some crazy business model that required duplicate rows? Wouldn't the complaint then be that the tool prevented duplicate roles?
Bottom line is that
1. You shouldn't be editing or deleting data with the tool anyways. You should be scripting out the statements for most things.
2. You should have a unique key
Can't blame any tool for not having those things in place.
Sql Server Management Studio 中的记录编辑器是 SQL Server 产品的一小部分(且相对不重要)。 我认为您可以安全地接受编辑器的怪癖,而不必担心服务器本身的相对质量。
Management Studio 在幕后执行 SQL 语句来执行您的操作,就像您自己键入该 SQL 一样。 所以,如果你违反了规则,你就要缴纳罚款。
The record editor in Sql Server Management Studio is a small (and relatively unimportant) part of the SQL Server product offering. I think you can safely accept the quirks of the editor without being concerned about the relative quality of the server itself.
Behind the scenes, the Management Studio is executing SQL statements to perform your actions, just as if you typed that SQL yourself. So if you break a rule, you pay the fine.