THAY ĐỔI BẢNG CHUYỂN ĐỔI từ bảng thông thường sang bảng được phân đoạn không thành công


9

Mã dưới đây thực hiện như sau:

  1. Tạo cơ sở dữ liệu play_partition trong C: \ TEMP
  2. Tạo hai bảng được phân vùng giống hệt nhau play_table và archive_play_table
  3. Chuyển phân vùng play_table 1 sang phân vùng archive_play_table 1
  4. Tạo một bảng không liên kết mới temp_table với cùng cấu trúc như play_table trên cùng một filegroup như phân vùng play_table 2
  5. Chuyển play_table_partition 2 sang temp_table
  6. Đã thử chuyển temp_table trở lại phân vùng play_table 2 và không thành công với

    Msg 4982, Cấp 16, Trạng thái 1, Dòng 64 ALTER TABLE SWITCH tuyên bố không thành công. Kiểm tra các ràng buộc của bảng nguồn 'play_partition.dbo.temp_table' cho phép các giá trị không được phép theo phạm vi được xác định bởi phân vùng 2 trên bảng đích 'play_partition.dbo.play_table'.

Tại sao nó thất bại?

Tôi đang sử dụng SQL Server 2014 (Bản dùng thử phiên bản doanh nghiệp).

Trân trọng,

Colin Daley

http://www.colindaley.com/translator

/* Playing with partitioned tables */

USE master;
GO

DROP DATABASE play_partition;
GO

CREATE DATABASE play_partition
    ON PRIMARY(
        NAME = play_partition
        , FILENAME = 'C:\TEMP\play_partition.mdf')
    ,FILEGROUP play_fg1(
        NAME = play_fg1
        ,FILENAME = 'C:\TEMP\play_fg1f1.ndf')
    ,FILEGROUP play_fg2(
        NAME = play_fg2f1
        ,FILENAME = 'C:\TEMP\play_fg2f1.ndf');
GO

USE play_partition;


CREATE PARTITION FUNCTION play_range(INT)
    AS RANGE LEFT FOR VALUES(3);

-- Partition scheme
CREATE PARTITION SCHEME play_scheme 
    AS PARTITION play_range TO (play_fg1, play_fg2);

-- Partitioned tables
CREATE TABLE dbo.play_table(
    c1 INT NOT NULL CONSTRAINT PK_play_table_c1 PRIMARY KEY CLUSTERED
)
    ON play_scheme(c1);

CREATE TABLE dbo.archive_play_table(
c1 INT NOT NULL CONSTRAINT PK_archive_play_table_c1 PRIMARY KEY CLUSTERED
)
    ON play_scheme(c1);

-- partition 1 = {1, 2, 3}, partiion 2 = {4, 5, 6}
INSERT INTO dbo.play_table(c1) VALUES (1), (2),  (3), (4), (5), (6);

-- move partition 1 from play_table to archive play_table
ALTER TABLE dbo.play_table
    SWITCH PARTITION 1 to dbo.archive_play_table PARTITION 1;

-- create empty table with same structure as dbo.play_table
SELECT * INTO dbo.temp_table FROM dbo.play_table WHERE 1 = 0;

-- move temp_table to filegroup play_fg2
ALTER TABLE dbo.temp_table
    ADD CONSTRAINT PK_temp_table_c1 PRIMARY KEY CLUSTERED(c1) ON play_fg2;

-- move contents of play_table to temp_table, which is not partitioned
-- but is in the same filegroup
ALTER TABLE dbo.play_table
    SWITCH PARTITION 2 TO temp_table;
PRINT 'Switched from partitioned table to non-partitioned table';

-- move data back to partitioned play_table from unpartitioned temp_table
-- FAIL
ALTER TABLE dbo.temp_table
    SWITCH TO play_table partition 2;
PRINT 'Switched from non-partitioned table to partitioned table';


SELECT 'archive_play_table' as table_name, t1.c1
    FROM dbo.archive_play_table AS t1
    UNION ALL
    SELECT 'temp_table' AS table_name, t1.c1
        FROM dbo.temp_table as t1
    ORDER BY 1, 2;

+1 cho câu hỏi của bạn. Bạn đã làm cho nó dễ dàng để repro và trả lời, do DDL bạn đặt ở đây. Vì điều đó, cảm ơn bạn. Tôi ước tôi có thể +10 câu hỏi như thế này.
Thomas Stringer

Cảm ơn. Lỗi đó cần một thông điệp tốt hơn. Khi nó đề cập đến các ràng buộc kiểm tra trên bảng (khi không có ràng buộc kiểm tra), thực tế đã không xảy ra với tôi rằng việc thiếu ràng buộc kiểm tra thực tế là vấn đề.
Colin Daley

Câu trả lời:


11

Khi bạn đang làm việc với chuyển đổi phân vùng, SQL Server sẽ cần xác minh rằng các ranh giới bảng / phân vùng nguồn có thể phù hợp với các ranh giới của bảng / phân vùng đích. Nói cách khác, bạn đang cố gắng để dữ liệu chuyển đổi từ dbo.temp_tableđể dbo.play_table's phân vùng 2. Hãy nghĩ về nó như thế này, các dữ liệu cho c1trong dbo.temp_tablechỉ bị hạn chế bởi các kiểu dữ liệu ( int), vì vậy bạn có thể có giá trị khác nhau, từ -2147483648 đến 2,147,483,647 . Nhưng ngược lại, đích đến của bạn ( dbo.play_tablephân vùng 2) có phạm vi từ 4 đến 2.147.483.647.

Dữ liệu của bạn không vi phạm điều này, nhưng đó là siêu dữ liệu không thể cho phép điều này. Bạn có thể dễ dàng chèn giá trị -10 vào dbo.temp_table. Việc chuyển đổi phân vùng sẽ thất bại theo cùng một cách và có ý nghĩa hơn, vì -10 không phù hợp với dbo.play_tableranh giới phân vùng thứ 2.

Nếu bạn muốn làm cho mã này hoạt động, bạn cần nói rõ ràng với SQL Server rằng dbo.temp_tablesẽ không bao giờ có bất kỳ dữ liệu nào không phù hợp với dbo.play_tablephân vùng thứ 2. Bạn có thể làm điều này với một ràng buộc kiểm tra:

/******************************************************************************
    your code omitted for brevity
******************************************************************************/

-- move contents of play_table to temp_table, which is not partitioned
-- but is in the same filegroup
ALTER TABLE dbo.play_table
    SWITCH PARTITION 2 TO temp_table;
PRINT 'Switched from partitioned table to non-partitioned table';

/******************************************************************************
    added check constraint so that data can fit in the destination partition
******************************************************************************/
alter table dbo.temp_table
add constraint CK_TempTable_C1 check (c1 >= 4);
go
/******************************************************************************
    end of added code
******************************************************************************/

-- move data back to partitioned play_table from unpartitioned temp_table
-- this will no longer FAIL
ALTER TABLE dbo.temp_table
    SWITCH TO play_table partition 2;
PRINT 'Switched from non-partitioned table to partitioned table';

/******************************************************************************
    your code omitted for brevity
******************************************************************************/

Việc bổ sung mẫu ở trên vào mã của bạn làm cho điều này trở thành một giải pháp hiệu quả. Bây giờ SQL Server biết rằng dữ liệu trong dbo.temp_tablecó thể vừa với phân vùng 2 dbo.play_tabledo các ràng buộc kiểm tra được thêm vào dbo.temp_table.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.