计算列不能保留

时间:2009-11-13 21:42:03

标签: sql sql-server

我有一个自定义函数,我正在尝试使用此函数创建一个持久列。

它给了我以下错误。

  

表'SomeTable'中的计算列'FormattedSSN'无法保留,因为该列是非确定性的。

这是功能:

ALTER FUNCTION [dbo].[FormatSSN]()
RETURNS VARCHAR(11)
AS
BEGIN
    return '';
END

以下是使用函数添加列的查询:

ALTER TABLE SomeTable
ADD FormattedSSN as dbo.FormatSSN() PERSISTED

如果有任何出路,请建议。感谢。

4 个答案:

答案 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