2013-07-03 3 views
2

Вот мой пример таблицы, первичный ключ является составным ключом Akey + BkeySQL Server 2012 Последовательность объектов

 
Akey Bkey ItemSequence  
---- ---- ------------ 
1  1  1 
1  5  2 
1  7  3 
2  7  1 
3  2  1 
3  3  2 

-ключа генерируется из SQL 2012 Sequence объекта нарушение проводимости. В большинстве случаев я вставляю одну строку за раз, и при необходимости я вызываю NEXT VALUE FOR ASequence. Однако мне нужно сделать вставку из заявления, как:

 
SELECT DENSE_RANK() OVER (ORDER BY Something) as AKey, 
    Bkey, Sequence 
FROM TABLEB 

Оговорка OVER следующего значения не работает так, как мне нужно, чтобы иметь возможность вставлять записи как SET, но только приращение последовательности один раз в Установлен DENSE_RANK. Итак, у нас есть команда ALTER SEQUENCE, и с этим я могу установить последовательность на то, что хочу. Остановитесь на том, что он должен быть константой и не будет принимать переменную. Моим обходным путем было следующее:

 
DECLARE @startingID INT 
DECLARE @sql VARCHAR(MAX) 
DECLARE @newSeed INT 

SET @startingID = NEXT VALUE FOR ASequence 

INSERT TABLEA 
SELECT DENSE_RANK() OVER (ORDER BY Something) + @startingID as AKey, 
    Bkey, Sequence 
FROM TABLEB 

SELECT @newSeed = MAX(Akey) FROM TABLEA 

SET @sql = ‘ALTER SEQUENCE ASEQUENCE RESTART WITH ‘ + cast(@newSeed+1 as varchar(10)) 
EXEC(@sql) 

Ужасно иметь инструкции DML в Dynamic SQL, подобные этому. Есть лучший способ сделать это?

+0

Решение, предоставленное Владом, - это путь. Однако, если вы ДОЛЖНЫ использовать динамический SQL в будущем, обязательно используйте [sp_executesql] (http://msdn.microsoft.com/en-us/library/ms188001.aspx) вместо EXEC. – kheld

ответ

0

Это следует сделать это:

INSERT TABLEA 
SELECT NEXT VALUE FOR ASequence OVER(ORDER BY Something) as AKey, 
    Bkey, Seq 
FROM TABLEB 
+0

Вы пробовали свой код? Это не сработает. Предложение OVER NEXT VALUE применяется только к сортировке. Он определяет порядок, в котором применяется последовательность, для каждой строки. Мне нужна последовательность, чтобы обеспечить 1 значение для каждого набора, как описано в моем вопросе. После долгих исследований я пришел к выводу, что это невозможно, кроме того, как я подробно описал. Я надеялся, что кто-то может доказать, что я ошибаюсь в своих выводах. На первый взгляд вы думаете, что NEXT VALUE будет работать таким образом, а также выглядит как логическая функция. – Jeff

+0

Смотрите, если sp_sequence_get_range звучит лучше для вас, чем динамический DDL. В любом случае этот код приведет к неправильным результатам при одновременном запуске нескольких соединений. –

+0

Не возражаете ли вы мне спросить, почему вас волнует, если AKey увеличивается на одну ранг или на запись? Можете ли вы просто рассматривать его как ПК в TableA и использовать прямую идентичность (или последовательность)? –

0

Или, как об этом:

CREATE TABLEA 
(
    GroupID INT, 
    AKey INT, 
    BKey INT, 
    ItemSequence INT, 
    CONSTRAINT PK_TABLEA PRIMARY KEY CLUSTERED 
    (
     GroupID, 
     AKey, 
     BKey 
    ) 
) 

DECLARE @GroupID INT 
SET @GroupID = NEXT VALUE FOR ASequence 

INSERT TABLEA 
SELECT @GroupID, DENSE_RANK() OVER (ORDER BY Something) as AKey, 
    Bkey, Sequence 
FROM TABLEB 

и если вам нужно значение AKEY, как в вашем примере, вы можете сделать GroupID + AKey Вот.