在SQL Server 2008 R2 Enterprise中创建分区视图

在SQL Server 2008 R2 Enterprise中创建分区视图,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,我正在扩展一些遗留软件,这些软件按公司将数据拆分为多个模式,例如CP1.ACCOUNTS、CP2.ACCOUNTS、CPN.ACCOUNTS。我试图使用分区创建这些表的可更新视图,但是我得到了典型的“由于未找到分区列而不可更新”错误。我试图划分的列是主键,据我所知,它不是任何不允许的东西 因此,对于这样的表定义: SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [CP1

我正在扩展一些遗留软件,这些软件按公司将数据拆分为多个模式,例如CP1.ACCOUNTS、CP2.ACCOUNTS、CPN.ACCOUNTS。我试图使用分区创建这些表的可更新视图,但是我得到了典型的“由于未找到分区列而不可更新”错误。我试图划分的列是主键,据我所知,它不是任何不允许的东西

因此,对于这样的表定义:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [CP1].[ACCOUNTS](
    [ACCOUNTID] [char](10) NOT NULL,
    [LASTNAME] [varchar](60) NOT NULL,
    [FIRSTNAME] [varchar](35) NOT NULL,
    [MIDDLE] [varchar](26) NULL,
    [SUFFIX] [varchar](10) NULL,
    [ADDRESS1] [varchar](55) NULL,
    [ADDRESS2] [varchar](55) NULL,
    [SOME_FLAG] [tinyint] NULL,
    CONSTRAINT [ARM_CODE_KEY] PRIMARY KEY CLUSTERED 
        (
            [CODE_] ASC
        ) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [CP1].[ACCOUNTS]  WITH CHECK ADD  CONSTRAINT [CK__ACCOUNTS__CODE___4DD705FF] CHECK  ((left([ACCOUNTID],(3))='CP1'))
GO

ALTER TABLE [CP1].[ACCOUNTS] CHECK CONSTRAINT [CK__ACCOUNTS__CODE___4DD705FF]
GO

ALTER TABLE [CP1].[ACCOUNTS] ADD  DEFAULT ((0)) FOR [SOME_FLAG]
GO
其余的表完全按照上面的定义,遵循CP2、CP3、CPN模式,视图定义是简单的:

CREATE VIEW [ALL].[ACCOUNTS] AS
    SELECT * FROM CP1.ACCOUNTS
    UNION ALL
    SELECT * FROM CP2.ACCOUNTS
    --UNION ALL etc...
插入内容如下:

INSERT INTO [ALL].[ACCOUNTS]
           ([ACCOUNTID]
           ,[LASTNAME]
           ,[FIRSTNAME]
           ,[MIDDLE]
           ,[SUFFIX]
           ,[ADDRESS1]
           ,[ADDRESS2]
           ,[SOME_FLAG])
     VALUES
           ('CP1XYZ0001',
            'SMITH',
            'JOHN',
            'Q',
            '',
            '123 Fake St',
            'Apt 2',
            0,
GO
生成如下错误:

Msg 4436, level 16, State 12, Line 1
UNION ALL view 'ALL.ACCOUNTS' is not updatable because a partitioning column was not found.

我错过了一些简单的东西吗?我是不是在左边的字段中走得太远了?

您需要一个约束来定义哪个列用作分区列。正如错误所示,您没有定义一个。如以下文件所述:

要在分区视图上执行更新,分区列必须 是基表主键的一部分。如果一个视图不是 可更新,您可以在 允许更新。您应该在触发器中设计错误处理,以 确保没有插入重复的行。例如 请参见设计而不是在视图上设计触发器,而不是在视图上设计触发器 触发器

换句话说,SQL Server需要能够确定哪个表得到更新

您可以修改表以包含公司名称列,然后将其用作主键的一部分。类似的方法可能会奏效:

create table . . .
    CompanyName as 'CompanyA',
    primary key (AccountId, CompanyName)
    . . .

另一种方法是使用
而不是
触发器,如文档中所建议的那样。

如果有人遇到这种情况,您可以使用计算列进行分区,只需确保它是一个持久的计算列

在这种情况下,计算列应该是
left([ACCOUNTID],(3)
,分区约束应该是
='CP1'
。注意:在约束中使用
left()
将导致它仍然扫描所有分区。检查约束只能使用以下运算符:
介于和之间,或者,=,=。


此外,由于问题引用了企业版,因此使用分区表而不是分区视图可以获得更好的性能。

您可以编辑问题并包含
更新
语句吗?感谢您的建议,@gordon linhoff。我添加了insert语句,以及收到的错误的确切文本。Since是一个现有的表,您可以在表定义末尾附近的
ALTER table
语句中找到约束。特别是
ALTER table[CP1].[ACCOUNTS]和CHECK ADD constraint[CK\u ACCOUNTS\uuuu code\uuuu 4DD705FF]检查((左([ACCOUNTID],(3))='CP1'))
不幸的是,无法使用附加列,因为无法更新旧软件以指定插入时的值,并且分区列不支持默认值。我猜SQL Server无法识别
左侧(AccountId,3)
作为主键的一部分。请尝试添加计算列并在约束中使用它。不幸的是,计算列对于分区无效。我还查看了
而不是
触发器,发现这可能不适用于基于集合的操作。要插入的表可能会随着行的变化而变化。我没有注意到“我不确定计算列是否可用于分区。您可以在每个表上放置一个触发器,使用
ACCOUNTID3
(定义为off
ACCOUNTID
)添加一个新列。然后您可以将其用于分区。”。