2012-03-05 20 views
15

En nuestro archivo db hay una tabla que tiene un poco más de 80 columnas. Tiene una clave principal y la inserción de identidad está activada. Estoy buscando una forma de insertar en esta tabla cada columna EXCEPTO la columna de clave primaria de una tabla idéntica en una base de datos diferente.T-SQL Insertar en la tabla sin tener que especificar cada columna

¿Esto es posible?

+1

Necesita especificar las columnas ... – JNK

+0

Suena como un caso de programación perezosa. Si hace clic con el botón derecho en el nombre de la tabla, puede "escribir como -> insertar en", y todas las columnas que no sean de identidad se escribirán para usted. Shazam. –

+0

YoOu debería beneficiar al rendimiento de la base de datos a largo plazo, no a usted mismo. Aceptaste la peor respuesta del grupo porque duplica el trabajo cada vez que se ejecuta lo que la consulta correcta tomaría y todo para ahorrarte un poco de tiempo. – HLGEM

Respuesta

40

Usted puede hacer esto con bastante facilidad en realidad:

-- Select everything into temp table 
Select * Into 
    #tmpBigTable 
    From [YourBigTable] 

-- Drop the Primary Key Column from the temp table 
Alter Table #tmpBigTable Drop Column [PrimaryKeyColumn] 

-- Insert that into your other big table 
Insert Into [YourOtherBigTable] 
    Select * From #tmpBigTable 

-- Drop the temp table you created 
Drop Table #tmpBigTable 

Siempre que tenga identidad Insertar On en "YourOtherBigTable" y las columnas son absolutamente idénticos va a estar bien.

+3

SELECCIONAR * es un antipatrón. Esto crea mucho más trabajo para el servidor que escribir correctamente la inserción con columnas. Esta es una muy mala solución. Estás haciendo un lío de rendimiento para ahorrar diez segundos de arrastrar las columnas desde el objeto tbrowser. Esta es una práctica inaceptable para un profesional. – HLGEM

+1

Además, no olvidemos que en este caso está copiando toda la tabla en una tabla temporal. Si solo tiene unas cuantas filas, esto podría funcionar, pero realmente podría empantanar el sistema de una tabla con muchas filas. – Kibbee

+1

-1 por las razones ya dadas por @HLGEM. –

2

Puede consultar Information_Schema para obtener una lista de todas las columnas y generar programáticamente los nombres de columna para su consulta. Si haces esto todo en t-sql sería engorroso, pero podría hacerse. Si está utilizando otro lenguaje de cliente, como C# para hacer la operación, sería un poco menos engorroso.

2

No, eso no es posible. Podría estar tentado de usar

INSERT INTO MyLargeTable SELECT * FROM OtherTable 

Pero eso no funcionaría, porque su columna de identidad se incluiría en el *.

Usted podría utilizar

SET IDENTITY_INSERT MyLargeTable ON 
INSERT INTO MyLargeTable SELECT * FROM OtherTable 
SET IDENTITY_INSERT MyLargeTable OFF 

valores de identidad primera habilita la inserción, que permite copiar los registros, a continuación, se habilita de nuevo la columna de identidad.

Pero esto no funcionará tampoco. El servidor SQL no aceptará el * en este caso. Tiene que incluir explícitamente el Id en el script, como por ejemplo:

SET IDENTITY_INSERT MyLargeTable ON 
INSERT INTO MyLargeTable (Id, co1, col2, ...., col80) SELECT Id, co1, col2, ...., col80 FROM OtherTable 
SET IDENTITY_INSERT MyLargeTable OFF 

Así que estamos de vuelta desde el principio.

La manera más fácil es hacer clic derecho en la tabla en Management Studio, dejar que genere los scripts INSERT y SELECT, y editarlos un poco para que funcionen juntos.

0

De verdad, honestamente se necesitan diez segundos o menos para tirar todas las columnas desde el navegador de objetos y luego eliminar la columna de identidad de la lista. Es una mala idea usar select * para cualquier cosa que no sea una consulta ad hoc rápida.

+2

Pero, ¿y si el OP es una consulta ad hoc rápida?;) – onedaywhen

+0

¿Qué sucede si quiere hacer lo mismo para todas sus 1000 tablas? ¿Y si la lista de columnas en la tabla se agrega con frecuencia y no desea tener que actualizar la consulta cada vez? –

+0

Debe actualizar la consulta cada vez, ya que puede que no necesite las nuevas columnas. Es irresponsable hacer cualquier otra cosa. Es posible que termine mostrando los campos de usuarios que no solo no les importa, sino que no deberían ver. O puede terminar con insertos que colocan datos en las columnas incorrectas porque alguien cambió el orden de las columnas en una tabla pero no en la otra o las inserciones que se rompen porque no se agregó una nueva columna a la tabla que está tomando los datos de una selección. Es posible que también deba ajustar actualizaciones para nuevas columnas. Es posible que necesite averiguar cuáles serán los datos iniciales para las inserciones. – HLGEM

-1

Respondiendo a una pregunta relacionada (SELECT * EXCEPT), señalo que el lenguaje realmente relacional Tutorial D permite que la proyección se exprese en términos de los atributos que se eliminarán en lugar de los que deben conservarse, p.

my_relvar { ALL BUT description } 

Sin embargo su sintaxis INSERT requiere constructores de datos tupla para incluir atribuyen pares nombre/valor, por ejemplo,

INSERT P 
    RELATION 
    { 
     TUPLE { PNO PNO ('P1') , PNAME CHARACTER ('Nut') }, 
     TUPLE { PNO PNO ('P2') , PNAME CHARACTER ('Bolt') } 
    }; 

Por supuesto, con esta sintaxis no existe una ordenación columna (porque es verdaderamente relacional!), Por ejemplo, esto es semánticamente equivalente:

INSERT P 
    RELATION 
    { 
     TUPLE { PNO PNO ('P1') , PNAME CHARACTER ('Nut') }, 
     TUPLE { PNAME CHARACTER ('Bolt') , PNO PNO ('P2') } 
    }; 

La alternativa sería confiar completamente en el orden de los atributos, lo que SQL hace parcialmente, p.este es un SQL equivalente cercano a la anterior:

INSERT INTO P (PNO , PNAME) 
    VALUES   
     (PNO ('P1') , CAST ('Nut' AS VARCHAR (20))) , 
     (PNO ('P2') , CAST ('Bolt' AS VARCHAR (20))); 

Una vez que el commalist de columnas se ha especificado las VALUES constructores de registros tienen el mantener este orden, que no es lo ideal. Pero al menos se especifica el orden: su propuesta se basaría en alguna orden predeterminada que posiblemente no sea determinista.

3
CREATE TABLE Tests 
(
    TestID int IDENTITY PRIMARY KEY, 
    A int, 
    B int, 
    C int 
) 

INSERT INTO dbo.Tests 
VALUES (1,2,3) 

SELECT * FROM Tests 

Esto funciona en SQL2012

1

¿Por qué no crear una vista de los datos originales, la eliminación de los campos no deseados? Luego 'Seleccione * en' su deseo de corazón.

  • Control localizado dentro de una única vista
  • No hay necesidad de modificar sproc
  • Agregar/cambiar/eliminar campos fácil
  • No hay necesidad de consultar los metadatos
  • No hay tablas temporales
+0

¿Por qué la creación de tablas temporales aparece como una desventaja frente a la utilización de una vista? No estoy cuestionando el reclamo, solo me estoy preguntando sobre el motivo. –

+0

La tabla TEMP (puede) usa una gran cantidad de memoria/disco, donde VIEW está básicamente filtrando la tabla de producción a los campos que desee. Este método funcionará más rápido, no tendrá una sobrecarga de larga duración y se puede cambiar como se desee. – davidWazy

Cuestiones relacionadas