Вычисляемый столбец SQL Server: как установить значение NOT NULL, без сохранения - PullRequest
0 голосов
/ 04 июля 2019

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

ALTER TABLE UnitHistory
ADD 
    [PrefixedUnitId] AS ((UnitHistory.UnitIdPrefix + cast(UnitHistory.UnitId     
    AS nvarchar(8)))) NOT NULL
GO

дает

Только вычисленные ограничения UNIQUE или PRIMARY KEY могут быть созданы при вычислении столбцы, в то время как ограничения CHECK, FOREIGN KEY и NOT NULL требуют чтобы вычисляемые столбцы были сохранены. Сообщение 15135, уровень 16, состояние 15, Процедура sp_addextendedproperty, строка 72 Объект недействителен. расширенный свойства не разрешены для 'dbo.UnitHistory.PrefixedUnitId', или объект не существует.

Теперь я понимаю, что говорится в сообщении, и, конечно же, использование PERSISTED NOT NULL действительно приводит к появлению столбца.

Однако, чтобы сэкономить место, я бы хотел, чтобы столбец не сохранялся.

Есть ли способ иметь вычисляемый столбец NOT NULL, но не постоянным, когда нижележащие столбцы NOT NULL?

Примечание: он должен работать на SQL Server 2012 SP2

1 Ответ

1 голос
/ 04 июля 2019

Это кажется полностью избыточным, но вы можете повторить условие в ограничении check:

ALTER TABLE UnitHistory
    ADD PrefixedUnitId AS ( UnitHistory.UnitIdPrefix + cast(UnitHistory.UnitId AS nvarchar(8)) );

ALTER TABLE UnitHistory
    ADD CONSTRAINT CHECK ( UnitHistory.UnitIdPrefix + cast(UnitHistory.UnitId AS nvarchar(8)) IS NOT NULL );

Однако, поскольку исходные столбцы равны NOT NULL, результат никогда не может быть NULL.

Понятие непостоянных вычисляемых столбцов заключается в том, что они рассчитаны на вывод , а не ввод .Я думаю, это объясняет, почему ограничения check не подходят.

Например, у вас может быть таблица с вычисляемым столбцом, который генерирует ошибку, и при этом полностью использовать таблицу:

create table t (
    id int identity primary key,
    x int,
    computed as (1 / 0)
);

-- works
insert into t (x) values (1);

-- works
select x
from t;

-- fails
select *
from t;

Здесь - это db <> fiddle.

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

...