Вычисленная колонка не может быть сохранена
У меня есть пользовательская функция, и я пытаюсь создать постоянный столбец, используя эту функцию.
Это дает мне следующую ошибку.
Вычисленный столбец "FormattedSSN" в таблице "SomeTable" не может быть сохранен, потому что столбец не является детерминированным.
Вот функция:
ALTER FUNCTION [dbo].[FormatSSN]()
RETURNS VARCHAR(11)
AS
BEGIN
return '';
END
Вот запрос на добавление столбца с помощью функции:
ALTER TABLE SomeTable
ADD FormattedSSN as dbo.FormatSSN() PERSISTED
Пожалуйста, предложите, есть ли выход. Спасибо.
Ответы
Ответ 1
Добавьте WITH SCHEMABINDING к следующей функции:
ALTER FUNCTION [dbo].[FormatSSN]
(
@SSN VARCHAR(9)
)
RETURNS CHAR(11)
WITH SCHEMABINDING
AS
BEGIN
your stuff here
END
а затем запустите это, чтобы проверить:
IF OBJECTPROPERTY (OBJECT_ID(N'[dbo].[FormatSSN]'),'IsDeterministic') = 1
PRINT 'Function is detrministic.'
ELSE IF OBJECTPROPERTY (OBJECT_ID(N'[dbo].[FormatSSN]'),'IsDeterministic') = 0
PRINT 'Function is NOT detrministic'
GO
Здесь работает.
Ответ 2
Как напрямую указать определение:
ALTER TABLE SomeTable
ADD FormattedSSN as
case when len(EmployeeSSN) = 9 then
substring(EmployeeSSN, 1, 3) + '-' +
substring(EmployeeSSN, 4, 2) + '-' +
substring(EmployeeSSN, 6, 4)
else EmployeeSSN end
PERSISTED
Ответ 3
Вместо вызова UDF, установите выражение вычисленного столбца на
Case When Len(EmployeeSSN) = 0 Then
SUBSTRING(EmployeeSSN, 1, 3) + '-' +
SUBSTRING(EmployeeSSN, 4, 2) + '-' +
SUBSTRING(EmployeeSSN, 6, 4)
Else EmployeeSSN End
В таблице Create script вы можете добавить столбец:
[NewColumnName] As
(Case When len([UpdateUserId])=(0) T
Then (((substring([UpdateUserId],(1),(3))+'-')+
substring([UpdateUserId],(4),(2)))+'-')+
substring([UpdateUserId],(6),(4))
Else [UpdateUserId] End) PERSISTED,
Ответ 4
Создайте не вычисленный столбец соответствующего типа данных. Создайте триггер Insert (и триггер обновления, если данные будут изменены). Затем вы можете сохранить вывод функции в столбце.
ALTER TABLE SomeTable ADD FormattedSSN VARCHAR(11)
GO
CREATE TRIGGER dbo.TR_I_SomeTable ON dbo.SomeTable AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
update s
set s.FormattedSSN = dbo.FormatSSN()
from SomeTable AS s
join inserted i on i.id = s.id
END
GO