避免在数据库中重复标识符

Tol*_*a E 1 sql oracle plsql duplicates no-duplicates

注意:请回答所有的答案,谢谢,但我们已经有一个序列..并且不能使用UNIQUE约束,因为有些项目需要重复...我需要以某种方式使用PLSQL处理这个,所以基于一些标准(使用一个如果声明)我需要确保没有重复的东西..而且只是为了确认,这些标识符是非常自定义的不同类型的字符串..并且对于每组字符串,我们有一个数字仅仅为该字符串计数(STR-STR - ####)我们有数百种这样的STR-STR组合,对于每种组合,我们都有一个####,它们可以计算......除此之外,还允许一些STR-STR组合有重复..所以我们不能使用UNIQUE CONTRAINTS,我们不能使用PRIMARY KEY,因为它不是一个简单的数字,最重要的是我们确实有一个PRIMARY KEY分配给每个项目..这些标识符适用于用户,而不适用于数据库管理.

当用户创建一个项目时,基于某个creteria,我们给项目一定数量..在保存功能中,调用一个函数来准备第一个初始字符串,然后扫描保存数字的表格并且分配该特定字符串的下一个可用4位数字.

现在有一些问题,在获取下一个数字和提交数据库之间有大约1000行代码.问题是当2个人在几秒钟内创建具有相同标准的项目时,有时会发出相同的数字.

我所做的就是在提交之前,我检查数据库中的数字,如果存在,我调用该函数再次获取下一个可用数字...

即使这段代码减少了重复的可能性,如果我同时保存2个项目,我仍然会得到一个重复的数字..

任何人都知道如何避免重复并将重复数字的机会降至0?

EDIT1:我们已经有了一个主键..这个标识符是一个特殊的字符串,并且非常自定义,因此不可能只使用从0开始计数的数字

编辑2:还有一些情况我们需要重复..这是非常小的(可能大约10个不同的项目轨道使用重复)所以在我使用if语句提交之前检查重复项之前,所以如果项目保存dosn' t属于应该有重复的系统之一,我跳过检查...

编辑3:我们在这里使用PL/SQL

编辑4:我猜这个问题是非常具体的,我没有完全传达它.虽然有很多答案,但没有人真的抓住了我的问题..无论如何,我解决了问题并在下面添加了我的答案..

Lar*_*tig 5

查找命令CREATE SEQUENCE.Oracle可以为您处理唯一的数字生成.(实际上)每个数据库都有一种处理这个问题的方法,尽管它们在实现方式上有所不同.

[响应编辑到问题中的新要求]

您仍然可以使用SEQUENCE生成计数部分,然后将其与前缀组合并将其保存回数据库.而且,在您需要重复ID的极少数情况下,请不要从SEQUENCE获取号码,只需使用您已有的号码.但SEQUENCE将解决您创建"井"的问题,您可以在需要时绘制保证的唯一编号


Ant*_*Ant 5

听起来你已经将3个数据非规范化为1个字段.这是您的字符串字段当前包含的内容:

  • StringField char(12):STR-STR - ####

这是你真正应该拥有的(仅限示例字段名称;这将有助于提供这些有意义的名称,但我不知道您的数据代表什么):

  • Str1 char(3):STR
  • Str2 char(3):STR
  • ID int:####

您现在可以在ID字段中使用序列.

如果要返回原始字符串,可以连接Str,Str2和ID字段的内容(使用连字符分隔).

简而言之:您的数据库设计已被破坏,您现在正在为此付出代价.我的建议是通过将您的身份字段规范化为3个单独的字段来修复设计.或者,您会发现花费数小时重新创建数据库的内置功能,最终得到一个有问题的解决方案,并且在竞争条件方面存在可怕的问题.


或者,如果PL/SQL允许所有这些功能:

创建一个包含以下字段的表:

  • Str1 char(3)
  • Str2 char(3)
  • CurrentID int

然后:

  • 对于STR-STR标识符的每种可能组合,请在数据库中添加一个条目,并将"CurrentID"值设置为0.
  • 编写用于检索下一个ID的存储过程.它将根据传入的STR-STR对锁定相关行,获取CurrentID中的值,增加值,解锁行并返回增加的值.
  • 需要生成新ID时,请调用该过程.

您将没有并发问题,因为每次获取ID的尝试都必须等待任何其他尝试完成.每个STR-STR对都有自己的计数器.