主键列的就地重新排序
我有一个带有复合主键的表:
table MyTable
(
some_id smallint not null,
order_seq smallint not null,
--other columns
)
...其中 some_id
和 order_seq
组成了复合主键。 order_seq
列用于确定 C# 3.5/ASP.NET 应用程序其他部分的显示顺序。
我正在设置一个管理页面,用户可以在其中随机排列这些行,一次更改多行的 order_seq
值:
屏幕上的所有项目都具有相同的 some_id
。 当用户单击“提交”时,新的 order_seq
值将显示应该保存到数据库中。
我的问题是 order_seq 是 PK 的一部分,因此整理这些内容的任务变得很复杂。由于 some_id
是相同的,因此除了 order_seq
本身之外,我无法识别它们,因为它会随着我的操作而变化。此外,我必须确保 order_seq 值保持唯一(可能具有某种临时值)。
我最好的想法是使用某种内存中的集合来跟踪我迄今为止所做的更改。不过,我在实施它时遇到了麻烦。如何一次对多行进行就地重新排序?我可以使用基于 C# 或 SQL 的解决方案。
编辑:不幸的是,我对表设计的控制为零,对数据库的控制通常有限。我将无法更改 PK 方案或引入任何新列。
I have a table with a composite primary key:
table MyTable
(
some_id smallint not null,
order_seq smallint not null,
--other columns
)
...where some_id
and order_seq
make up a composite primary key. The order_seq
column is used to determine the display order in other parts of my C# 3.5/ASP.NET application.
I'm setting up an admin page where users can shuffle these rows around, changing multiple rows' order_seq
values at a time:
All items on the screen have the same some_id
. When the user clicks Submit, the new order_seq
values are supposed to be saved to the database.
My problem is that order_seq
is part of the PK, so the task of shuffling these things around becomes complicated. Since some_id
is the same, I have no way of identifying them other than order_seq
itself, which changes as I go. Furthermore, I have to make sure the order_seq
values stay unique (presumably with some kind of temp value).
The best idea I have is to use some kind of in-memory collection to keep track of the changes I've made so far. I'm having trouble implementing it, though. How can I do an in-place resequence of multiple rows at once? I'd be fine with either a C# or SQL-based solution.
EDIT: Unfortunately, I have zero control over the table design, and limited control over the DB in general. I won't be able to change the PK scheme or introduce any new columns.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果可能的话,引入代理主键将为您减轻很多压力。由于您可以更改 order_seq 而不更改任何其他字段,因此它并不真正适合作为主键的一部分(记录中的所有其他字段应直接依赖于主键)。但即使超出了理论知识,您也已经发现了这种复合密钥的技术问题。
如果您确实需要保持结构相同,那么更改关键字段将会很乏味,并且正如您已经发现的那样,需要一些临时值。在我的脑海中,如果我必须完成这个任务,我会分两步完成:
显然,为每个正在更改的不同行运行第一个语句,然后在最后运行第二个语句以重置它们的值。这应该可以防止您在此过程中的任何时候出现重复的主键。
If at all possible, you will save yourself a lot of stress if you introduce a surrogate primary key. Since you can change the order_seq without changing any of the other fields, it's doesn't really fit as part of the primary key (which all other fields in your record should directly depend on). But even beyond the theoretical stuff, you're already discovering the technical problems with this kind of compound key.
If you do need to keep the structure the same, then changing the key fields is going to be tedious and, as you already figured out, require some temporary values. Off the top of my head, if I had to accomplish this I'd do it in two steps:
Obviously, run the first statement for every distinct row that's changing, then run the second statement at the very end to reset their values. This should prevent you from having duplicate primary keys at any point in the process.
您需要存储原始复合 PK(隐藏列)。在屏幕上,如果管理得当,两个项目不应该具有相同的顺序。然后,您可以找到具有原始复合 PK 的商品,并使用新的订单值更新它们。
编辑:好吧,您可以在代码中执行类似的操作,即跟踪具有原始 PK 和当前 PK 的对象列表,任何时候用户尝试更改顺序,如果允许,则进行验证,然后允许或阻止它。您需要找到一个具有更新的 Id 和 orderId 的对象,如果您确实找到了一个对象,则不允许这样做。
抱歉,如果我没理解这个问题。试图提供帮助。
You'll need to store the original composite PK (hidden column). On the screen, if you manage it properly, two items should not have the same order. Then you can find the items with the original composite PK and update them with your new order values.
Edit: All right, you can do similar thing in your code, ie, keep track of the list of objects with original PK and current PK, any time user tries to change order, do a validation if it's allowed, and then either allow or block it. You'll need to find an object with updated Id and orderId, if you do find one, then it's not allowed.
Sorry, if I haven't understood the problem. Trying to help.
您可以使用带有 XML 参数以及一对旧 order_seq 和新 order_seq 的 SP 来完成此操作。
一些测试数据
存储过程
要反转
some_id = 1
的顺序,请像这样调用 SP:您需要跟踪客户端上的旧 order_seq 并在用户选择提交更改时构建 xml 。
You can do it with a SP that takes a XML parameter with a pair of the old order_seq and the new order_seq.
Some test data
Stored proc
To reverse the order for
some_id = 1
call the SP like this:You need to keep track of the old order_seq on the client and build the xml when the user chooses to submit the changes.