Poniższy kod wykonuje następujące czynności:
- Tworzy bazę danych partycja play w C: \ TEMP
- Tworzy dwie identyczne partycjonowane tabele play_table i archive_play_table
- Przełącza partycję 1 tabeli odtwarzania do partycji 1 tabeli odtwarzania
- Tworzy nową niepartycjonowaną tabelę temp_table o tej samej strukturze co play_table w tej samej grupie plików co partycja 2 play_table
- Przełącza partycję play_table_partition 2 na temp_table
Próbuje przełączyć temp_table z powrotem na partycję play_table 2 i kończy się niepowodzeniem
Msg 4982, poziom 16, stan 1, wiersz 64 ALTER TABLE SWITCH instrukcja nie powiodła się. Sprawdź ograniczenia tabeli źródłowej „play_partition.dbo.temp_table” dopuszczaj wartości, które nie są dozwolone przez zakres zdefiniowany przez partycję 2 w tabeli docelowej „play_partition.dbo.play_table”.
Dlaczego to się nie udaje?
Używam SQL Server 2014 (wersja Enterprise Edition Trial).
Pozdrowienia,
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
źródło
źródło
Odpowiedzi:
Podczas pracy z przełączaniem partycji SQL Server będzie musiał sprawdzić, czy granice tabeli źródłowej / partycji mieszczą się w granicach tabeli docelowej / partycji. Innymi słowy, próbujesz przełączyć dane z
dbo.temp_table
nadbo.play_table
partycję 2. Pomyśl o tym w ten sposób, dane dlac1
indbo.temp_table
są ograniczone tylko przez typ danych (int
), więc możesz mieć wartości od -14 147 483 648 do 2 147 483 647 . Ale odwrotnie, miejsce docelowe (dbo.play_table
partycja 2) ma zakres od 4 do 2 147 483 647.Twoje dane nie naruszają tego, ale nie pozwalają na to metadane. Równie łatwo możesz wstawić wartość -10 do
dbo.temp_table
. Przełączanie partycji nie powiedzie się w ten sam sposób i ma większy sens, ponieważ -10 nie mieści się wdbo.play_table
granicach drugiej partycji.Jeśli chcesz, aby ten kod działał, musisz wyraźnie powiedzieć SQL Serverowi, że
dbo.temp_table
nigdy nie będzie zawierał żadnych danych, które nie zmieściłyby się nadbo.play_table
drugiej partycji. Możesz to zrobić z ograniczeniem sprawdzania:Powyższy przykładowy dodatek do kodu sprawia, że jest to działające rozwiązanie. Teraz SQL Server wie, że dane
dbo.temp_table
mogą zmieścić się na partycji 2 zdbo.play_table
powodu dodanego ograniczenia sprawdzaniadbo.temp_table
.źródło