CHECK CONSTRAINT of string to contain only digits. (Oracle SQL)

前端 未结 8 1823
一向
一向 2020-12-20 12:22

I have a column, say PROD_NUM that contains a \'number\' that is left padded with zeros. For example 001004569. They are all nine characters long.

I do not use a num

相关标签:
8条回答
  • 2020-12-20 12:50

    In MSSQL, I might use something like this as the constraint test:

    PROD_NUM NOT LIKE '%[^0-9]%'
    

    I'm not an Oracle person, but I don't think they support bracketed character lists.

    0 讨论(0)
  • 2020-12-20 12:53

    Not sure about performance but if you know the range, the following will work. Uses a CHECK constraint at the time of creating the DDL.

    alter table test add jz2 varchar2(4)
         check ( jz2 between 1 and 2000000 );
    

    as will

    alter table test add jz2 varchar2(4)
         check ( jz2 in (1,2,3)  );
    

    this will also work

    alter table test add jz2 varchar2(4)
             check ( jz2 > 0  );
    
    0 讨论(0)
  • 2020-12-20 12:55
    REGEXP_LIKE(PROD_NUM, '^[[:digit:]]{9}$')
    
    0 讨论(0)
  • 2020-12-20 12:58

    in MS SQL server I use this command: alter table add constraint [cc_mytable_myfield] check (cast(myfield as bigint) > 0)

    0 讨论(0)
  • 2020-12-20 12:59

    You already received some nice answers on how to continue on your current path. Please allow me to suggest a different path: use a number(9,0) datatype instead.

    Reasons:

    • You don't need an additional check constraint to confirm it contains a real number.

    • You are not fooling the optimizer. For example, how many prod_num's are "BETWEEN '000000009' and '000000010'"? Lots of character strings fit in there. Whereas "prod_num between 9 and 10" obviously selects only two numbers. Cardinalities will be better, leading to better execution plans.

    • You are not fooling future colleagues who have to maintain your code. Naming it "prod_num" will have them automatically assume it contains a number.

    Your application can use lpad(to_char(prod_num),9,'0'), preferably exposed in a view.

    Regards, Rob.

    (update by MH) The comment thread has a discussion which nicely illustrates the various things to consider about this approach. If this topic is interesting you should read them.

    0 讨论(0)
  • 2020-12-20 13:08

    I think Codebender's regexp will work fine but I suspect it is a bit slow.

    You can do (untested)

    replace(translate(prod_num,'0123456789','NNNNNNNNNN'),'N',null) is null

    0 讨论(0)
提交回复
热议问题