[英]Database Migration from SQL Server 2008 Express to 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.