Der folgende Code bewirkt Folgendes:
- Erstellt eine Datenbank play_partition in C: \ TEMP
- Erstellt zwei identische partitionierte Tabellen play_table und archive_play_table
- Schaltet die play_table-Partition 1 auf die archive_play_table-Partition 1 um
- Erstellt eine neue nicht partitionierte Tabelle temp_table mit derselben Struktur wie play_table in derselben Dateigruppe wie play_table Partition 2
- Schaltet play_table_partition 2 auf temp_table um
Versucht, temp_table wieder auf play_table Partition 2 umzuschalten und schlägt mit fehl
Meldung 4982, Ebene 16, Status 1, Zeile 64 ALTER TABLE SWITCH-Anweisung fehlgeschlagen. Überprüfen Sie die Einschränkungen der Quelltabelle 'play_partition.dbo.temp_table' und lassen Sie Werte zu, die nach dem von Partition 2 in der Zieltabelle 'play_partition.dbo.play_table' definierten Bereich nicht zulässig sind.
Warum scheitert es?
Ich verwende SQL Server 2014 (Enterprise Edition-Testversion).
Grüße,
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
quelle
quelle
Antworten:
Wenn Sie mit Partitionswechsel arbeiten, muss SQL Server überprüfen, ob die Grenzen der Quelltabelle / Partition in die Grenzen der Zieltabelle / Partition passen. Mit anderen Worten, Sie versuchen, Daten von
dbo.temp_table
derdbo.play_table
Partition 2 zu wechseln. Stellen Sie sich das so vor: Die Daten für dasc1
In werdendbo.temp_table
nur durch den Datentyp (int
) eingeschränkt, sodass Sie Werte zwischen -2.147.483.648 und 2.147.483.647 haben können . Umgekehrt hat Ihr Ziel (dbo.play_table
Partition 2) einen Bereich von 4 bis 2.147.483.647.Ihre Daten verletzen dies nicht, aber es sind die Metadaten, die dies nicht zulassen. Sie können genauso gut den Wert -10 in einfügen
dbo.temp_table
. Die Partitionsumschaltung würde auf die gleiche Weise fehlschlagen und sinnvoller sein, da -10 nicht indbo.play_table
die 2. Partitionsgrenzen passt .Wenn Sie diesen Code zum Laufen bringen möchten, müssen Sie SQL Server explizit mitteilen, dass
dbo.temp_table
niemals Daten vorhanden sind, die nicht indbo.play_table
die zweite Partition passen . Sie können dies mit einer Prüfbedingung tun:Die obige Beispielergänzung zu Ihrem Code macht dies zu einer funktionierenden Lösung. Jetzt weiß SQL Server, dass die Daten in
dbo.temp_table
Partition 2dbo.play_table
aufgrund der hinzugefügten Prüfbeschränkung für passen könnendbo.temp_table
.quelle