2008-09-23 12 views
11

Tengo una tabla temporal con la estructura exacta de una tabla T. concreto Fue creado de esta manera: seleccione la parte superior 0 * en #tmp de TInsertar en ... Seleccione *, ¿cómo ignorar la identidad?

Después de procesar y rellenar el contenido en #tmp, quiero copiar el contenido de nuevo a T como este: insertar en T seleccionar * de #tmp

Esto está bien siempre que T no tenga una columna de identidad, pero en mi caso sí. ¿Hay alguna forma en que pueda ignorar la columna de autoincremento de #tmp cuando copie a T? Mi motivación es evitar tener que deletrear cada nombre de columna en la lista Insertar en.

EDIT: alternar identity_insert no funcionaría porque los pkeys en #tmp pueden colisionar con los de T si las filas se insertaron en T fuera de mi script, eso es si #tmp ha autoincrementado la pkey para sincronizar con T en El primer lugar.

+0

Puede explicar un poco más acerca de por qué desea una copia tabla temporal en primer lugar, por favor? Puede haber una mejor manera de lograr lo que estás buscando. –

+0

1. me da la oportunidad de obtener una vista previa de los datos antes de hacer la inserción 2. Tengo uniones entre tablas temporales como parte de mi cálculo; Las tablas temporales me permiten enfocarme en los datos exactos del set con los que estoy trabajando. Creo que eso fue todo. ¿Alguna sugerencia/comentario? – Haoest

+0

¿Su propósito es simplemente duplicar los datos que ya están allí? ¿O estás limpiando T antes de insertar? –

Respuesta

8

Como lo hará la identidad Se generará durante la inserción de todos modos, ¿podría simplemente eliminar esta columna de #tmp antes de insertar los datos de nuevo en T?

alter table #tmp drop column id 

UPD: He aquí un ejemplo que he probado en SQL Server 2008:

create table T(ID int identity(1,1) not null, Value nvarchar(50)) 
insert into T (Value) values (N'Hello T!') 
select top 0 * into #tmp from T 
alter table #tmp drop column ID 
insert into #tmp (Value) values (N'Hello #tmp') 
insert into T select * from #tmp 
drop table #tmp 
select * from T 
drop table T 
+0

De mis experimentos simples, parece que esto hace el trabajo :) gracias. ¿Alguien puede pensar en alguna forma en la que los contenidos de la celda puedan estar desalineados debido al hecho de que la tabla fuente #tmp tiene 1 columna menos que el destino T? – Haoest

+0

Hola, probé esto, pero al volver a insertar en la tabla original no funciona, dice "El nombre de la columna o el número de valores suministrados no coincide con la definición de la tabla". es decir, este comando "insertar en T seleccionar * desde #tmp" no funciona. – kristianp

+0

@kristianp He agregado un código de prueba de trabajo completo a la respuesta, pero es posible que estés tratando de resolver un problema levemente diferente, por ej.es posible que ya tenga activada la inserción de identidad. Si otras respuestas a esta pregunta y la búsqueda de SO no lo ayudan, podría tener sentido crear una nueva pregunta con más detalles sobre su situación. –

13

SET_IDENTITY_INSERT EN

comando INSERT

SET_IDENTITY_INSERT OFF

+0

Puede haber una colisión de clave primaria si lo hago porque para cuando #tmp está listo para copiar, las mismas claves pueden haberse insertado en T. – Haoest

+0

¿Funcionaría entonces como una transacción? – Kolten

+0

Ahh, eso funcionaría. No inicié la transacción hasta que # tmp estuviera listo para copiar (tengo que calcular muchos tmps) para minimizar el tiempo de bloqueo. Supongo que ahora es justificable. – Haoest

0
set identity_insert on 

Utilice esta.

1

No con SELECT * - si seleccionó cada columna pero la identidad, estará bien. La única forma en que puedo ver es que puedes hacer esto construyendo dinámicamente la instrucción INSERT.

1

Simplemente enumere las columnas que desea volver a insertar, nunca debe usar seleccionar * de todos modos. Si no desea escribirlos, simplemente arrástrelos desde el navegador de objetos (si expande la tabla y arrastra la palabra, columnas, obtendrá todos ellos, simplemente elimine la columna de id.)

+0

error de diseño o algo así, esta tabla tiene unas 80 columnas, 30 de las cuales están en desuso. Debido a la forma en que se crea #tmp, creo que está bien hacer una excepción al uso de select *. – Haoest

0

puede convenir un "actualización donde T.ID = # tmp.ID" trabajo?

+0

no, no hay contenido en #tmp – Haoest

-1
  1. me da la oportunidad de obtener una vista previa de los datos antes de hacer la inserción
  2. tengo uniones entre tablas temporales como parte de mi cálculo; Las tablas temporales me permiten enfocarme en los datos exactos del set con los que estoy trabajando. Creo que eso fue todo. ¿Alguna sugerencia/comentario?

Para la parte 1, como se ha mencionado por Kolten en uno de los comentarios, encapsulando sus estados de cuenta en una transacción y la adición de un parámetro para alternar entre la pantalla y cometen se adapte a sus necesidades. Para la Parte 2, necesitaría ver qué "cálculos" está intentando hacer. Limitar sus datos a una tabla temporal puede complicar la situación.

0

INSERT INTO #Table SELECT MAX (Id) + ROW_NUMBER() OVER (ORDER BY Id)

2

Ver las respuestas here y here:

select * into without_id from with_id 
union all 
select * from with_id where 1 = 0 

Motivo:

Cuando una columna de identidad existente se selecciona en una nueva tabla, la nueva columna hereda la propiedad IDENTIDAD, a menos que una de las siguientes condiciones sea verdadera:

  • La instrucción SELECT contiene una combinación, cláusula GROUP BY o función de agregado.
  • Se unen varias instrucciones SELECT utilizando UNION.
  • La columna de identidad aparece en la lista más de una vez en la lista de selección.
  • La columna de identidad es parte de una expresión.
  • La columna de identidad proviene de una fuente de datos remota.

Si alguna de estas condiciones es verdadera, la columna se crea NOT NULL en lugar de heredar la propiedad IDENTITY. Si se requiere una columna de identidad en la nueva tabla, pero dicha columna no está disponible, o si desea un valor inicial o de incremento diferente de la columna de identidad de origen, defina la columna en la lista de selección usando la función IDENTIDAD. Consulte "Crear una columna de identidad usando la función IDENTIDAD" en la sección de Ejemplos a continuación.

Todo el crédito va a Eric Humphrey y bernd_k

+0

Esto es brillante. Exactamente lo que solicitó el cartel original. – Juraj

Cuestiones relacionadas