0

我在这个问题上失败了几个小时,只是无法解决这个问题。从“人类” POV 看来,这似乎相当简单,但不知何故,我似乎无法将其写入代码。

情况:给定由起始编号和分配给特定位置的当前“活动”编号定义的多个编号范围(或 0 用于通用位置)

startno   | actualno | location
100       | 159      | 0
200       | 203      | 1
300       | 341      | 2
400       | 402      | 0

现在,如您所见,一个位置也可以有两个范围。在这种情况下,只有 startno 最高的范围(在这种情况下为 400)被认为是活动的,另一个只是为了历史目的而存在。

每个用户都被分配到一个特定的位置(与位置列中的 ID 相同),但永远不会分配到一个通用的位置(零)。

当用户想要一个新号码时,他将从分配给他的位置的范围中获得一个分配的号码,或者,如果没有找到,则从最高的通用号码中获得一个号码(例如 user.location = 0 将获得 403,user.location = 2 将得到 342)。

然后,用户可以选择使用这个数字或从分配的数字开始的数量 X。

问题来了:如何确保范围不会相互重叠?假设用户(位置 = 2)获得下一个数字 342,并决定他需要 100 个数字。这将产生 441 的结束编号,这在通用范围内,这是绝对不能发生的。

我尝试了几个嵌套的 SELECT,同时使用起始和结束编号,聚合 MAX(),将表加入自身,但我无法 100% 正确。

4

2 回答 2

0

根据我对这种事情的理解,我可能只是在 db 中的表上创建一个触发器来进行验证,如果在应用程序更新表时发现重叠,则会引发错误,这样用户只会得到一个错误,说你不能做。假设您希望它以 441 结尾,然后让用户执行此操作并尝试将带有实际编号的表更新为 441,然后一个简单的选择将新数字与所有现有的startno进行比较,看看它是否大于任何startno然后引发错误。更新触发器中的内容如下:

IF EXISTS(SELECT 1 FROM 
         Table1
         WHERE @newnumber >= startno AND id <> @currentID)
BEGIN
    'Go Raise the error
END

好吧,也许我在某些情况下错过了一些东西,这不起作用,请告诉我。

使用触发器进行数据完整性检查是完全可以的,根本不应该是一个问题。这将比预先验证容易得多,特别是如果您考虑多线程的东西可能会在那里产生一些大问题。

另一方面,为了防止这种情况太容易发生,我可能会在这些数字中添加更多的零作为初始值:

startno   | actualno | location
100000    | 100059   | 0
200000    | 200003   | 1
300000    | 300041   | 2
400000    | 400002   | 0
于 2013-05-02T09:04:25.307 回答
0

通常,我在发布问题后不久就找到了一种方法。它似乎描述了一个问题,因此其他人理解它是获得解决方案的一半。至少,我得到了一个可能的,到目前为止证明是相当有抵抗力的。

我查询数据库

SELECT nostart FROM numbers
WHERE nostart BETWEEN X AND Y

其中X是请求的起始编号,Y是用户的结束编号。(为了符合我的介绍示例,X = 342并且Y = 441

然后,这将为我提供所有范围的列表,其起始编号在用户请求的数字范围内,在这种情况下,列表将是

nostart 
400

现在,如果查询没有找到结果,我是金子,可以使用数字。如果查询找到一个结果,并且该结果等于用户的起始编号,我也可以,因为这意味着这是用户第一次请求此范围内的内容。

如果不是这种情况,则不能使用该范围,因为另一个范围在其中。此外,如果查询找到多个结果(例如 forX = 100Y = 350,这将导致100|200|300我也拒绝该请求,因为多个范围重叠。

如果有人对此有更好的解决方案或注释,我将把它留在这里并使用它,只要它有效。

于 2013-05-02T12:13:40.687 回答