Проверить ограничение только один из трех столбцов не равен нулю

У меня есть таблица (SQL Server), которая содержит 3 типа результатов: FLOAT, NVARCHAR (30) или DATETIME (3 отдельных столбца). Я хочу убедиться, что для любой заданной строки только один столбец имеет результат, а остальные столбцы - NULL. Какое простейшее контрольное ограничение для этого?

Контекст для этого заключается в том, чтобы модифицировать возможность захвата нечисловых результатов в существующую систему. Добавление двух новых столбцов в таблицу с ограничением для предотвращения более чем одного результата для каждой строки было наиболее экономичным, не обязательно правильным.

Обновление: Извините, тип данных snafu. К сожалению, я не предполагал, что типы результатов, которые, как предполагается, интерпретируются как типы данных SQL Server, только общие термины, теперь исправлены.

53 голоса | спросил David Clarke 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 01 Sep 2011 04:46:22 +0400 2011, 04:46:22

3 ответа


65

Следующее должно сделать трюк:

CREATE TABLE MyTable (col1 FLOAT NULL, col2 NVARCHAR(30) NULL, col3 DATETIME NULL);
GO

ALTER TABLE MyTable
ADD CONSTRAINT CheckOnlyOneColumnIsNull
CHECK (
(CASE WHEN col1 IS NOT NULL THEN 1 ELSE 0 END
    + CASE WHEN col2 IS NOT NULL THEN 1 ELSE 0 END
    + CASE WHEN col3 IS NOT NULL THEN 1 ELSE 0 END)
    = 1
)
GO
ответил Mark Storey-Smith 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 01 Sep 2011 05:19:53 +0400 2011, 05:19:53
20

Вероятно, вам понадобится выполнить три теста в рамках ограничения, по одному тесту для каждой пары, для которого вы хотите быть нулевым, и одному для столбца, который должен быть не равным null:

ALTER TABLE table
ADD CONSTRAINT CK_one_is_null
CHECK (
     (col1 IS NOT NULL AND col2 IS NULL AND col3 IS NULL)
  OR (col2 IS NOT NULL AND col1 IS NULL AND col3 IS NULL) 
  OR (col3 IS NOT NULL AND col1 IS NULL AND col2 IS NULL)
);
ответил mrdenny 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 01 Sep 2011 05:21:12 +0400 2011, 05:21:12
3

Вот решение PostgreSQL с помощью встроенных функций массива :

ALTER TABLE your_table
ADD chk_only_one_is_not_null CHECK (array_length(array_remove(ARRAY[col1::text, col2::text, col3::text], NULL), 1) = 1);
ответил CrEOF 6 J0000006Europe/Moscow 2018, 20:12:19

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132