我有一个自定义函数,我正在尝试使用此函数创建一个持久列。
它给了我以下错误。
表'SomeTable'中的计算列'FormattedSSN'无法保留,因为该列是非确定性的。
这是功能:
ALTER FUNCTION [dbo].[FormatSSN]()
RETURNS VARCHAR(11)
AS
BEGIN
return '';
END
以下是使用函数添加列的查询:
ALTER TABLE SomeTable
ADD FormattedSSN as dbo.FormatSSN() PERSISTED
如果有任何出路,请建议。感谢。
答案 0 :(得分:38)
将 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
在这里工作。
答案 1 :(得分:5)
如何直接指定定义:
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
答案 2 :(得分:3)
不是调用UDF,而是将计算列表达式设置为
Case When Len(EmployeeSSN) = 0 Then
SUBSTRING(EmployeeSSN, 1, 3) + '-' +
SUBSTRING(EmployeeSSN, 4, 2) + '-' +
SUBSTRING(EmployeeSSN, 6, 4)
Else EmployeeSSN End
在“创建表”脚本中,您可以添加一列:
[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,
答案 3 :(得分:1)
创建适当数据类型的非计算列。创建插入触发器(如果数据将更改,则创建更新触发器)。然后,您可以将函数输出保留在列中。
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