2013-07-26 34 views
0

如何在customers表中的first_name(varchar2(20))列上添加約束,以便插入列中的值不包含數字?檢查約束中的正則表達式:不接受數字

我想我找到了可行的解決方案:

ALTER TABLE customers 

ADD CONSTRAINT first_name_check 

CHECK (REGEXP_LIKE(first_name,'^[[:alpha:][:blank:][:cntrl:][:punct:]]+$')) NOVALIDATE; 

另外:

ALTER TABLE customers 

ADD CONSTRAINT first_name_check 

CHECK (NOT REGEXP_LIKE(first_name,'[[:digit:]]')) NOVALIDATE; 

然而,有沒有更好的方式來做到這一點?沒有使用所有這些字符類,並在REGEXP_LIKE之前沒有「NOT」?

我想這會工作:

ALTER TABLE customers 

ADD CONSTRAINT first_name_check 

CHECK (NOT REGEXP_LIKE(first_name,'^[^[:digit:]]+$')) NOVALIDATE; 

但是我錯了。你能解釋我爲什麼嗎?

回答

3

至於問「有沒有更好的方式來做到這一點」對此約束:

CHECK (NOT REGEXP_LIKE(first_name,'[[:digit:]]')) 

這是一個主觀的問題,所以這裏是一個主觀的答案:我不這麼認爲。它完成這項工作,它的字符集安全,並且很容易閱讀(對於正則表達式)。

1

你最後的正則表達式似乎不太正確。 ^[^[:digit:]]+$應該匹配任何不是由數字組成的字符串,但是您會反轉該檢查。

要麼擺脫NOT,要麼嘗試更多像這樣的:[$.*[:digit:].*^]以匹配任何字符序列,一個數字,然後是任何字符序列。

Example on SQL Fiddle

+0

我很困惑!首先,我擔心我的問題很糟糕。我想拒絕任何包含一個或多個數字的字符串。例如:_'ab。 d''_沒問題,但應該拒絕_'a9b'_或_'9ab'_或_'ab12'_。現在,讓我們來看看我的想法:'^ [^ [:digit:]] + $'不是'[^ foobar]'意味着「任何事情,但不是** _foobar_」?因此''[^ [:digit:]]'意思是「除**之外的任何東西**'[:digit:]'」?最後,看看你的想法:'[$。* [:digit:]。* ^]'並不意味着:任何包含美元符號或點或星號或任何數字或點(重複)或星號(重複)或^? – browning0