sql >> Base de Datos >  >> RDS >> Sqlserver

Cambiar una partición en SQL Server (T-SQL)

En SQL Server, puede cambiar particiones dentro y fuera de una tabla particionada.

Puedes hacer esto con ALTER TABLE declaración. Básicamente, es así:

ALTER TABLE OldTable
SWITCH TO NewTable PARTITION x

Esto cambia la partición para OldTable en la partición x de NewTable (donde x es el número de partición).

Ejemplo

Antes de comenzar a cambiar, configuremos dos mesas. Uno (llamado OrdersOld ) contendrá los datos que queremos "cambiar" a la otra tabla (llamada OrdersNew ).

Particionaremos OrdersNew en cuatro particiones.

-- Create filegroups
ALTER DATABASE Test ADD FILEGROUP OrdersNewFg1;
GO

ALTER DATABASE Test ADD FILE (  
    NAME = OrdersNewFg1dat,  
    FILENAME = '/var/opt/mssql/data/OrdersNewFg1dat.ndf',  
    SIZE = 5MB,  
    MAXSIZE = 100MB,  
    FILEGROWTH = 5MB
    )  
TO FILEGROUP OrdersNewFg1;
GO

ALTER DATABASE Test ADD FILEGROUP OrdersNewFg2;
GO

ALTER DATABASE Test ADD FILE (  
    NAME = OrdersNewFg2dat,  
    FILENAME = '/var/opt/mssql/data/OrdersNewFg2dat.ndf',  
    SIZE = 5MB,  
    MAXSIZE = 100MB,  
    FILEGROWTH = 5MB
    )  
TO FILEGROUP OrdersNewFg2;
GO
ALTER DATABASE Test ADD FILEGROUP OrdersNewFg3;
GO

ALTER DATABASE Test ADD FILE (  
    NAME = OrdersNewFg3dat,  
    FILENAME = '/var/opt/mssql/data/OrdersNewFg3dat.ndf',  
    SIZE = 5MB,  
    MAXSIZE = 100MB,  
    FILEGROWTH = 5MB
    )  
TO FILEGROUP OrdersNewFg3;
GO
ALTER DATABASE Test ADD FILEGROUP OrdersNewFg4;
GO

ALTER DATABASE Test ADD FILE (  
    NAME = OrdersNewFg4dat,  
    FILENAME = '/var/opt/mssql/data/OrdersNewFg4dat.ndf',  
    SIZE = 5MB,  
    MAXSIZE = 100MB,  
    FILEGROWTH = 5MB
    )  
TO FILEGROUP OrdersNewFg4;
GO

-- Create a partition function that will result in four partitions  
CREATE PARTITION FUNCTION OrdersNewPartitionFunction (date)  
    AS RANGE RIGHT FOR VALUES (
        '20200201', 
        '20200301',
        '20200401'
    );
GO

-- Create a partition scheme that maps the partitions to the filegroups
CREATE PARTITION SCHEME OrdersNewPartitionScheme
    AS PARTITION OrdersNewPartitionFunction  
    TO (
        OrdersNewFg1,
        OrdersNewFg2,
        OrdersNewFg3,
        OrdersNewFg4
        );  
GO

-- Create a table that contains the data that we will be switching in.  
-- Note that the filegroup matches the filegroup of the partition that we will switch in to.
-- Include CHECK constraint to restrict data to the range specified in the switch-in partition
CREATE TABLE OrdersOld (
    OrderDate date NOT NULL,
    OrderId int IDENTITY NOT NULL,
    OrderDesc varchar(255) NOT NULL,
    CONSTRAINT chkDate CHECK (OrderDate >= '20200301' AND OrderDate < '20200401'),
    CONSTRAINT PKOrdersOld PRIMARY KEY CLUSTERED(OrderDate, OrderId)
    )
    ON OrdersNewFg3;
GO

-- Insert data into the OrdersOld table. This is the data we will be switching in to the OrdersNew table.
INSERT INTO OrdersOld(OrderDate, OrderDesc) VALUES
    ('20200302', 'Cat food'),
    ('20200315', 'Water bowl'),
    ('20200318', 'Saddle for camel'),
    ('20200321', 'Dog biscuits'),
    ('20200328', 'Bigfoot shoes');
GO

-- Create a partitioned table called OrdersNew that uses the OrderDate column as the partitioning column
CREATE TABLE OrdersNew (
    OrderDate date NOT NULL,
    OrderId int IDENTITY NOT NULL,
    OrderDesc varchar(255) NOT NULL,
    CONSTRAINT PKOrdersNew PRIMARY KEY CLUSTERED(OrderDate, OrderId)
    )  
    ON OrdersNewPartitionScheme (OrderDate);  
GO

-- Check how many rows are in each table
SELECT COUNT(*) AS OrdersOld 
FROM OrdersOld;

SELECT COUNT(*) AS OrdersNew
FROM OrdersNew;

Resultado:

+-------------+
| OrdersOld   |
|-------------|
| 5           |
+-------------+

+-------------+
| OrdersNew   |
|-------------|
| 0           |
+-------------+

Tal como está ahora, OrdersOld contiene 5 filas y OrdersNew está vacío.

Es hora de cambiar los datos.

ALTER TABLE OrdersOld
SWITCH TO OrdersNew PARTITION 3;

Resultado:

Commands completed successfully.

Los datos ahora se han cambiado con éxito a la partición 3 de la tabla de destino.

Revisemos ambas tablas nuevamente.

SELECT COUNT(*) AS OrdersOld 
FROM OrdersOld;

SELECT COUNT(*) AS OrdersNew
FROM OrdersNew;

Resultado:

+-------------+
| OrdersOld   |
|-------------|
| 0           |
+-------------+

+-------------+
| OrdersNew   |
|-------------|
| 5           |
+-------------+

Esta vez OrdersOld está vacío y OrdersNew contiene 5 filas.

También podemos ejecutar la siguiente consulta para verificar la partición real en la que se encuentran los datos.

SELECT 
    p.partition_number AS [Partition], 
    fg.name AS [Filegroup], 
    p.Rows
FROM sys.partitions p
    INNER JOIN sys.allocation_units au
    ON au.container_id = p.hobt_id
    INNER JOIN sys.filegroups fg
    ON fg.data_space_id = au.data_space_id
WHERE p.object_id = OBJECT_ID('OrdersNew')
ORDER BY [Partition];

Resultado:

+-------------+--------------+--------+
| Partition   | Filegroup    | Rows   |
|-------------+--------------+--------|
| 1           | OrdersNewFg1 | 0      |
| 2           | OrdersNewFg2 | 0      |
| 3           | OrdersNewFg3 | 5      |
| 4           | OrdersNewFg4 | 0      |
+-------------+--------------+--------+

Como era de esperar, las 5 filas se asignan a la partición 3, en OrdersNewFg3 grupo de archivos.

Errores comunes

Error 4982

En mi ejemplo anterior, notará que creé un CHECK restricción al crear el OrdersOld mesa.

Si recibe el mensaje de error 4982 (ALTER TABLE SWITCH statement failed... ), podría ser que no hayas creado un CHECK restricción en la tabla de origen.

O podría ser que hayas creado un CHECK restricción, pero no impone valores entre el rango de la partición de cambio.

Debe asegurarse de que los valores de cambio estén, de hecho, dentro del rango definido por la partición, y SQL Server buscará un CHECK restricción en la tabla de origen que verifica esto.

Error 4939

Otro error común es el error 4939 (ALTER TABLE SWITCH statement failed... ).

Si obtiene este error, probablemente se deba a que está intentando cambiar a una partición que usa un grupo de archivos diferente al de la tabla de origen.

Uno de los requisitos para cambiar de partición es que tanto la tabla o partición de origen como la tabla o partición de destino deben estar ubicadas en el mismo grupo de archivos.

Para corregir este error, asegúrese de que la tabla de origen use el mismo grupo de archivos que la partición de destino.

Desconexión

Consulte Cambiar una partición en SQL Server para saber cómo cambiar una partición.