2008-09-18 31 views
45

Estoy insertando varios registros en una tabla A de otra tabla B. ¿Hay alguna forma de obtener el valor de identidad de la tabla A y actualizar la tabla b sin tener que hacer un cursor?¿Cómo insertar múltiples registros y obtener el valor de identidad?

Create Table A 
(id int identity, 
Fname nvarchar(50), 
Lname nvarchar(50)) 

Create Table B 
(Fname nvarchar(50), 
Lname nvarchar(50), 
NewId int) 

Insert into A(fname, lname) 
SELECT fname, lname 
FROM B 

estoy usando MS SQL Server 2005.

+0

Me doy cuenta de que esta es una vieja pregunta y especifica SQL Server 2005, pero dado que es el primer resultado para mostrar la declaración MERGE disponible en 2008 y posterior, debe mencionarse para aquellos que buscan una solución. Combinar en TargetTable USO ( SELECT .... ) como fuente de EN 1 = 2 Si la alineación no ENTONCES INSERT .... OUTPUT inserted.ID EN TempTable ( InsertedID ) – oldegreyg

+0

No necesita una fusión para un simple inserto. Merge es bueno para una inserción/actualización, pero exagerado para una simple inserción en. La respuesta de salida de Andy funcionó para mí y ayudó a quitar un bloqueo de índice. – CodeMonkeyForHire

+0

La respuesta de Andy Irving es la mejor. Los desencadenadores son torpes y no funcionan bien para operaciones arbitrarias en su tabla de destino, especialmente si su objetivo es temporal o simplemente intermedio. La respuesta de Darren es incorrecta, si está insertando un conjunto de filas, su orden en la tabla objetivo no es necesariamente el mismo que el orden de su conjunto. El camino de Dmitry es malo porque requiere un bucle para insertar una sola fila a la vez, que es de bajo rendimiento, siempre use conjuntos cuando pueda. El camino de Cory es malo y explicó por qué, "siempre y cuando no entren en conflicto". Esto va a convertirse en un sábado por la noche c – clemahieu

Respuesta

-6

MBelly es justo en el dinero - Pero entonces el gatillo siempre tratará de tabla de actualización B, incluso si eso no se requiere (Debido a que usted también está la inserción de la tabla C ?).

Darren también es correcto aquí, no puede obtener múltiples identidades como un conjunto de resultados. Sus opciones están usando un cursor y tomando la identidad de cada fila que inserta, o utilizando el enfoque de Darren de almacenar la identidad antes y después. Siempre que sepa el incremento de la identidad, esto debería funcionar, siempre y cuando se asegure de que la tabla esté bloqueada para los tres eventos.

Si fuera yo, y no era tan crítico, iría con un cursor.

0

Si siempre desea este comportamiento, se puede poner un desencadenador AFTER INSERT en la Tabla A que actualizará la tabla B.

0

Usted puede obtener el uniéndose al row number. Esto es posible porque, como se trata de una identidad, aumentará a medida que agregue elementos, que estarán en el orden en que los está seleccionando.

+2

Incorrecto, no se garantiza que los registros entren en la base de datos en el orden en el que crees que están ingresando. – HLGEM

0

Por lo que yo entiendo, el problema que está teniendo es que desea INSERTAR en la Tabla A, que tiene una columna de identidad, y desea conservar la identidad de la Tabla B que no lo hace.

Para hacerlo, solo debe activar la inserción de identidad en la tabla A. Esto le permitirá definir sus identificaciones en la inserción y, siempre que no entren en conflicto, debería estar bien. A continuación, sólo puede hacer:

Insert into A(identity, fname, lname) SELECT newid, fname, lname FROM B 
No

seguro de lo DB que está utilizando, pero para el servidor SQL del comando para encender la inserción de identidad sería:

set identity_insert A on 
+0

No intenta actualizar la tabla A, intenta actualizar la tabla B. La Tabla B no tiene una columna de identidad. – njr101

4

La lectura de su pregunta con cuidado, lo que desea es tabla de actualización B en base a los nuevos valores de identidad en la tabla A.

Después de la inserción está terminado, basta con ejecutar una actualización ...

UPDATE B 
SET NewID = A.ID 
FROM B INNER JOIN A 
    ON (B.FName = A.Fname AND B.LName = A.LName) 

Esto supone que la combinación FName/LName se puede usar para hacer coincidir las claves de los registros entre las tablas. Si no es el caso, es posible que deba agregar campos adicionales para garantizar que los registros coincidan correctamente.

Si no tiene una clave alternativa que le permita hacer coincidir los registros, entonces no tiene ningún sentido, ya que los registros en la tabla B no pueden distinguirse entre sí.

0

Sugiero usar el tipo uniqueidentifier en lugar de la identidad. Yo este caso se puede generar identificaciones antes de la inserción:

update B set NewID = NEWID() 

insert into A(fname,lname,id) select fname,lname,NewID from B 
127

Utilice la cláusula matriz resultado 2005:

DECLARE @output TABLE (id int) 

Insert into A (fname, lname) 
OUTPUT inserted.ID INTO @output 
SELECT fname, lname FROM B 

select * from @output 

ahora la variable de tabla tiene los valores de identidad de todas las filas se insertan.

+2

Pero, ¿cómo se actualiza la tabla B? Quiero decir, ¿cómo asocias cada registro de @output con un registro en B? Si usa fname, lname como clave, entonces es más sencillo usar la solución de njr. – munissor

+2

@munissor, sé que este es un hilo viejo, pero echa un vistazo a [este artículo sencillo] (http://www.simple-talk.com/sql/learn-sql-server/working-with-the-insert -statement-in-sql-server /) sobre el tema. Mire la sección "Agregar una cláusula OUTPUT". –

+1

@munissor un poco tarde pero puede hacer 'output inserted.id, inserted.whateverColumn en @ output' –

Cuestiones relacionadas