Ответ 1
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
У меня есть запрос, где мне нужно "пакет" вставлять строки в таблицу с первичным ключом без идентификатора.
--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
(упрощенный пример - пожалуйста, не комментируйте возможные проблемы concurrency: -))
Проблема заключается в том, что она не увеличивает PK "для каждой" обработанной строки, и я получаю нарушение первичного ключа.
Я знаю, как это сделать с помощью цикла курсора /while, но я хотел бы избежать этого и решить его в виде набора, если это возможно?
(выполняется стандартный SQL Server 2008)
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
+1 Майклу Буэну, но у меня есть одно предложение:
Таблица "tablea" может быть пустой, поэтому мы должны написать:
Select @i = isnull(max(pk),0) + 1 from tablea;
Это предотвратит ошибку null при попытке использовать этот код.
Проблема, которую вы видели, состоит в том, что все они получают одинаковый номер строки, max (PK) +1 одинаковый для каждой строки.
Попробуйте преобразовать его в Max(PK) + Row_number()
Я работаю на основе того, почему вы знаете, что это плохая идея и т.д., и ваш вопрос упрощается с целью получения ответа, а не как вы хотели бы решить проблему.
Вы можете:
;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
У меня есть предложение для вас приятель, лучше практика SQL говорит использовать SEQUENCE, и угадайте, что, очень легко сделать это человек, просто скопируйте и вставьте мой:
CREATE SEQUENCE SEQ_TABLEA AS INTEGER НАЧАТЬ С 1 INCREMENT BY 1 MAXVALUE 2147483647 MINVALUE 1 НЕТ ЦИКЛА
и используйте вот так:
INSERT INTO TableA (PK, CustNo) VALUES (SEQ_TABLEA.NEXTVAL, 123)
Надеюсь, что этот совет поможет вам!