2015-05-05 6 views
1

У кого-нибудь есть решение для следующего, пожалуйста? (фрагменты кода в обоих случаях должны выполняться как полные блоки)SQL Server: автоинкремент для столбца, разделенный значениями в другом столбце

Следующий код имитирует ситуацию для ежедневного задания обработки.

Вот день 1

Declare @poitem_source table (PONum int, txt varchar(50), status varchar(25)) 
Declare @poitem_destination table (PONum int, LineNum int, txt varchar(50)) 

insert @poitem_source 
values (1,'Item1', 'NEW'), (1,'Item2', 'NEW'), 
     (1,'Item3', 'NEW'), (2,'Item1', 'NEW'), 
     (2,'Item2', 'NEW') 

update @poitem_source 
set status = 'PROCESSING' 
where status = 'NEW' 

insert @poitem_destination 
    SELECT 
     PONum, 
     ROW_NUMBER() OVER (PARTITION BY PONum ORDER BY PONum) AS POLineNumber, 
     txt 
    FROM 
     @poitem_source 
    WHERE 
     status = 'PROCESSING' 

update @poitem_source 
set status = 'DONE' 
where status = 'PROCESSING' 

select * 
from @poitem_destination 
order by PONum, txt 

Если вы запустите ее, вы увидите, что приращения LINENUM 1 ... п для каждого PONum в таблице назначения.

Однако это явно не будет работать на 2-й день ... вот код ...

Declare @poitem_source table (PONum int, txt varchar(50), status varchar(25)) 
Declare @poitem_destination table (PONum int, LineNum int, txt varchar(50)) 

insert @poitem_source 
values (1,'Item1', 'NEW'), (1,'Item2', 'NEW'), (1,'Item3', 'NEW'), 
     (2,'Item1', 'NEW'), (2,'Item2', 'NEW') 

update @poitem_source 
set status = 'PROCESSING' 
where status = 'NEW' 

insert @poitem_destination 
    select 
     PONum, 
     ROW_NUMBER() OVER (PARTITION BY PONum ORDER BY PONum) AS POLineNumber, 
     txt 
    from 
     @poitem_source 
    where 
     status = 'PROCESSING' 

update @poitem_source 
set status = 'DONE' 
where status = 'PROCESSING' 

select * 
from @poitem_destination 
order by PONum, txt 

--- 2nd day 

insert @poitem_source 
values (1,'Item4', 'NEW'), (2,'Item3', 'NEW') 

update @poitem_source 
set status = 'PROCESSING' 
where status = 'NEW' 

insert @poitem_destination 
    select 
     PONum, 
     ROW_NUMBER() OVER (PARTITION BY PONum ORDER BY PONum) AS POLineNumber, 
     txt 
    from @poitem_source 
    where status = 'PROCESSING' 

update @poitem_source 
set status = 'DONE' 
where status = 'PROCESSING' 

select * 
from @poitem_destination 
order by PONum, txt 

Для 2-й день, дополнительные элементы получить номера строк в 1, так как запрос на выборку не связан в любом случае в таблицу назначения (и я не думаю, что это может быть).

У кого-нибудь есть альтернативное решение для генерации этих номеров строк?

Благодаря

ответ

0

Решение следующим

Declare @poitem_source table (PONum int, txt varchar(50), status varchar(25)) 
Declare @poitem_destination table (PONum int, LineNum int, txt varchar(50)) 


insert @poitem_source values (1,'Item1', 'NEW'), (1,'Item2', 'NEW'), (1,'Item3', 'NEW'), (2,'Item1', 'NEW'), (2,'Item2', 'NEW') 

update @poitem_source set status = 'PROCESSING' where status = 'NEW' 

insert @poitem_destination 
SELECT PONum, ROW_NUMBER() OVER(PARTITION BY PONum ORDER BY PONum) + (select isnull(max(linenum),0) from @poitem_destination d where d.PONum = s.PONum) AS POLineNumber, txt from @poitem_source s where status = 'PROCESSING' 

select * from @poitem_destination order by PONum, txt 

update @poitem_source set status = 'DONE' where status = 'PROCESSING' 

--- 2nd day 

insert @poitem_source values (1,'Item4', 'NEW'), (2,'Item3', 'NEW') 

update @poitem_source set status = 'PROCESSING' where status = 'NEW' 

insert @poitem_destination 
SELECT PONum, ROW_NUMBER() OVER(PARTITION BY PONum ORDER BY PONum) + (select isnull(max(linenum),0) from @poitem_destination d where d.PONum = s.PONum) AS POLineNumber, txt from @poitem_source s where status = 'PROCESSING' 

update @poitem_source set status = 'DONE' where status = 'PROCESSING' 

select * from @poitem_destination order by PONum, txt 

Так что теперь мы можем использовать PONum & LINENUM в качестве первичного ключа

0

Добавить столбец IDENTITY в таблицу (и это было бы хорошим кандидат для первичного ключа для таблицы). Это даст ему уникальный номер увеличенной строки в таблице. Затем вы можете сохранить свои ежедневные номера строк.

Как это:

Declare @poitem_source table (ID int IDENTITY(1,1) NOT NULL PRIMARY KEY, PONum int, txt varchar(50), status varchar(25)) 

В качестве альтернативы, вы можете просто ваша линия номер столбца быть IDENTITY(1,1); однако это потеряет данные и, вероятно, вызовет проблемы в будущем («Мне нужно, чтобы LineNumber X со дня Y ...» было бы сложнее получить).

+0

IDENTITY * не * первичный ключ. Это просто атрибут столбца. Вы можете даже иметь несколько столбцов идентификации в одной таблице –

+0

Да, я рекомендую, чтобы он выполнял оба IDENTITY и делал это первичным ключом. Отредактировано для уточнения. –

+0

Идентификация не работает - мне нужно значение для увеличения для PONum - однако у меня есть решение - коррелированный подзапрос - добавлено к вопросу - спасибо за предложения, хотя – Cryptic

Смежные вопросы