Разрешить только определенные значения в столбце B на основе значения столбца A - PullRequest
0 голосов
/ 18 апреля 2019

Я хочу разрешить, чтобы в столбец A можно было вставить только определенное количество значений, и, в зависимости от введенного значения, разрешить вставку в столбец B только определенного количества значений. Например

Например

  • Если A = 1, B может находиться в диапазоне от 1 до 9
  • Если A = 2, B может быть между 10 и 19
  • Если A = 3, B может быть между 20 и 29

Как мне этого добиться?

Я решил, что проверочные ограничения - лучшее место для начала. Простое ограничение гарантирует, что в столбец A могут быть добавлены только значения 1-3. Такие как:

CREATE TABLE dbo.test (
    col_a INT, 
    col_b INT,
    CONSTRAINT ch_col_a_valid_range CHECK (col_a BETWEEN 1 AND 3)
)
GO

Затем я предположил, что используя скалярную функцию, чтобы определить, является ли col_b допустимым, передав значение из col_a и col_b.

CREATE FUNCTION dbo.value_is_valid (
    @a INT, 
    @b INT
)
RETURNS BIT
AS 
BEGIN
    IF (@a = 1 AND @b BETWEEN 1 AND 9) RETURN 1;
    IF (@a = 2 AND @b BETWEEN 10 AND 19) RETURN 1;
    IF (@a = 3 AND @b BETWEEN 20 AND 29) RETURN 1;
    RETURN 0;
END
GO

Затем добавьте ограничение к таблице и вызовите функцию как часть проверки.

CREATE TABLE dbo.test (
    col_a INT, 
    col_b INT,
    CONSTRAINT ch_col_a_valid_range CHECK (col_a BETWEEN 1 AND 3),
    CONSTRAINT ch_col_b_valid_based_on_a CHECK(dbo.value_is_valid(col_a, col_b) = 1)
)
GO

Однако следующая вставка завершается неудачно, из-за чего возникает конфликт с добавленным ограничением ch_col_b_valid_based_on_a.

INSERT INTO dbo.test (
    col_a, 
    col_b
)
VALUES (1, 9)

Оператор INSERT конфликтовал с ограничением CHECK "ch_col_b_valid_based_on_a". Конфликт произошел в базе данных «MyDB», таблица «dbo.test».

Что я могу сделать, чтобы обойти это и достичь результата, упомянутого выше?


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

Ответы [ 2 ]

1 голос
/ 18 апреля 2019

Одним из методов является ограничение check:

CREATE TABLE dbo.test (
    col_a INT, 
    col_b INT,
    CONSTRAINT ch_col_a_valid_range CHECK (col_a BETWEEN 1 AND 3),
    CONSTRAINT chk_col_a_colb
        CHECK ( (col_a = 1 AND col_b BETWEEN 1 AND 9) OR
                (col_a = 2 AND col_b BETWEEN 10 AND 19) OR
                (col_a = 3 AND col_b BETWEEN 20 AND 29)
             )

);

Однако я могу склониться к созданию таблицы AB_valid со списком допустимых пар и использованием ограничения внешнего ключа.Таким образом, список допустимых значений может поддерживаться динамически, не требуя изменения определения таблицы.

0 голосов
/ 18 апреля 2019

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

CREATE TABLE dbo.test (
    col_a INT, 
    col_b INT,
    CONSTRAINT ch_col_a_valid_range CHECK (col_a BETWEEN 1 AND 3),
    CONSTRAINT ch_col_b_valid_based_on_a CHECK(col_b/10 + 1 = col_a)
);
...