Se ricevi il messaggio di errore 4982 in SQL Server, è perché la tabella di origine non ha un vincolo che limita i dati solo all'intervallo supportato dalla partizione a cui stai tentando di passare.
Esempio di errore
Ecco come appare l'errore:
Msg 4982, Level 16, State 1, Line 1 ALTER TABLE SWITCH statement failed. Check constraints of source table 'Test.dbo.OrdersOld' allow values that are not allowed by range defined by partition 3 on target table 'Test.dbo.OrdersNew'.
La formulazione esatta dipenderà dai nomi delle tabelle, dalla partizione, dall'ambiente, ecc.
Quando si tenta di trasferire i dati su una nuova partizione, si desidera essere sicuri che i dati aderiscano all'intervallo di quella partizione. Ad esempio, se la tua partizione ha un intervallo da 1 a 10, non vuoi inserire accidentalmente valori compresi tra 11 e 20.
Anche SQL Server vuole essere sicuro, ed è per questo che viene visualizzato questo errore. Quando si tenta di cambiare i dati, SQL Server esamina la tabella di origine per un CHECK
vincolo che limita i dati all'intervallo specificato nella partizione di destinazione. Se non ne trova uno, viene visualizzato questo errore.
Per risolvere questo problema, aggiungi un CHECK
vincolo alla tabella di origine e assicurati che limiti i dati all'intervallo supportato dalla partizione a cui stai passando.
Esempio di codice problema
Ecco il codice che ha causato l'errore:
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 PARTITION FUNCTION OrdersNewPartitionFunction (date)
AS RANGE RIGHT FOR VALUES (
'20200201',
'20200301',
'20200401'
);
GO
CREATE PARTITION SCHEME OrdersNewPartitionScheme
AS PARTITION OrdersNewPartitionFunction
TO (
OrdersNewFg1,
OrdersNewFg2,
OrdersNewFg3,
OrdersNewFg4
);
GO
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 INTO OrdersOld(OrderDate, OrderDesc) VALUES
('20200302', 'Cat food'),
('20200315', 'Water bowl'),
('20200318', 'Saddle for camel'),
('20200321', 'Dog biscuits'),
('20200328', 'Bigfoot shoes');
GO
CREATE TABLE OrdersNew (
OrderDate date NOT NULL,
OrderId int IDENTITY NOT NULL,
OrderDesc varchar(255) NOT NULL
)
ON OrdersNewPartitionScheme (OrderDate),
CONSTRAINT PKOrdersNew PRIMARY KEY CLUSTERED(OrderDate,OrderId);
GO
ALTER TABLE OrdersOld
SWITCH TO OrdersNew PARTITION 3;
Risultato:
Msg 4982, Level 16, State 1, Line 1 ALTER TABLE SWITCH statement failed. Check constraints of source table 'Test.dbo.OrdersOld' allow values that are not allowed by range defined by partition 3 on target table 'Test.dbo.OrdersNew'.
Soluzione
Ecco lo stesso codice ma questa volta con il CHECK
appropriato vincolo aggiunto.
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 PARTITION FUNCTION OrdersNewPartitionFunction (date)
AS RANGE RIGHT FOR VALUES (
'20200201',
'20200301',
'20200401'
);
GO
CREATE PARTITION SCHEME OrdersNewPartitionScheme
AS PARTITION OrdersNewPartitionFunction
TO (
OrdersNewFg1,
OrdersNewFg2,
OrdersNewFg3,
OrdersNewFg4
);
GO
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 INTO OrdersOld(OrderDate, OrderDesc) VALUES
('20200302', 'Cat food'),
('20200315', 'Water bowl'),
('20200318', 'Saddle for camel'),
('20200321', 'Dog biscuits'),
('20200328', 'Bigfoot shoes');
GO
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
ALTER TABLE OrdersOld
SWITCH TO OrdersNew PARTITION 3;
Risultato:
Commands completed successfully.
I dati sono stati ora trasferiti correttamente nella partizione.