Ответ 1
REGEXP_LIKE(PROD_NUM, '^[[:digit:]]{9}$')
У меня есть столбец, скажем PROD_NUM, который содержит "число", которое остается заполненным нулями. Например, 001004569. Они имеют длину всего 9 символов.
Я не использую числовой тип, потому что нормальная операция на числах не имеет смысла в этих "числах" (например, PROD_NUM * 2 не имеет никакого смысла.) И поскольку они имеют одинаковую длину, столбец определяемый как CHAR (9)
CREATE TABLE PRODUCT (
PROD_NUM CHAR(9) NOT NULL
-- ETC.
)
Я хотел бы ограничить PROD_NUM, поэтому он может содержать только девять цифр. Нет пробелов, никаких других символов, кроме '0' - '9'
REGEXP_LIKE(PROD_NUM, '^[[:digit:]]{9}$')
Вы уже получили несколько приятных ответов о том, как продолжить свой текущий путь. Пожалуйста, позвольте мне предложить другой путь: вместо этого используйте число (9,0).
Причины:
Вам не нужно дополнительное контрольное ограничение, чтобы подтвердить, что оно содержит действительное число.
Вы не обманываете оптимизатора. Например, сколько prod_num "BETWEEN" 000000009 "и" 000000010 "? В нем есть множество символов. В то время как" prod_num между 9 и 10", очевидно, выбирает только два числа. Большие качества будут лучше, что приведет к лучшим планам выполнения.
Вы не обманываете будущих коллег, которые должны поддерживать ваш код. Назвав его "prod_num", они автоматически предполагают, что он содержит число.
Ваше приложение может использовать lpad (to_char (prod_num), 9, '0'), предпочтительно отображаться в представлении.
С уважением, Роб.
(обновление от MH) В потоке комментариев есть обсуждение, которое приятно иллюстрирует различные вещи, которые следует учитывать в отношении этого подхода. Если эта тема интересна, вы должны их прочитать.
Работает во всех версиях:
TRANSLATE(PROD_NUM,'123456789','000000000') = '000000000'
Я думаю, что codegender regexp будет работать нормально, но я подозреваю, что он немного медленный.
Вы можете сделать (непроверенный)
replace (translate (prod_num, '0123456789', 'NNNNNNNNNN'), 'N', null) имеет значение null
Передайте его целому числу, верните его в varchar и убедитесь, что он равен исходной строке?
В MSSQL я могу использовать что-то вроде этого как тест ограничения:
PROD_NUM NOT LIKE '%[^0-9]%'
Я не человек Oracle, но я не думаю, что они поддерживают списки символов в квадратных скобках.
на сервере MS SQL я использую эту команду: alter table add constraint [cc_mytable_myfield] check (cast (myfield as bigint) > 0)
Не уверен в производительности, но если вы знаете диапазон, будет работать следующее. Использует ограничение CHECK во время создания DDL.
alter table test add jz2 varchar2(4)
check ( jz2 between 1 and 2000000 );
как и
alter table test add jz2 varchar2(4)
check ( jz2 in (1,2,3) );
это также будет работать
alter table test add jz2 varchar2(4)
check ( jz2 > 0 );