Inserción masiva desde la table a la table

Estoy implementando un escenario A / B / View que significa que la Vista apunta a la tabla A, mientras que la tabla B se actualiza, luego se produce un cambio y la vista apunta a la tabla B mientras se carga la tabla A, y así sucesivamente. El cambio ocurre a diario. Hay millones de filas y miles de usuarios. Estoy en SQL Server 2012.

Mi pregunta es cómo insert datos en una tabla desde otra tabla de la manera más rápida posible (dentro de un process almacenado). ¿Hay alguna forma de usar BULK INSERT? O bien, ¿está utilizando inserción regular / select la manera más rápida de hacerlo?

Podría seleccionar una ColA, ColB en DestTable_New From SrcTable. Una vez que se carga DestTable_New, vuelve a crear índices y restricciones.

A continuación, cambie el nombre de DestTable a DestTable_Old y cambie el nombre de DestTable_New a DestTable. Renombrar es extremadamente rápido. Si algo sale mal, también tiene una copy de security de la tabla anterior cerca (DestTable_Old).

Hice este escenario una vez donde teníamos que tener el sistema en funcionamiento las 24 horas, los 7 días de la semana, y necesitaba cargar decenas de millones de filas cada día.

Puede hacer los nombres de campo seleccionados en TableName de la tabla de Destino, como lo sugieren las respuestas de un par, debe ser lo más rápido posible (dependiendo de cuántos índices necesite recrear, etc.).

Pero sugeriría usar sinónimos para cambiar el puntero de una tabla a otra. Son muy transparentes y, en mi opinión, más limpios que actualizar la vista o cambiar el nombre de las tablas. Compruébalo aquí .

INSERT... SELECT... funciona bastante similarmente a BULK INSERT . Podría usar SSIS, como dice @GarethD, pero eso podría ser demasiado complejo si solo está copyndo filas de la tabla1 a la tabla2.

Si está copyndo cantidades importantes de datos, observe el logging de transactions; puede hincharse bastante rápido cuando hace inserciones grandes. Una alternativa consiste en "codificar" los datos que está insertando, al pasar el cursor sobre una statement de inserción que procesa, digamos, solo 100.000 o 10.000 filas por vez (depende de qué tan amplias sean sus filas, es decir, cuántos MB por pase).

(Es curioso, ¿estás haciendo ALTER VIEW para restablecer la vista? Hice algo similar una vez, aunque tuvimos que tener cuatro tablas y cuatro vistas para admitir sets pasados ​​/ presentes / próximos / intercambiar).

Me inclinaría a usar SSIS.

Convierta la tabla A en una fuente OLEDB y la tabla B en un destino OLEDB. Va a omitir el logging de transactions para networkingucir la carga en la database. La única forma (puedo pensar) de hacer esto usando T-SQL es cambiar el model de recuperación para toda la database, lo cual está lejos de ser ideal porque significa que no se almacenan las transactions, no solo las de la transferencia.

Configurar la transferencia de SSIS

Cree un nuevo proyecto y arrastre una tarea de flujo de datos a su superficie de layout

Menú de caja de herramientas

Haga doble clic en su tarea de flujo de datos que lo llevará a la pestaña Flujo de datos. A continuación, arrastre y suelte un origen OLE DB desde el menu "Fuentes de flujo de datos" y un destino OLE DB desde el menu "Destinos de flujo de datos"

Fuentes de flujo de datosDestinos de flujo de datos

Haga doble clic en el origen de OLE DB, configure la connection a su server, elija la tabla desde la que desea cargar y click Aceptar. Arrastre la flecha verde desde el origen de OLE DB al destino y haga doble clic en el destino. Configure su gestor de connection, el nombre de la tabla de destino y las asignaciones de columna, y debería estar listo para continuar.

Documentos fuente de OLE DB en MSDN

Documentos de destino de OLE DB en MSDN

Simplemente puedes hacer esto

  select * into A from B Where [criteria] 

Esto seleccionará los datos de B, en function de los criterios y los insertá en A, siempre que las columnas sean las mismas o puede especificar los nombres de las columnas en lugar de *.

Sé que la pregunta es antigua, pero estaba buscando una respuesta a la misma pregunta y no encontré nada realmente útil. Sí, el enfoque de SSIS es una posibilidad, pero la pregunta quería un procedimiento almacenado.

Para mi deleite, descubrí (casi) la solución que quería la pregunta original; puedes hacerlo con un CLR SP.

Seleccione los datos de la Tabla A en una DataTable y luego utilice el método WriteToServer (DataTable dt) de la class SqlBulkCopy con TableB como DestinationTableName.

El único inconveniente leve es que el procedimiento CLR debe usar acceso externo para usar SqlBulkCopy y no funciona con la connection de context, por lo que debe manipular un poco los permissions y las cadenas de connection. ¡Pero hey! nada es perfecto.

 INSERT INTO B as SELECT FROM A WHERE...