使用 REGEX_LIKE 实现检查约束

Tod*_*ett 1 database-design constraint regular-expression regex

背景

我正在为跟踪有关我公司的数据库开发项目的信息的应用程序设计数据库。项目管理办公室 (PMO) 根据项目的成本是否计入合并整合,为每个项目分配一个伪编号。举例来说,分配的数字将以INT(对于有助于合并整合的项目)或NINT(对于不有助于合并整合的项目)开头。然后分配一个序列号。例如,INT175将是第 175 个确定有助于合并整合的项目。另一个问题是 PMO 有时希望创建多个具有相同编号的项目,因为它们是“相关的”。因此,例如可能有一个 INT175 a项目、INT175 b项目等。

虽然 PMO 认为这个数字是项目的标识符,但在数据库中,我只会将该列用作备用唯一键,以确保不会创建重复的项目并作为用户的搜索键。我想对该列实施检查约束,以确保只能输入与我上面给出的规则匹配的有效数字。

我试过的 - 正则表达式

我的第一个想法是使用正则表达式。在 Oracle 中,我的目标 DBMS,我们有可以使用的 REGEX_LIKE 函数。我研究了关于正则表达式的文档(这里这里这里这里这里),发现这些选项令人眼花缭乱!无论出于何种原因,我的大脑都在试图获取所有各种模式匹配选项的列表并将其应用到我的特定示例中。我是最擅长使用示例的人之一。不幸的是,我还没有找到很多例子。我发现的东西要么太简单,要么太复杂,我无法理解它们。

到目前为止我尝试过的是这样的:

select c
from (
  select 'INT1756b' c from dual union all
  select 'INT175a' c from dual union all
  select 'INT75a' c from dual union all
  select 'INT75' c from dual union all
  select 'NINT2283a' c from dual union all
  select 'NINT2283' c from dual union all
  select 'NINT915c' c from dual union all
  select 'NINT915' c from dual union all
  select 'NINT95b' c from dual union all
  select 'NINT95' c from dual union all
  select 'ABC123' c from dual
) x
where REGEXP_LIKE ( c, '(NINT|INT)\d{2}[0-9]|[a-z]' );
Run Code Online (Sandbox Code Playgroud)

我的测试“表” x 具有我预见的所有可能的有效数字组合和一个无效数字组合的示例。它们都以INTNINT开头,然后至少有 2 个数字,最多 4 个数字,最后是可选的小写字母。

我的奋斗 - 处理不同的长度

我真正在苦苦挣扎的是如何处理不同长度的数字。可以有 2、3 或 4 个数字,这些数字后面可能有也可能没有小写字母。我在上面想出的,只是作为一个开始,是在INTNINT之后寻找 2 个数字。我知道总会有至少两个数字。然后我只是看看其余的是否在一组数字或小写字母中。现在我知道这还不够好,但这是我绞尽脑汁一两天后所能想到的。

请求帮助!

有没有人用正则表达式做过类似的事情,他们可以指出正确的方向或给我一个例子?有没有更优雅和简单的方法来实现这个约束?我感谢任何和所有的帮助和指点!

mus*_*cio 5

这不是一个真正的数据库管理问题,但是......

首先,您的模式不会阻止这样的条目:XXXINT123abogus,因为它没有说“INT”或“NINT”应该在字符串的开头,也没有说小写字母(如果在那里)应该是字符串的最后一个符号。

您可能想尝试以下操作:

 +----------------------------- begins with
 |+---------------------------- optional "N"
 ||  +------------------------- then "INT"
 ||  |  +---------------------- then digits
 ||  |  | +-------------------- minimum 2
 ||  |  | | +------------------ maximum 4
 ||  |  | | |   +-------------- then a lowercase letter
 ||  |  | | |   |  +----------- which is optional
 ||  |  | | |   |  |+---------- and nothing more
 ||  |  | | |   |  ||
 ||  |  | | |   |  ||
'^N?INT\d{2,4}[a-z]?$' 
Run Code Online (Sandbox Code Playgroud)