SQL Serverでエラーメッセージ4982が表示される場合は、ソーステーブルに、切り替えようとしているパーティションでサポートされている範囲のみにデータを制限する制約がないためです。
エラーの例
エラーは次のようになります。
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'.
正確な表現は、テーブル名、パーティション、環境などによって異なります。
データを新しいパーティションに切り替えようとするときは、データがそのパーティションの範囲に準拠していることを確認する必要があります。たとえば、パーティションの範囲が1〜10の場合、誤って11〜20の値をそこに入れたくないでしょう。
SQL Serverも確認したいので、このエラーが発生します。データを切り替えようとすると、SQLServerはソーステーブルでCHECK
を探します。 データを宛先パーティションで指定された範囲に制限する制約。見つからない場合は、このエラーが発生します。
これを修正するには、CHECK
を追加します ソーステーブルへの制約を設定し、切り替え先のパーティションでサポートされている範囲にデータが制限されていることを確認してください。
問題コードの例
エラーの原因となったコードは次のとおりです。
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;
結果:
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'.
解決策
これは同じコードですが、今回は適切なCHECK
を使用します 制約が追加されました。
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;
結果:
Commands completed successfully.
これで、データは正常にパーティションに切り替えられました。