Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Insert в staging table. Странное поведение.  [new]
S_A_V_e
Member

Откуда:
Сообщений: 181
Здравствуйте.
Ситуация такая:
Есть таблица разбитая на партишены.
create partition function bls_sdpf (int) as range right for values (20010100);

create partition scheme bls_sdps as partition bls_sdpf all to ([PRIMARY]);
go 

-- Create a partitioned table. 

create table series_data 
( 
  id bigint not null IDENTITY, 
  series_id bigint not null, 
  point_date int not null,
  point_value float

)
 on bls_sdps(point_date);
go 

ALTER TABLE [dbo].[series_data] ADD  CONSTRAINT [PK_series_data] PRIMARY KEY CLUSTERED ([id],point_date)  on bls_sdps(point_date)

-- Create a partition-aligned columnstore index on the table. 
create nonclustered columnstore index bls_sdncci on series_data(point_date);


Я делаю insert записей в эту таблицу следующим образом:
1. Создаю staging table (series_stg)
2. Делаю switch out раздела в эту табличку

alter table series_data switch partition $partition.bls_sdpf(20010200) to series_stg;

3. Заполняю series_stg данными
insert into series_stg(series_id,point_date,point_value)
select series_id,point_date,point_value
from source_data
where point_date = 20010100

4. Делаю switch in в основную таблицу
alter table series_stg switch to series_data partition $partition.bls_sdpf(20010200) ;


При первом заполнении раздела всё отрабатывает и данные попадают в основную таблицу (series_data). Затем операция повторяется. Я делаю switch out того же раздела (заполненного) и пытаюсь дописать в раздел данные (за следующий месяц например):
insert into series_stg(series_id,point_date,point_value)
select series_id,point_date,point_value
from source_data
where point_date = 20010200


В результате получаю ошибку:

Msg 2627, Level 14, State 1, Line 1
Violation of PRIMARY KEY constraint 'PK_series_stg'. Cannot insert duplicate key in object 'dbo.series_stg'. The duplicate key value is (1, 20020100).
The statement has been terminated.


Не пойму откуда может браться duplicate key если поле id в series_stg autoincrement ? Как с таким бороться ?

Заметил следующее:
Если вставлять записи курсором , то большинство записей добавляются и только на некоторых возникает ошибка. Причём обязательно с последовательными ключами. Например (39, 20030700) и (40, 20030800)

Заранее благодарю за ответы.
6 фев 13, 22:20    [13887608]     Ответить | Цитировать Сообщить модератору
 Re: Insert в staging table. Странное поведение.  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 33970
Блог
select @@version
6 фев 13, 22:27    [13887637]     Ответить | Цитировать Сообщить модератору
 Re: Insert в staging table. Странное поведение.  [new]
S_A_V_e
Member

Откуда:
Сообщений: 181
Microsoft SQL Server 2012 - 11.0.2100.60 (X64)
Feb 10 2012 19:39:15
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
6 фев 13, 22:48    [13887709]     Ответить | Цитировать Сообщить модератору
 Re: Insert в staging table. Странное поведение.  [new]
S_A_V_e
Member

Откуда:
Сообщений: 181
Вот что ещё происходит:
Выполняю приведенную последовательность действий. Получаю ошибку ( The duplicate key value is (1, 20020100) ).
В series_stg например 2 записи:
id    series_id    point_date   point_value
1     3744814    20020100    0,319
2     3744814    20020200    0,318




Затем выполняю запрос (добавляю произвольные данные):
insert into series_stg(series_id,point_date,point_value)
values(11111,20030500,1)

select * from series_stg
where series_id = 11111


Данные попадают в таблицу. Но поле id не увеличивается (autoincrement не происходит). Данные выглядят так:

id      series_id    point_date  point_value
1       3745607    20020100    0,319
2       3745607    20020200    0,318
2       11111       20030500    1



Если же добавлять так (с уже существующим point_date):
insert into series_stg(series_id,point_date,point_value)
values(11111,20020200,1)


То получаю:
Msg 2627, Level 14, State 1, Line 1
Violation of PRIMARY KEY constraint 'PK_series_stg'. Cannot insert duplicate key in object 'dbo.series_stg'. The duplicate key value is (2, 20020200).
The statement has been terminated.

Но при этом для следующей записи id увеличится.

Т.е. вопрос сводится к тому как заставить поле id расти при каждом insert и желательно не от 1 , а от последнего значения в таблице series_stg.
7 фев 13, 15:27    [13891666]     Ответить | Цитировать Сообщить модератору
 Re: Insert в staging table. Странное поведение.  [new]
Гость333
Member

Откуда:
Сообщений: 3683
S_A_V_e,

Сдаётся мне, вы не всю последовательность действий описали.
Какая структура series_stg? Как в неё вставляются данные, если на ней для выполнения switch должен быть columnstore index?
7 фев 13, 15:51    [13891922]     Ответить | Цитировать Сообщить модератору
 Re: Insert в staging table. Странное поведение.  [new]
S_A_V_e
Member

Откуда:
Сообщений: 181
Таблица series_stg создаётся скриптом который делает клон таблицы series_data (+ добавляется check на point_date ). Причём делает правильно, иначе swith out не делался бы . Затем на ней отключается columnstore index.
ALTER INDEX .... DISABLE


Делается запись данных и индекс включается снова.
ALTER INDEX .... REBUILD

И затем делается switch in.
7 фев 13, 17:19    [13892852]     Ответить | Цитировать Сообщить модератору
 Re: Insert в staging table. Странное поведение.  [new]
S_A_V_e
Member

Откуда:
Сообщений: 181
Нашел решение.
Поле id увеличивалось. Но росло не от последнего значения которое было в series_stg , а от 1.
Поэтому перед заполнением таблицы данными ставлю identity seed на последнее значение id в таблице (после switch out):
declare @maxid int
select @maxid=(isnull(max(id),0) + 1) from series_stg
DBCC CHECKIDENT('series_stg',RESEED, @maxid);
8 фев 13, 19:57    [13899936]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить