Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2008 Forums
 Transact-SQL (2008)
 partiion switch fails

Author  Topic 

Bex
Aged Yak Warrior

580 Posts

Posted - 2010-07-14 : 09:01:33
I have the following code, which results in the following error. I don't understand what I am doing wrong, as the load table has a constraint defined to limit the values that fall within the source's boundary value. Any suggestions?:

Error:
Msg 4972, Level 16, State 1, Line 10
ALTER TABLE SWITCH statement failed. Check constraints or partition function of source table 'Test.load.Header' allows values that are not allowed by check constraints or partition function on target table 'Test.dbo.Header'.


Code:
use [master]
go
if exists(select 1 from sys.databases where [name] = 'Test')
begin drop database [Test] end
go
create database [Test]
go
use [Test]
go
create schema load
go
-- Create partition scheme
CREATE PARTITION FUNCTION Pf_dbo_EndTransDateTime (DATETIME)
AS RANGE RIGHT
FOR VALUES ('20100706','20100707','20100708', '20100709','20100710','20100711', '20100712', '20100713', '20100714','20100715')

CREATE PARTITION SCHEME Ps_dbo_EndTransDateTime AS PARTITION Pf_dbo_EndTransDateTime ALL TO ([PRIMARY])

--select * from sys.partition_range_values
go
-- Create table on partition scheme
create table Header (TransactionID BIGINT not null, EndTransDateTime DATETIME not null, StoreNo INT, POSNo INT, TicketNo INT, CashierNo INT, InsertedDateTime DATETIME,
constraint pk_Header_TransactionID primary key (TransactionID, EndTransDateTime))on Ps_dbo_EndTransDateTime (EndTransDateTime)

alter table Header
add constraint uq_Header_NaturalKey unique (StoreNo, POSNo, TicketNo, EndTransDateTime) with (IGNORE_DUP_KEY = Off)

create index ix_Header_CashierNo on Header (CashierNo)
go
-- Create load table with unique index (to prevent dupes)-if violated, TranID will be set to 0 and child tables not inserted into
create table load.Header (TransactionID BIGINT not null, EndTransDateTime DATETIME not null, StoreNo INT, POSNo INT, TicketNo INT, CashierNo INT, InsertedDateTime DATETIME)on [PRIMARY]

alter table load.Header
add constraint uq_Header_NaturalKey unique (StoreNo, POSNo, TicketNo, EndTransDateTime) with (IGNORE_DUP_KEY = Off)
go

insert into load.Header
select 1, GETDATE(), 1,1,1,1,GETDATE()
go

-- Once load is complete, add additional indexes
alter table load.Header
add constraint pk_Header_TransactionID primary key (TransactionID, EndTransDateTime)

create index ix_Header_CashierNo on load.Header (CashierNo)

-- add check constraint to prevent dates other than today being inserted, and to ensure that the switch can be done
-- cannot perform the switch without the check constraint
declare @today datetime, @tomorrow datetime, @sql nvarchar(max)

select @today = CONVERT(char(8), current_timestamp,112), @tomorrow = dateadd(day,1,@today)

--set @sql = 'alter table load.Header add constraint ck_Header_EndTransDateTime check (EndTransDateTime >= '''+convert(char(8),@today,112)+''' and EndTransDateTime < '''+convert(char(8),@tomorrow,112)+''')'
--select @sql
--exec sp_executesql @sql

alter table load.Header add constraint ck_Header_EndTransDateTime check (EndTransDateTime >= '20100714' and EndTransDateTime < '20100715')
go

-- perform switch of load table with partition in dbo
declare @date datetime, @boundaryid int

set @date = CONVERT(char(8), current_timestamp,112)

select @boundaryid = boundary_id from sys.partition_range_values
where value = @date

select @boundaryid

ALTER TABLE load.Header SWITCH TO dbo.Header PARTITION @boundaryid
go





Hearty head pats

Bex
Aged Yak Warrior

580 Posts

Posted - 2010-07-14 : 09:58:33
I can get it to work by creating a partition function on the load schema, but that adds a whole new level of complexity. See code below. However, according to BOL, I should only have to add a chck constraint to limit the boundary values, which I have in the first post.

'Nonpartitioned tables must have the same constraints as target partition. If you are adding a nonpartitioned table as a partition to an already existing partitioned table, there must be a constraint defined on the column of the source table that corresponds to the partition key of the target table. This makes sure that the range of values fits within the boundary values of the target partition.'
use [master]
go
if exists(select 1 from sys.databases where [name] = 'Test')
begin drop database [Test] end
go
create database [Test]
go
use [Test]
go
create schema load
go
-- Create partition scheme
CREATE PARTITION FUNCTION Pf_dbo_EndTransDateTime (DATETIME)
AS RANGE RIGHT
FOR VALUES ('20100706','20100707','20100708', '20100709','20100710','20100711', '20100712', '20100713', '20100714','20100715')

CREATE PARTITION SCHEME Ps_dbo_EndTransDateTime AS PARTITION Pf_dbo_EndTransDateTime ALL TO ([PRIMARY])

select * from sys.partition_range_values
go
-- Create partition scheme for the load table
CREATE PARTITION FUNCTION Pf_load_EndTransDateTime (DATETIME)
AS RANGE RIGHT
FOR VALUES ('20100713', '20100714','20100715')

CREATE PARTITION SCHEME Ps_load_EndTransDateTime AS PARTITION Pf_load_EndTransDateTime ALL TO ([PRIMARY])

select * from sys.partition_range_values
go
-- Create table on partition scheme
create table Header (TransactionID BIGINT not null, EndTransDateTime DATETIME not null, StoreNo INT, POSNo INT, TicketNo INT, CashierNo INT, InsertedDateTime DATETIME,
constraint pk_Header_TransactionID primary key (TransactionID, EndTransDateTime))on Ps_dbo_EndTransDateTime (EndTransDateTime)

alter table Header
add constraint uq_Header_NaturalKey unique (StoreNo, POSNo, TicketNo, EndTransDateTime) with (IGNORE_DUP_KEY = Off)

create index ix_Header_CashierNo on Header (CashierNo)
go
-- Create load table with unique index (to prevent dupes)-if violated, TranID will be set to 0 and child tables not inserted into
create table load.Header (TransactionID BIGINT not null, EndTransDateTime DATETIME not null, StoreNo INT, POSNo INT, TicketNo INT, CashierNo INT, InsertedDateTime DATETIME)on Ps_load_EndTransDateTime (EndTransDateTime)

alter table load.Header
add constraint uq_Header_NaturalKey unique (StoreNo, POSNo, TicketNo, EndTransDateTime) with (IGNORE_DUP_KEY = Off)

-- add check constraint to prevent dates other than today being inserted, and to ensure that the switch can be done
-- cannot perform the switch without the check constraint
declare @today datetime, @tomorrow datetime, @sql nvarchar(max)

select @today = CONVERT(char(8), current_timestamp,112), @tomorrow = dateadd(day,1,@today)

--set @sql = 'alter table load.Header add constraint ck_Header_EndTransDateTime check (EndTransDateTime >= '''+convert(char(8),@today,112)+''' and EndTransDateTime < '''+convert(char(8),@tomorrow,112)+''')'
--select @sql
--exec sp_executesql @sql

alter table load.Header add constraint ck_Header_EndTransDateTime check (EndTransDateTime >= '20100714' and EndTransDateTime < '20100715')

go

insert into load.Header
select 1, GETDATE(), 1,1,1,1,GETDATE()
go

-- Once load is complete, add additional indexes to make sure structure is identical to the target table
alter table load.Header
add constraint pk_Header_TransactionID primary key (TransactionID, EndTransDateTime)

create index ix_Header_CashierNo on load.Header (CashierNo)

go

-- perform switch of load (source) table with target (partitioned table in dbo schema)
declare @date datetime, @boundaryid_dbo int, @boundaryid_load int

set @date = CONVERT(char(8), current_timestamp,112)

select @boundaryid_dbo = boundary_id from sys.partition_range_values
where value = @date
and function_id = (select function_id from sys.partition_functions where name = 'Pf_dbo_EndTransDateTime')

select @boundaryid_load = boundary_id from sys.partition_range_values
where value = @date
and function_id = (select function_id from sys.partition_functions where name = 'Pf_load_EndTransDateTime')


select @boundaryid_dbo

select value from sys.partition_range_values
where boundary_id = @boundaryid_dbo

ALTER TABLE load.Header SWITCH PARTITION @boundaryid_load TO dbo.Header PARTITION @boundaryid_dbo
go


Hearty head pats
Go to Top of Page

Bex
Aged Yak Warrior

580 Posts

Posted - 2010-07-14 : 11:33:24
Anyone? I'm so stuck......

Hearty head pats
Go to Top of Page

Bex
Aged Yak Warrior

580 Posts

Posted - 2010-07-15 : 04:49:07
still stuck.......

Hearty head pats
Go to Top of Page
   

- Advertisement -