sql >> データベース >  >> RDS >> Sqlserver

「ALTERTABLESWITCHステートメントが失敗しました」を修正する方法メッセージ4982(SQL Server)

    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.

    これで、データは正常にパーティションに切り替えられました。


    1. PostgreSQL-結果セットを返すストアドプロシージャに動的SQLを記述します

    2. NEWSEQUENTIALID()を使用して、SQLServerでインクリメントGUIDを作成します

    3. SQL Server ServerManagementStudioを使用したデータベースのインポート/エクスポート

    4. JDBCで開いている接続をプログラムでチェックする