如何使用标量函数设置列的默认值

时间:2012-01-20 13:30:50

标签: sql sql-server sql-server-2008

我有这样的表:

CREATE TABLE [dbo].[tbl](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Year] [int] NOT NULL,
[Month] [int] NOT NULL,
[Fields] [xml] NOT NULL,
[NameFromXML] [nvarchar](1000) NULL
) ON [PRIMARY]

Fields列中我像这样存储XML:

<Employees>
   <Person>
      <ID>0</ID>
      <Name>Ligha</Name>
      <LName>Agha</LName>
   </Person>
</Employees>

好的。我希望Name元素的持久值为NameFromXML。我写这个函数:

CREATE FUNCTION dbo.GetName
(
        @xml XML
)
RETURNS NVARCHAR(100)
WITH RETURNS NULL ON NULL INPUT
AS
   BEGIN
  RETURN @xml.value('/Employees[1]/Person[1]/Name[1]', 'nvarchar(100)')
   END
GO

但是当我编写此代码以添加默认值时:

ALTER TABLE tbl_Test_XML_Index_View  ADD CONSTRAINT  df_f  DEFAULT(dbo.GetName(Fields)) 
FOR namefromXML 

我收到了这个错误:

  

名称&#34;字段&#34;在这种情况下是不允许的。有效表达式是常量,常量表达式和(在某些上下文中)变量。不允许使用列名。

我如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

您似乎正在尝试为每一行存储冗余数据。如果XML中的某个名称发生了变化,会发生什么?您如何注意更新NameFromXML列?通过使用触发器?我可以给你建议,只使用常规列存储你需要的数据。编写插入/更新存储过程将把XML作为参数,并将数据从中插入到适当的列中。

答案 1 :(得分:1)

为什么不将它作为计算列始终是正确的,并且不再需要维护工作:

CREATE FUNCTION dbo.GetName
(
        @xml XML
)
RETURNS NVARCHAR(100)
WITH RETURNS NULL ON NULL INPUT
, SCHEMABINDING
AS
   BEGIN
  RETURN @xml.value('/Employees[1]/Person[1]/Name[1]', 'nvarchar(100)')
   END
GO
CREATE TABLE [dbo].[tbl](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Year] [int] NOT NULL,
[Month] [int] NOT NULL,
[Fields] [xml] NOT NULL,
[NameFromXML] AS dbo.GetName(Fields) persisted
) ON [PRIMARY]

insert into dbo.tbl (Year,Month,Fields)
select 1,1,'<Employees>
   <Person>
      <ID>0</ID>
      <Name>Ligha</Name>
      <LName>Agha</LName>
   </Person>
</Employees>'

select * from dbo.tbl

我必须在函数中添加SCHEMABINDING,以便将其视为 deterministic 。反过来,这允许我将计算列标记为persisted,这意味着如果需要,它可以被索引。