Col*_*ley 9 sql-server partitioning sql-server-2014
下面的代码执行以下操作:
尝试将 temp_table 切换回 play_table 分区 2 并失败
消息 4982,级别 16,状态 1,第 64 行 ALTER TABLE SWITCH 语句失败。检查源表“play_partition.dbo.temp_table”的约束允许目标表“play_partition.dbo.play_table”上的分区 2 定义的范围不允许的值。
为什么会失败?
我使用的是 SQL Server 2014(企业版试用版)。
问候,
科林戴利
http://www.colindaley.com/translator
/* Playing with partitioned tables */
USE master;
GO
DROP DATABASE play_partition;
GO
CREATE DATABASE play_partition
ON PRIMARY(
NAME = play_partition
, FILENAME = 'C:\TEMP\play_partition.mdf')
,FILEGROUP play_fg1(
NAME = play_fg1
,FILENAME = 'C:\TEMP\play_fg1f1.ndf')
,FILEGROUP play_fg2(
NAME = play_fg2f1
,FILENAME = 'C:\TEMP\play_fg2f1.ndf');
GO
USE play_partition;
CREATE PARTITION FUNCTION play_range(INT)
AS RANGE LEFT FOR VALUES(3);
-- Partition scheme
CREATE PARTITION SCHEME play_scheme
AS PARTITION play_range TO (play_fg1, play_fg2);
-- Partitioned tables
CREATE TABLE dbo.play_table(
c1 INT NOT NULL CONSTRAINT PK_play_table_c1 PRIMARY KEY CLUSTERED
)
ON play_scheme(c1);
CREATE TABLE dbo.archive_play_table(
c1 INT NOT NULL CONSTRAINT PK_archive_play_table_c1 PRIMARY KEY CLUSTERED
)
ON play_scheme(c1);
-- partition 1 = {1, 2, 3}, partiion 2 = {4, 5, 6}
INSERT INTO dbo.play_table(c1) VALUES (1), (2), (3), (4), (5), (6);
-- move partition 1 from play_table to archive play_table
ALTER TABLE dbo.play_table
SWITCH PARTITION 1 to dbo.archive_play_table PARTITION 1;
-- create empty table with same structure as dbo.play_table
SELECT * INTO dbo.temp_table FROM dbo.play_table WHERE 1 = 0;
-- move temp_table to filegroup play_fg2
ALTER TABLE dbo.temp_table
ADD CONSTRAINT PK_temp_table_c1 PRIMARY KEY CLUSTERED(c1) ON play_fg2;
-- move contents of play_table to temp_table, which is not partitioned
-- but is in the same filegroup
ALTER TABLE dbo.play_table
SWITCH PARTITION 2 TO temp_table;
PRINT 'Switched from partitioned table to non-partitioned table';
-- move data back to partitioned play_table from unpartitioned temp_table
-- FAIL
ALTER TABLE dbo.temp_table
SWITCH TO play_table partition 2;
PRINT 'Switched from non-partitioned table to partitioned table';
SELECT 'archive_play_table' as table_name, t1.c1
FROM dbo.archive_play_table AS t1
UNION ALL
SELECT 'temp_table' AS table_name, t1.c1
FROM dbo.temp_table as t1
ORDER BY 1, 2;
Run Code Online (Sandbox Code Playgroud)
Tho*_*ger 11
当您使用分区切换时,SQL Server 需要验证源表/分区边界是否适合目标表/分区边界。换句话说,您正在尝试将数据从dbo.temp_table
todbo.play_table
的分区 2切换。可以这样想,c1
indbo.temp_table
的数据仅受数据类型 ( int
) 的约束,因此您可以拥有从 -2,147,483,648 到 2,147,483,647 的值. 但相反,您的目的地(dbo.play_table
分区 2)的范围从 4 到 2,147,483,647。
您的数据没有违反这一点,但元数据不允许这样做。您可以轻松地将值 -10 插入到dbo.temp_table
. 分区切换会以同样的方式失败并且更有意义,因为 -10 不适合dbo.play_table
的第二个分区边界。
如果你想让这段代码工作,你需要明确地告诉 SQL Serverdbo.temp_table
永远不会有任何不适合dbo.play_table
的第二个分区的数据。您可以使用检查约束来做到这一点:
/******************************************************************************
your code omitted for brevity
******************************************************************************/
-- move contents of play_table to temp_table, which is not partitioned
-- but is in the same filegroup
ALTER TABLE dbo.play_table
SWITCH PARTITION 2 TO temp_table;
PRINT 'Switched from partitioned table to non-partitioned table';
/******************************************************************************
added check constraint so that data can fit in the destination partition
******************************************************************************/
alter table dbo.temp_table
add constraint CK_TempTable_C1 check (c1 >= 4);
go
/******************************************************************************
end of added code
******************************************************************************/
-- move data back to partitioned play_table from unpartitioned temp_table
-- this will no longer FAIL
ALTER TABLE dbo.temp_table
SWITCH TO play_table partition 2;
PRINT 'Switched from non-partitioned table to partitioned table';
/******************************************************************************
your code omitted for brevity
******************************************************************************/
Run Code Online (Sandbox Code Playgroud)
上述示例添加到您的代码使其成为一个有效的解决方案。现在的SQL Server知道,在数据dbo.temp_table
能够适应分区2的dbo.play_table
,因为增加的检查约束的dbo.temp_table
。
归档时间: |
|
查看次数: |
20507 次 |
最近记录: |