「対象テーブルのチェック制約またはパーティション機能で許可されていない値を許可する」でデータの切り替えが失敗する


12

次の場合

-- 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);

次に、データを移動します。

-- 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;

以下は、同じテーブル構造を検証するための「Script Table As ... CREATE」DDLです。

/****** 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

SWITCHOUT OUTは正常に機能します。INを切り替えると、次のエラーが生成されます。

メッセージ4972、レベル16、状態1、行1のALTER TABLE SWITCHステートメントが失敗しました。ソース表「greek.dbo.f_word_swapin」のチェック制約またはパーティション関数は、ターゲット表「greek.dbo.f_word」のチェック制約またはパーティション関数で許可されていない値を許可します。

ランニング:

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

すべてのデータがパーティション13に戻ることを確認します。

私は本当にパーティション分割が初めてなので、私は間違ったことをしていると確信しています。それが何であるかわかりません。


これは、少なくとも1つのテーブルでチェック制約がWITH NOCHECKで作成された場合にも発生する可能性があります。

回答:


19

についてのこと CHECK制約は、述語が返す行のみを許可しないことFALSEです。チェックがを返した場合、そうUNKNOWNではないFALSEため、行はチェックに合格します。

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!

チェック制約はNULL値を許可しません。これは、SWITCHステートメントが反対する範囲外の「値」です。スイッチインテーブルには、パーティション2に属さないヌルが含まれている場合があります。

宛先パーティションがパーティション1(nullが行く場所)ではない場合、制約に追加AND source_id IS NOT NULLしますCHECK

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.