Подтвердить что ты не робот

ПРОВЕРЬТЕ CONSTRAINT строки, чтобы содержать только цифры. (Oracle SQL)

У меня есть столбец, скажем PROD_NUM, который содержит "число", которое остается заполненным нулями. Например, 001004569. Они имеют длину всего 9 символов.

Я не использую числовой тип, потому что нормальная операция на числах не имеет смысла в этих "числах" (например, PROD_NUM * 2 не имеет никакого смысла.) И поскольку они имеют одинаковую длину, столбец определяемый как CHAR (9)

CREATE TABLE PRODUCT (
    PROD_NUM CHAR(9) NOT NULL
    -- ETC.
)

Я хотел бы ограничить PROD_NUM, поэтому он может содержать только девять цифр. Нет пробелов, никаких других символов, кроме '0' - '9'

4b9b3361

Ответ 1

REGEXP_LIKE(PROD_NUM, '^[[:digit:]]{9}$')

Ответ 2

Вы уже получили несколько приятных ответов о том, как продолжить свой текущий путь. Пожалуйста, позвольте мне предложить другой путь: вместо этого используйте число (9,0).

Причины:

  • Вам не нужно дополнительное контрольное ограничение, чтобы подтвердить, что оно содержит действительное число.

  • Вы не обманываете оптимизатора. Например, сколько prod_num "BETWEEN" 000000009 "и" 000000010 "? В нем есть множество символов. В то время как" prod_num между 9 и 10", очевидно, выбирает только два числа. Большие качества будут лучше, что приведет к лучшим планам выполнения.

  • Вы не обманываете будущих коллег, которые должны поддерживать ваш код. Назвав его "prod_num", они автоматически предполагают, что он содержит число.

Ваше приложение может использовать lpad (to_char (prod_num), 9, '0'), предпочтительно отображаться в представлении.

С уважением, Роб.

(обновление от MH) В потоке комментариев есть обсуждение, которое приятно иллюстрирует различные вещи, которые следует учитывать в отношении этого подхода. Если эта тема интересна, вы должны их прочитать.

Ответ 3

Работает во всех версиях:

TRANSLATE(PROD_NUM,'123456789','000000000') = '000000000'

Ответ 4

Я думаю, что codegender regexp будет работать нормально, но я подозреваю, что он немного медленный.

Вы можете сделать (непроверенный)

replace (translate (prod_num, '0123456789', 'NNNNNNNNNN'), 'N', null) имеет значение null

Ответ 5

Передайте его целому числу, верните его в varchar и убедитесь, что он равен исходной строке?

Ответ 6

В MSSQL я могу использовать что-то вроде этого как тест ограничения:

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

Я не человек Oracle, но я не думаю, что они поддерживают списки символов в квадратных скобках.

Ответ 7

на сервере MS SQL я использую эту команду: alter table add constraint [cc_mytable_myfield] check (cast (myfield as bigint) > 0)

Ответ 8

Не уверен в производительности, но если вы знаете диапазон, будет работать следующее. Использует ограничение 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  );