【问题标题】:Oracle SQL constraint to ensure data formatOracle SQL 约束保证数据格式
【发布时间】:2023-01-31 06:21:08
【问题描述】:

我试图确保进入数据行中单元格/字段的数据遵循 YYYYAB、YYYYAC、YYYYAD 格式。这意味着任何四个数字年份然后是两个字符“AB”或“AC”或“AD”都是有效的,其他任何内容都将被拒绝。

不确定如何使用类似条件和“_”或“%”通配符组合约束,以便在创建列时完成此操作。

我希望使用语法如下的东西:

constraint cksemester check (SEMESTER in ( _ _ _ _ A B, _ _ _ _ A C, _ _ _ _ A D)),

或 % 和正则表达式的组合.....有没有办法将格式限制为基本上任何四个数字 然后强制后缀为“AB”或“AC”或“AD”中的任何一个?

谢谢你。

【问题讨论】:

    标签: sql constraints oracle12c sql-like


    【解决方案1】:

    您可以使用 TRANSLATE 函数在没有正则表达式的情况下执行此操作:

    CONSTRAINT cksemester CHECK (
      TRANSLATE(
        semester,
        '0123456789',
        '0000000000'
      ) IN ('0000AB', '0000AC', '0000AD')
    )
    

    如果你想使用正则表达式(它通常比简单的字符串函数执行得慢,比如TRANSLATE)那么你可以使用:

    CONSTRAINT cksemester CHECK ( REGEXP_LIKE(semester, '^d{4}A[BCD]$') )
    

    【讨论】:

    • 当我研究翻译时: TRANSLATE ( source_string, from_string, to_string ) 所以上面,semester 是我的列名,一个 YYYYAA 格式的值(读作 4 位数字年份,然后两个字母的缩写将作为数据出现)有没有地方持有人,你能澄清一下'0123456789'和随后的'0000000000'在这里做什么吗?谢谢你。
    • Translate 只是将 from_string 中的字符替换为 to_string 中的相应字符;所以它将用零替换所有数字,然后 IN 比较检查它有 4 个零(这是我们替换数字的内容),然后是 ABACAD
    【解决方案2】:

    您可以使用正则表达式来验证您的字段。检查约束的工作方式类似于 where 条件,因此:

    ALTER TABLE yourTable
      add constraint cksemester 
      check (REGEXP_LIKE(SEMESTER,'[[:digit:]]{4}(AB|AC|AD)','I')); 
    

    这个正则表达式确保:

    • [[:digit:]]{4}:四位数字
    • (AB|AC|AD) :ABACAD
    • 'I'参数代表不区分大小写

    编辑:

    正如 MT0 在 cmets 中所建议的,上述正则表达式的更好版本是 ^[[:digit:]]{4}(AB|AC|AD)$

    • ^ 确保字符串需要从 4 位数字开始
    • $ 确保字符串在那里结束,它需要在“或”表达式之后结束。

    这个改进的正则表达式,防止原始正则表达式的“出站”,例如 XYZ1234ABCDEF,这将被认为是有效的,但事实并非如此。

    【讨论】:

    • 这将匹配XYZ1234ABCDEF。如果您只想匹配 4 位数字和 2 个字母,那么您需要在字符串 ^ 的开头和字符串 $ 的结尾包含锚点。
    • 所以整个表达式将是:(REGEXP_LIKE(SEMESTER, '^[[:digit:]]{4}(AB|AC|AD)$', 'I')); ?不用说,我不太擅长正则表达式。谢谢你。
    • @Effectsmeister 是的,这是正确的。我将编辑答案以反映 MT0 的建议。
    • @MT0 你是对的。感谢您的建议,将编辑以添加它。
    猜你喜欢
    • 2021-03-27
    • 1970-01-01
    • 2015-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多