防止数字范围重叠

本文关键字:重叠 范围 数字 | 更新日期: 2023-09-27 18:11:41

我在这个问题上失败了好几个小时了,就是不能理解它。从"人类"的角度来看,这似乎相当简单,但不知何故,我似乎无法将其写入代码。

情况:给定由分配给特定位置的起始号码和当前"活动"号码定义的几个号码范围(或通用号码为0)

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

现在,如您所见,一个位置也可以有两个范围。在本例中,只有startno最高的范围(在本例中为400)被认为是活动的,另一个仅存在于历史记录中。

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

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

用户可以选择使用该号码,也可以选择从分配的号码开始使用X。

问题来了:我怎样才能保证范围不会相互重叠?假设用户(location = 2)得到了下一个数字342,并决定在此之后需要100个数字。这将产生结束数441,它在通用范围内,这是不应该发生的。

我尝试了几个嵌套的select,使用开始和结束的数字,聚合MAX(),连接表本身,但我只是不能得到它100%正确。

防止数字范围重叠

根据我的理解,我可能只是在db的表上创建一个触发器来进行验证,并在应用程序更新表时发现重叠时引发错误,这样用户就会得到一个错误,说你不能这样做。如果你想让它以441结束,那么就让用户这样做,并尝试将actualno更新到441,然后简单地选择将新数字与所有现有的startno进行比较,看看它是否比任何startno大,然后引发错误。更新触发器中如下所示:

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

好吧,也许我遗漏了一些东西,在某些情况下,这将无法工作,请让我知道。

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

另一方面,为了防止这种情况太容易发生,我可以在这些数字中再加几个0作为初始值:
startno   | actualno | location
100000    | 100059   | 0
200000    | 200003   | 1
300000    | 300041   | 2
400000    | 400002   | 0

像往常一样,我在发布问题后不久就找到了一个方法。描述一个问题,让其他人理解它,似乎是解决问题的一半。至少,我得到了一个可能的,到目前为止被证明是相当耐药的。

我用

查询数据库
SELECT nostart FROM numbers
WHERE nostart BETWEEN X AND Y

,其中X为请求的起始号码,Y为用户的结束号码。(为了与我介绍的例子一致,X = 342Y = 441

这将给我一个列表,其中包含所有起始数字在用户请求的数字范围内的范围,在这种情况下,该列表将是

nostart 
400

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

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

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