SQL ограничение с UNIQUE и CHECK - PullRequest
       31

SQL ограничение с UNIQUE и CHECK

0 голосов
/ 28 февраля 2020

Моя цель состоит в том, чтобы предотвратить вставку, если "адрес" с тем же "account_id", что и "is_principal" true (я хочу, чтобы только один адрес is_principal для учетной записи).

Есть ли способ создать SQL ограничение с UNIQUE и CHECK?

Я пробую это:

ALTER TABLE address ADD CONSTRAINT fk_account_adresses2_idx UNIQUE(account_id, CHECK (is_principal >= 1)); 

ОШИБКА:

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHECK (is_principal >= 1))' at line 1 (SQL: ALTER TABLE address ADD CONSTRAINT fk_compte_adresses2_idx UNIQUE(account_id, CHECK (is_principal >= 1));)

Спасибо.

РЕДАКТИРОВАТЬ:

ВСТАВИТЬ примеры, которые должны работать:

insert into `address` (`address`, `account_id`, `is_principal`) values (address 1, 1, 1);
insert into `address` (`address`, `account_id`, `is_principal`) values (address 2, 1, 0);
insert into `address` (`address`, `account_id`, `is_principal`) values (address 3, 1, 0);

ВСТАВИТЬ примеры, которые должны работать:

insert into `address` (`address`, `account_id`, `is_principal`) values (address 1, 1, 1);
insert into `address` (`address`, `account_id`, `is_principal`) values (address 2, 1, 1);

Ответы [ 2 ]

0 голосов
/ 28 февраля 2020
ALTER TABLE address 
ADD COLUMN for_check INT AS (CASE WHEN is_principal 
                                  THEN account_id 
                                  END) VIRTUAL,
ADD CONSTRAINT check_only_one_principal_address 
    UNIQUE INDEX (for_check);

fiddle

Сгенерированный столбец генерирует значение account_id для записи с is_principal = TRUE и NULL в другом случае. NULL не проверяются в ограничении UNIQUE.

Виртуальному сгенерированному столбцу не требуется дополнительное дисковое пространство.

Применимо для MySQL, начиная с версии 5.7.8 (если вы не укажете VIRTUAL и используйте столбец stati c, STORED, затем из 5.7.6).

0 голосов
/ 28 февраля 2020

Использовать разделенный запятыми синтаксис:

ALTER TABLE address ADD CONSTRAINT fk_account_adresses2_idx UNIQUE(account_id),
                    ADD CHECK (is_principal >= 1);

В качестве примечания, проверочные ограничения в версиях MySQL ранее, чем 8+, будут игнорироваться. Таким образом, если вы используете более раннюю версию MySQL, то проверочное ограничение будет игнорироваться.

...