2011-08-08 14 views
11

Tengo una consulta donde necesito "por lotes" insertar filas en una tabla con una clave principal sin identidad.T-SQL, Insertar en con MAX() + 1 en subconsulta no incrementa, ¿alternativas?

--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 

(ejemplo simplificado - por favor no comentar acerca de los posibles problemas de concurrencia :-))

El problema es que no se incrementa el PK "para cada" fila procesada, y yo obtener una violación de clave principal.

Sé cómo hacerlo con un cursor/while, pero me gustaría evitar eso, y resolverlo de una manera establecida, ¿si eso es posible?

(ejecuta SQL Server 2008 Standard)

+4

¿Por qué no haces de la columna una columna de identidad? – Chandu

+0

+1 @Cybernate: esta es una idea terrible y si te has tomado la molestia de buscar en SO, hay unas 20 preguntas similares a esta, cada una te dice por qué es una mala idea. – JNK

+0

Resumen largo: crearía una identidad si pudiera :-). @JNK me molesté, pero es mi única opción, y quiero resolverlo de la mejor manera posible. También ten en cuenta que proporcioné un ejemplo simplificado. – KorsG

Respuesta

23
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 
+0

Hace el trabajo, gracias por la respuesta rápida :-) – KorsG

+2

Tenga cuidado con las condiciones de carrera. – HLGEM

4

El problema, como han visto es que todos reciben el mismo número de fila, al máximo (PK) 1 es el mismo para cada fila.

Trate convertirlo a ser Max(PK) + Row_number()

estoy trabajando sobre la base de por qué usted sabe que esto es una mala idea, etc., y su pregunta se ha simplificado con el fin de obtener una respuesta, y no cómo se desearía resolver el problema

+0

Esto ayudará. http://stackoverflow.com/questions/13845791/insert-multiple-rows-with-incremental-primary-key-sql –

3

Puedes;

;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 
7

+1 a Michael Buen, pero tengo una sugerencia:

La tabla "Tabla A" puede estar vacío, por lo que debemos escribir:

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

Esto evitará un error nulo cuando intentas usar este código

1

Tengo una sugerencia para usted amigo, una mejor práctica en SQL dice utilizar SECUENCIA, y adivina qué, Es muy fácil de hacer que el hombre, sólo debes copiar y pegar el mío:

CREAR SECUENCIA SEQ_TABLEA AS INTEGER comenzar con 1 incrementan en 1 MAXVALUE 2147483647 MINVALUE 1 NO CYCLE

y utilizar de esta manera:

INSERT INTO TableA (PK, CustNo) VALORES (SEQ_TABLEA.NEXTVAL, 123)

Esperanza este consejo capaz de ayudar ya!

+2

Gracias por responder, pero la pregunta original era sobre SQL Server 2008, y SEQUENCE solo está disponible para SQL Server 2012+ – KorsG

Cuestiones relacionadas