El siguiente código hace lo siguiente:
- Crea una base de datos play_partition en C: \ TEMP
- Crea dos tablas particionadas idénticas play_table y archive_play_table
- Cambia la partición play_table 1 a la partición archive_play_table 1
- Crea una nueva tabla no particionada temp_table con la misma estructura que play_table en el mismo grupo de archivos que play_table partición 2
- Cambia play_table_partition 2 a temp_table
Intenta cambiar temp_table de nuevo a play_table partición 2 y falla con
Mensaje 4982, Nivel 16, Estado 1, Línea 64 La instrucción ALTER TABLE SWITCH falló. Compruebe las restricciones de la tabla de origen 'play_partition.dbo.temp_table' para permitir valores que no están permitidos por el rango definido por la partición 2 en la tabla de destino 'play_partition.dbo.play_table'.
¿Por qué falla?
Estoy usando SQL Server 2014 (versión de prueba de Enterprise Edition).
Saludos,
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
fuente
fuente
Respuestas:
Cuando trabaje con el cambio de partición, SQL Server deberá verificar que los límites de la tabla / partición de origen puedan caber en los límites de la tabla / partición de destino. En otras palabras, usted está tratando de datos de conmutación de
dbo.temp_table
adbo.play_table
's partición 2. Piense en ello como esto, los datos para elc1
endbo.temp_table
está limitada sólo por el tipo de datos (int
), lo que puede tener valores comprendidos entre -2147483648 a 2147483647 . Pero a la inversa, su destino (dbo.play_table
partición 2) tiene un rango de 4 a 2,147,483,647.Sus datos no violan esto, pero son los metadatos los que no pueden permitirlo. Podría insertar fácilmente el valor -10 en
dbo.temp_table
. El cambio de partición fallaría de la misma manera y tendría más sentido, ya que -10 no cabe endbo.play_table
los límites de la segunda partición.Si desea hacer que este código funcione, deberá decirle explícitamente a SQL Server que
dbo.temp_table
nunca tendrá datos que no quepan endbo.play_table
la segunda partición. Puede hacer esto con una restricción de verificación:La adición de muestra anterior a su código hace que esta sea una solución funcional. Ahora SQL Server sabe que los datos
dbo.temp_table
pueden caber en la partición 2dbo.play_table
debido a la restricción de verificación agregada adbo.temp_table
.fuente