检查字符串的CONSTRAINT只包含数字.(Oracle SQL)

Sha*_*nce 12 sql oracle

我有一个专栏,比如PROD_NUM,其中包含一个用零填充的"数字".例如001004569.它们都是九个字符长.

我不使用数字类型,因为对数字的正常操作对这些"数字"没有意义(例如PROD_NUM*2没有任何意义.)并且因为它们的长度都相同,所以列定义为CHAR(9)

CREATE TABLE PRODUCT (
    PROD_NUM CHAR(9) NOT NULL
    -- ETC.
)
Run Code Online (Sandbox Code Playgroud)

我想约束PROD_NUM所以它只能包含九位数.没有空格,除了'0'到'9'之外没有其他字符

Tim*_*ter 15

REGEXP_LIKE(PROD_NUM, '^[[:digit:]]{9}$')
Run Code Online (Sandbox Code Playgroud)

  • 一组表示字符类,两组表示命名字符类.请参见http://en.wikipedia.org/wiki/Regular_expression#POSIX_character_classes (2认同)
  • @rihardtallent:检查约束从不使用索引. (2认同)

Rob*_*ijk 12

您已经收到了关于如何继续当前路径的一些很好的答案.请允许我建议一个不同的路径:使用数字(9,0)数据类型.

原因:

  • 您不需要额外的检查约束来确认它包含实数.

  • 你不是在愚弄优化器.例如,有多少prod_num是"BETWEEN'0000009'和'000000010'"?那里有很多字符串.而"9到10之间的prod_num"显然只选择两个数字.基数会更好,从而导致更好的执行计划.

  • 你不是在愚弄未来需要维护代码的同事.将其命名为"prod_num"会让它们自动假设它包含一个数字.

您的应用程序可以使用lpad(to_char(prod_num),9,'0'),最好在视图中显示.

问候,Rob.

(由MH更新)评论主题有一个讨论,很好地说明了这种方法需要考虑的各种事项.如果这个主题很有趣,你应该阅读它们.

  • @Rob,你提出了很多好处.然而,世界充满了不是数字的"数字",而是代码或ID.我想到了VIN(车辆识别号码)和许多序列号.用户决定调用这些产品编号,并决定他们希望在左侧填充零.在应用程序的某一层,我必须有一个零填充字符串的产品编号.我宁愿一直到基表一致. (4认同)
  • 好的,请允许我最后一条评论.我认为必须选择对数据进行恰当约束的数据类型.仅仅因为它不是数学上的操纵并不意味着它不是一个数字.我不打算使用我的代理键数字,而不是我的电话号码,而不是我的环法自行车赛车手号码.我仍然认为它们是数字,因为它会对它们进 我永远不会建议声明这些列VARCHAR2(N)(4000?)甚至是CLOB,为可能发生在他们身上的一切做好准备.我使用了一个视图层. (3认同)
  • @Rob,"我的回答的目的只是让你意识到选择CHAR(9)方法时可能存在的陷阱." 谢谢你.我想证明我已经考虑过你提出的问题.我喜欢这个答案,足以投票. (3认同)
  • 好的,最后一条评论,我会闭嘴.我目前正在这个确切场景发挥作用的网站上工作.我们系统的一个中心重要的"数字"开始是所有数字.卫星系统开始假设数字; 应用程序也是如此.然后,我们的客户说,"哦,顺便说一下,我们希望你用两个字母标记为你的"数字"加上前缀.猜猜是什么?未来几年我们仍然感受到痛苦.总是看着路.考虑最坏的情况.不要认为因为今天的事物看起来像数字,所以它们必须始终是数字.外部性很重要! (2认同)
  • +1 对于每个人都如此友好地提出不同意见并像文明人一样讨论它。万岁! (2认同)

Dav*_*dge 7

适用于所有版本:

TRANSLATE(PROD_NUM,'123456789','000000000') = '000000000'
Run Code Online (Sandbox Code Playgroud)