Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

So beheben Sie „ALTER TABLE SWITCH-Anweisung fehlgeschlagen“ Msg 4982 (SQL Server)

Wenn Sie die Fehlermeldung 4982 in SQL Server erhalten, liegt das daran, dass Ihre Quelltabelle keine Einschränkung hat, die Daten nur auf den Bereich beschränkt, der von der Partition unterstützt wird, zu der Sie wechseln möchten.

Fehlerbeispiel

So sieht der Fehler aus:

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'.

Der genaue Wortlaut hängt von Ihren Tabellennamen, der Partition, der Umgebung usw. ab.

Wenn Sie versuchen, Daten auf eine neue Partition zu verschieben, möchten Sie sicher sein, dass die Daten dem Bereich dieser Partition entsprechen. Wenn Ihre Partition beispielsweise einen Bereich von 1 bis 10 hat, möchten Sie dort nicht versehentlich Werte zwischen 11 und 20 einfügen.

SQL Server möchte auch sicher sein, und deshalb erhalten Sie diesen Fehler. Wenn Sie versuchen, die Daten zu wechseln, sucht SQL Server in der Quelltabelle nach einem CHECK Einschränkung, die die Daten auf den Bereich beschränkt, der in der Zielpartition angegeben ist. Wenn es keinen findet, erhalten Sie diesen Fehler.

Um dies zu beheben, fügen Sie ein CHECK hinzu Beschränkung auf die Quelltabelle und stellen Sie sicher, dass sie die Daten auf den Bereich beschränkt, der von der Partition unterstützt wird, zu der Sie wechseln.

Beispiel für Problemcode

Hier ist der Code, der den Fehler verursacht hat:

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;

Ergebnis:

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'.

Lösung

Hier ist derselbe Code, aber diesmal mit dem passenden CHECK Einschränkung hinzugefügt.

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;

Ergebnis:

Commands completed successfully.

Die Daten wurden nun erfolgreich auf die Partition ausgelagert.