Przełączanie danych kończy się niepowodzeniem z „zezwala na wartości, które nie są dozwolone przez ograniczenia sprawdzania lub funkcję partycji w tabeli docelowej”

12

Biorąc pod uwagę następujące kwestie

-- table ddl
create table dbo.f_word(
    sentence_id int NULL,
    sentence_word_id int NULL,
    word_id int NULL,
    lemma_id int NULL,
    source_id int NULL,
    part_of_speech_id int NULL,
    person_id int NULL,
    gender_id int NULL,
    number_id int NULL,
    tense_id int NULL,
    voice_id int NULL,
    mood_id int NULL,
    case_id int NULL,
    degree_id int NULL,
    citation nvarchar(100) NULL
);
-- create partition function
create partition function pf_f_word_source_id (int)
as range left for values 
(
    1,2,3,4,5,6,7,8,9,10,11,12,13,14,
    15,16,17,18,19,20,21,22,23
);

-- create the partition scheme
create partition scheme ps_f_word as partition pf_f_word_source_id to 
(
    [primary],[primary],[primary],[primary],[primary],[primary],[primary],[primary],[primary],
    [primary],[primary],[primary],[primary],[primary],[primary],[primary],[primary],[primary],
    [primary],[primary],[primary],[primary],[primary],[primary]
);

-- partition the index
create unique clustered index cix_fword on dbo.f_word 
(
    source_id,
    sentence_id,
    sentence_word_id,
    word_id,
    lemma_id,
    part_of_speech_id,
    person_id,
    gender_id,
    number_id,
    tense_id,
    voice_id,
    mood_id,
    case_id,
    degree_id 
)
on ps_f_word (source_id);

-- swapin table ddl

create table dbo.f_word_swapin(
    sentence_id int NULL,
    sentence_word_id int NULL,
    word_id int NULL,
    lemma_id int NULL,
    source_id int NULL,
    part_of_speech_id int NULL,
    person_id int NULL,
    gender_id int NULL,
    number_id int NULL,
    tense_id int NULL,
    voice_id int NULL,
    mood_id int NULL,
    case_id int NULL,
    degree_id int NULL,
    citation nvarchar(100) NULL
) on [primary];

-- create the same index on the swapin table
create unique clustered index cix_fword_swapin on dbo.f_word_swapin 
(
    source_id,
    sentence_id,
    sentence_word_id,
    word_id,
    lemma_id,
    part_of_speech_id,
    person_id,
    gender_id,
    number_id,
    tense_id,
    voice_id,
    mood_id,
    case_id,
    degree_id 
);

-- add check constraints WITH CHECK
ALTER TABLE dbo.f_word_swapin
WITH CHECK
ADD CONSTRAINT ck_f_word_swapin_lb
CHECK ( source_id > 12);

ALTER TABLE dbo.f_word_swapin
WITH CHECK
ADD CONSTRAINT ck_f_word_swapin_ub
CHECK ( source_id <= 13);

Następnie przenieś dane:

-- switch data OUT of the partitioned table
ALTER TABLE dbo.f_word
SWITCH PARTITION 13 TO dbo.f_word_swapin;

-- attempt to switch data back IN 
ALTER TABLE dbo.f_word_swapin
SWITCH TO dbo.f_word PARTITION 13;

Poniżej znajduje się DDL „Tabela skryptów jako ... UTWÓRZ”, aby zweryfikować te same struktury tabel.

/****** Object:  Table [dbo].[f_word_swapin]    Script Date: 9/10/2014 10:01:01 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[f_word_swapin](
    [sentence_id] [int] NULL,
    [sentence_word_id] [int] NULL,
    [word_id] [int] NULL,
    [lemma_id] [int] NULL,
    [source_id] [int] NULL,
    [part_of_speech_id] [int] NULL,
    [person_id] [int] NULL,
    [gender_id] [int] NULL,
    [number_id] [int] NULL,
    [tense_id] [int] NULL,
    [voice_id] [int] NULL,
    [mood_id] [int] NULL,
    [case_id] [int] NULL,
    [degree_id] [int] NULL,
    [citation] [nvarchar](100) NULL
) ON [PRIMARY]

/****** Object:  Table [dbo].[f_word]    Script Date: 9/10/2014 10:09:43 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[f_word](
    [sentence_id] [int] NULL,
    [sentence_word_id] [int] NULL,
    [word_id] [int] NULL,
    [lemma_id] [int] NULL,
    [source_id] [int] NULL,
    [part_of_speech_id] [int] NULL,
    [person_id] [int] NULL,
    [gender_id] [int] NULL,
    [number_id] [int] NULL,
    [tense_id] [int] NULL,
    [voice_id] [int] NULL,
    [mood_id] [int] NULL,
    [case_id] [int] NULL,
    [degree_id] [int] NULL,
    [citation] [nvarchar](100) NULL
)

GO

WYŁĄCZENIE działa dobrze. PRZEŁĄCZANIE powoduje następujący błąd:

Msg 4972, poziom 16, stan 1, wiersz 1 ALTER TABLE SWITCH instrukcja nie powiodła się. Sprawdź ograniczenia lub funkcję partycji tabeli źródłowej „greek.dbo.f_word_swapin” dopuszcza wartości, które nie są dozwolone przez ograniczenia kontroli lub funkcję partycji w tabeli docelowej „greek.dbo.f_word”.

Bieganie:

select target_partition_id = $PARTITION.pf_f_word_source_id(source_id), 
    *
from dbo.f_word_swapin;

sprawdza, czy wszystkie dane powinny wrócić do partycji 13.

Naprawdę jestem całkiem nowy w partycjonowaniu, więc jestem pewien, że robię rzeczy niepoprawnie, po prostu nie wiem co to jest.

swasheck
źródło
Może się to również zdarzyć, jeśli przynajmniej w jednej z tabel twoje ograniczenie czekowe zostało utworzone Z NOCHECK.

Odpowiedzi:

19

Rzecz w CHECKograniczeniach polega na tym, że nie zezwalają tylko na wiersze, dla których predykat zwraca FALSE. Jeśli czek się zwraca UNKNOWN, to nie jest FALSEtak, więc wiersz przechodzi przez czek:

CREATE TABLE dbo.T1 (id int NULL CHECK (id = 1));

INSERT dbo.T1 VALUES (1); -- Ok
INSERT dbo.T1 VALUES (2); -- Error
INSERT dbo.T1 VALUES (NULL); -- Ok!

Twoje ograniczenie sprawdzania nie zabrania NULLwartości, które są poza zakresem „wartości”, której SWITCHsprzeciwia się instrukcja. Twoja tabela przełączania może zawierać wartości null, które nie należą do partycji 2.

Dodaj AND source_id IS NOT NULLdo swojego CHECKograniczenia, gdy partycja docelowa nie jest partycją 1 (gdzie idą wartości null).

Paul White 9
źródło