Kode di bawah ini melakukan yang berikut:
- Membuat database play_partition di C: \ TEMP
- Membuat dua tabel yang dipartisi identik play_table dan archive_play_table
- Beralih partisi play_table 1 ke archive_play_table partisi 1
- Membuat tabel tanpa partisi baru temp_table dengan struktur yang sama seperti play_table pada filegroup yang sama dengan partisi play_table 2
- Alihkan play_table_partition 2 ke temp_table
Mencoba untuk beralih temp_table kembali ke partisi play_table 2 dan gagal dengan
Msg 4982, Level 16, Status 1, Baris 64 ALTER TABLE SWITCH pernyataan gagal. Periksa batasan tabel sumber 'play_partition.dbo.temp_table' memungkinkan nilai yang tidak diizinkan oleh kisaran yang ditentukan oleh partisi 2 pada tabel target 'play_partition.dbo.play_table'.
Mengapa ini gagal?
Saya menggunakan SQL Server 2014 (Percobaan Edisi Perusahaan).
Salam,
Colin Daley
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;
sql-server
partitioning
sql-server-2014
Colin Daley
sumber
sumber
Jawaban:
Ketika Anda bekerja dengan peralihan partisi, SQL Server perlu memverifikasi bahwa tabel sumber / batas partisi dapat masuk dalam tabel tujuan / batas partisi. Dengan kata lain, Anda mencoba untuk mengalihkan data dari
dbo.temp_table
kedbo.play_table
partisi 2. Pikirkan seperti ini, data untukc1
indbo.temp_table
hanya dibatasi oleh tipe data (int
), sehingga Anda dapat memiliki nilai mulai dari -2,147,483,648 hingga 2,147,483,647 . Tetapi sebaliknya, tujuan Anda (dbo.play_table
partisi 2) berkisar antara 4 hingga 2.147.483.647.Data Anda tidak melanggar ini, tetapi metadata yang tidak memungkinkan ini. Anda bisa dengan mudah memasukkan nilai -10 ke dalam
dbo.temp_table
. Pergantian partisi akan gagal dengan cara yang sama dan lebih masuk akal, karena -10 tidak cocok dengandbo.play_table
batas-batas partisi ke-2.Jika Anda ingin membuat kode ini berfungsi, Anda harus secara eksplisit memberi tahu SQL Server bahwa
dbo.temp_table
tidak akan pernah ada data yang tidak sesuai dengandbo.play_table
partisi ke-2. Anda bisa melakukan ini dengan batasan cek:Itu penambahan sampel di atas untuk kode Anda membuat ini solusi yang berfungsi. Sekarang SQL Server tahu bahwa data di
dbo.temp_table
dapat masuk dalam partisi 2dbo.play_table
karena kendala cek yang ditambahkandbo.temp_table
.sumber