【问题标题】:Oracle SQL Developer limit number of character of datatype char(5)Oracle SQL Developer 限制数据类型 char(5) 的字符数
【发布时间】:2021-02-12 19:02:33
【问题描述】:

我的任务是实现一个带有可变组码的表。有几个要求。

  1. 字符(5)
  2. 2 或 4 个大写字母加 1 位数值介于 1 和 4 之间的数字(例如,AA1、AABB1)
  3. 应禁止任何其他违反点 1 和 2 的输入

我唯一能想到的就是 regexp_like 但我的努力是徒劳的,例如

create table Test(
groupcode char(5) check(
regexp_like(groupcode, '^[A-Z]{2}[0-9]$', 'c') 
)
);

INSERT INTO Test(groupcode) VALUES ('AA1');

我插入了这个,但它一直告诉我有一些违规行为,我不明白。

我指定^$,因为我不希望出现'bbAA1''AA1bb' 之类的内容。

我也对非正则表达式解决方案持开放态度。经过今天下午的所有工作,我开始怀疑自己的方法了。

编辑--致蒂姆:

【问题讨论】:

    标签: sql regex oracle sqldatatypes check-constraints


    【解决方案1】:

    您的正则表达式 ^[A-Z]{2}[0-9]$ 只允许(完全)三个字符。但是,如果您提供的字段少于三个,则定义为 char(5) 的列会用空格填充,因此实际上'AA1' 将存储为'AA1 ',这违反了您的正则表达式。

    请改用char(3)

    更好的是,永远不要使用char(您刚刚经历了其中一个原因),使用varchar(5)varchar(3) 两者都可以与您的正则表达式一起使用。


    2 或 4 个大写字母加 1 位介于 1 和 4 之间的数字

    这不是您的正则表达式所做的。 [A-Z]{2}正好两个大写字母。如果您想允许不同长度的模式,则无法使用char(5),除非您还在正则表达式中包含空格:

    create table test
    (
      groupcode char(5) check(
          regexp_like(groupcode, '(^[A-Z]{2}[0-9]  $)|(^[A-Z]{4}[0-9]$)', 'c'))
    );
    

    上述正则表达式允许两个大写字符后跟一个数字和两个空格四个大写字符后跟一个数字。

    【讨论】:

    • 好消息:非常感谢我理解了'AA1 '的概念;坏消息:我需要严格遵守 char(5 约束。:(.
    • @AndesLam:char(5) 列上的正则表达式不能满足“2 个大写字母加 1 个数字”部分。你真的应该改用varchar(5)。使用char(5) 绝对没有任何优势(无论是性能还是存储空间)——只有缺点。
    • char(5) 有什么理由吗?不仅这里错了,char 总是错的。我从未见过将它用作列数据类型的良好用途。有一个论点是它记录了该值始终具有一定长度的意图,但我从未发现这令人信服 - 如果长度如此重要,请添加检查约束。也许提出这个要求的人正在考虑其他一些工作方式不同的 RDBMS。
    • 我看不出 CHAR(3) 或 VARCHAR(3) 如何容纳更长的代码(在同一列中)。另外:正则表达式可以简化为^([A-Z]{2}){1,2}[1-4]$。注意最后的[1-4] - OP 使用了[0-9],但他给出的要求说“在 1 到 4 之间”。
    【解决方案2】:

    我建议:

    CREATE TABLE Test (
        groupcode VARCHAR(5),
        CONSTRAINT (CHECK(REGEXP_LIKE(groupcode, '^[A-Z]{2}([A-Z]{2})?[1-4]$', 'c')))
    );
    

    下面是正则表达式模式的解释:

    ^                from the start of the column
        [A-Z]{2}     match AA, AB, BB, etc.
        ([A-Z]{2})?  then match another optional AA, AB, BB, etc.
        [1-4]        match 1-4
    $                end of the column
    

    Demo

    后期编辑:@Horse 答案正确指出您应该在此处使用VARCHAR。但是你的正则表达式也有问题,我解决了。

    【讨论】:

    • @AndesLam 我搞砸了检查约束语法(但也假设你有这个权利)。尝试在 create table 语句中将检查约束列为正式约束。我的回答似乎奏效了,至少在演示中是这样。
    • 正式约束是指constraint test_c check(regexp_like(groupcode, '^[A-Z]{2}([A-Z]{2})?[1-4]$', 'c'))吗?因为在这种情况下,Oracle SQL Developer 仍然不让步。但我明白其中的逻辑。 :((
    猜你喜欢
    • 2020-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    • 2017-06-06
    • 1970-01-01
    相关资源
    最近更新 更多