簡體   English   中英

在SQL Server 2008 R2 Enterprise中創建分區視圖

[英]Creating a partitioned view in SQL Server 2008 R2 Enterprise

我正在擴展一些舊軟件,該軟件可以按公司將數據拆分為多個架構,例如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.

我是否缺少簡單的東西? 我只是在這里離開左側區域嗎?

您需要一個約束,該約束定義將哪一列用作分區列。 如錯誤提示所示,您沒有定義。 文檔中所述:

要對分區視圖執行更新,分區列必須是基表主鍵的一部分。 如果視圖不可更新,則可以在允許更新的視圖上創建INSTEAD OF觸發器。 您應該在觸發器中設計錯誤處理,以確保沒有插入重復的行。 有關在視圖上設計的INSTEAD OF觸發器的示例,請參見設計INSTEAD OF觸發器。

換句話說,SQL Server需要能夠確定哪個表獲得了更新。

您可能可以更改表以包含公司名稱列,然后將其用作主鍵的一部分。 這樣的事情可能會起作用:

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

另一種方法是按照文檔中的建議使用instead of觸發器。

萬一有人遇到這種情況,您可以使用計算列進行分區,只需確保使其成為持久的計算列即可。

在這種情況下,計算列應為left([ACCOUNTID],(3) ,分區約束應為<computed column> = 'CP1' 。注意:在約束中使用left()將導致其仍掃描所有分區。CHECK約束只能使用以下運算符: BETWEEN, AND, OR, <, <=, >, >=, =.

另外,由於該問題引用了企業版,因此​​使用分區表而不是分區視圖會獲得更好的性能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM