T-SQL, вставка в MAX () + 1 в подзапросе не увеличивается, альтернативы? - PullRequest
12 голосов
/ 08 августа 2011

У меня есть запрос, где мне нужно «пакетно» вставить строки в таблицу с первичным ключом без идентификатора.

--TableA
--PK int (Primary key, no-identity)
--CustNo int
INSERT INTO TableA (PK,CustNo)
  SELECT (SELECT MAX(PK)+1 AS PK FROM TableA), CustNo
  FROM Customers

(упрощенный пример - не комментируйте возможные проблемы параллелизма: -))

Проблема в том, что он не увеличивает PK для каждой обработанной строки, и я получаю нарушение первичного ключа.

Я знаю, как это сделать с помощью курсора / цикла, но я бы хотел этого избежать и решить его на основе множеств, если это возможно?

(работает под управлением SQL Server 2008 Standard)

Ответы [ 5 ]

24 голосов
/ 08 августа 2011
Declare @i int;

Select @i = max(pk) + 1 from tablea;

INSERT INTO TableA (PK, custno)
Select row_number() over(order by custno) + @i  , CustNo
FROM Customers
7 голосов
/ 08 августа 2011

+ 1 для Майкла Буэна, но у меня есть одно предложение:

Таблица "tablea" может быть пустой, поэтому мы должны написать:

Select @i = isnull(max(pk),0) + 1 from tablea;

Это предотвратит ошибку NULLпри попытке использовать этот код.

4 голосов
/ 08 августа 2011

Проблема, как вы видели, состоит в том, что все они получают одинаковый номер строки, максимальное (PK) +1 одинаково для каждой строки.

Попробуйте преобразовать его в Max(PK) + Row_number()

Я работаю на основании того, почему вы знаете, что это плохая идея и т. Д., И ваш вопрос упрощен с целью получить ответ, а не то, как вы хотели бы решить проблему.

3 голосов
/ 08 августа 2011

Вы можете;

;with T(NPK, CustNo) as (
  select row_number() over (order by CustNo), CustNo from Customers
)
insert into TableA (PK, CustNo)
  select NPK, custno from T
order by CustNo 
1 голос
/ 18 июня 2015

У меня есть предложение для вас, приятель, лучшая практика на SQL гласит: использовать SEQUENCE, и угадайте, что, ОЧЕНЬ легко сделать, просто скопируйте и вставьте мой:

СОЗДАЙТЕ ПОСЛЕДОВАТЕЛЬНОСТЬ SEQ_TABLEA КАК ЦЕЛОГО НАЧАЛА С 1 УВЕЛИЧЕНИЕМ НА 1 МАКС. ЗНАЧЕНИЕ 2147483647 МИНВАЛЬНОЕ 1 НЕТ ЦИКЛА

и используйте вот так:

ВСТАВЬТЕ В TableA (PK, CustNo) ЗНАЧЕНИЯ (SEQ_TABLEA.NEXTVAL, 123)

Надеюсь, этот совет поможет вам!

...