2009-10-23 15 views
40

Me preguntaba si es posible mover todas las filas de datos de una tabla a otra, que coincidan con una determinada consulta?Mover datos SQL de una tabla a otra

Por ejemplo, necesito mover todas las filas de la tabla de la Tabla1 a la Tabla2 donde su nombre de usuario = 'X' y contraseña = 'X', para que ya no aparezcan en la Tabla1.

Estoy usando SQL Server 2008 Management Studio.

Gracias.

+0

Hola chicos, muchas gracias por las respuestas rápidas. Muy apreciado. – doubleplusgood

Respuesta

70

debería ser posible utilizando dos declaraciones dentro de una transacción, una inserción y una eliminación:

INSERT INTO Table2 (<columns>) 
SELECT <columns> 
FROM Table1 
WHERE <condition>; 

DELETE FROM Table1 
WHERE <condition>; 

COMMIT; 

Esta es la forma más simple. Si tiene que preocuparse de que se inserten nuevos registros coincidentes en la tabla 1 entre las dos instrucciones, puede agregar un and exists <in table2>.

+1

desea asegurarse de que ambas declaraciones se realicen como una sola transacción. Para decir, desactivar la confirmación automática y realizar una única confirmación después de la eliminación, solo si no se han producido errores. Probablemente no desee eliminar si la inserción falla, o viceversa. – Jay

+0

lo suficientemente cierto, pero incluso si se realizan como una sola transacción, puede haber problemas si se producen inserciones durante la ejecución de las dos instrucciones. No se ejecutan demasiadas bases de datos de forma que las "lecturas sean repetibles" dentro de una transacción. – Thorsten

+0

Creo que puede usar "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE" para la transacción para asegurarse de que no vea los nuevos registros –

2

probar este

INSERT INTO TABLE2 (Cols...) SELECT Cols... FROM TABLE1 WHERE Criteria 

Entonces

DELETE FROM TABLE1 WHERE Criteria 
3

Usted debe ser capaz de con una subconsulta en la instrucción INSERT.

INSERT INTO table1(column1, column2) SELECT column1, column2 FROM table2 WHERE ...; 

seguido de la eliminación de la tabla1.

Recuerde ejecutarlo como una transacción única para que, si algo sale mal, pueda retrotraer toda la operación.

1

Usted podría intentar esto:

SELECT * INTO tbl_NewTableName 
FROM tbl_OldTableName 
WHERE [email protected] 

continuación, ejecutar una eliminación simple:

DELETE FROM tbl_OldTableName 
WHERE [email protected] 
8

sí lo es. Primero INSERT + SELECT y luego DELETE orginals.

INSERT INTO Table2 (UserName,Password) 
SELECT UserName,Password FROM Table1 WHERE UserName='X' AND Password='X' 

continuación, elimine orginals

DELETE FROM Table1 WHERE UserName='X' AND Password='X' 

es posible que desee conservar UserID o someother clave primaria, entonces se puede utilizar IDENTITY INSERT para preservar la tecla.

see more on SET IDENTITY_INSERT on MSDN

15

Todas estas respuestas ejecutar la misma consulta para la inserción y eliminación. Como se mencionó anteriormente, esto pone en riesgo el DELETE recogiendo registros insertados entre las declaraciones y podría ser lento si la consulta es compleja (aunque los motores inteligentes "deberían" hacer que la segunda llamada sea rápida).

La manera correcta (suponiendo que INSERT esté en una tabla nueva) es hacer ELIMINAR contra la tabla 1 usando el campo clave de la tabla2.

El borrado debe ser:

DELETE FROM tbl_OldTableName WHERE id in (SELECT id FROM tbl_NewTableName) 

excusa mi sintaxis, estoy saltando entre los motores, pero usted consigue la idea.

29

Esta es una publicación antigua, lo siento, pero ahora solo la encontré y quería dar mi solución a cualquiera que se tropezara con este día.

Como algunos han mencionado, la realización de una INSERT y luego un DELETE podría conducir a problemas de integridad, por lo que tal vez una manera de conseguir alrededor de él, y para llevar a cabo todo perfectamente en una sola instrucción, es tomar ventaja de la tabla temporal [deleted] .

DELETE FROM [source] 
OUTPUT [deleted].<column_list> 
INTO [destination] (<column_list>) 
+0

Nunca eliminaría ningún contenido antes de haberlo agregado donde lo necesito. Si algo sale mal, ¡puede ser difícil de entender! – d00dle

+2

Con una instrucción 'DELETE', todos los registros se escriben primero en la tabla temporal' [deleted] ', antes de que se resuelva la cláusula' DELETE', desde donde se pueden procesar, en este caso insertados en otra tabla, después de lo cual declaración resuelve. Si la sección de procesamiento de la declaración falla, la declaración completa se termina; no solo la cláusula 'INTO'. Además, 'BEGIN TRY ... BEGIN CATCH' y' ROLLBACK TRANSACTION' son excelentes declaraciones preventivas. – that0th3rGuy

+5

Esto tendrá problemas si el destino está involucrado en relaciones de claves foráneas. Obtendrá el error: La tabla de destino '' de la cláusula OUTPUT INTO no puede estar en ninguno de los lados de una relación (clave principal, clave externa). Restricción de referencia encontrada ''. –

0

Si las dos tablas utilizar el mismo ID o tiene una clave única común:

1) insertar el registro seleccionado en la tabla 2

INSERT INTO table2 SELECT * FROM table1 WHERE (conditions) 

2) eliminar el registro seleccionado de tabla1 si se presenta en tabla2

DELETE FROM table1 as A, table2 as B WHERE (A.conditions) AND (A.ID = B.ID) 
2

Aquí es cómo hacerlo con solo estado

WITH deleted_rows AS (
DELETE FROM source_table WHERE id = 1 
RETURNING * 
) 
INSERT INTO destination_table 
SELECT * FROM deleted_rows; 

Ejemplo:

postgres=# select * from test1 ; 
id | name 
----+-------- 
    1 | yogesh 
    2 | Raunak 
    3 | Varun 
(3 rows) 


postgres=# select * from test2; 
id | name 
----+------ 
(0 rows) 


postgres=# WITH deleted_rows AS (
postgres(# DELETE FROM test1 WHERE id = 1 
postgres(# RETURNING * 
postgres(#) 
postgres-# INSERT INTO test2 
postgres-# SELECT * FROM deleted_rows; 
INSERT 0 1 


postgres=# select * from test2; 
id | name 
----+-------- 
    1 | yogesh 
(1 row) 

postgres=# select * from test1; 
id | name 
----+-------- 
    2 | Raunak 
    3 | Varun 
0

Es posible utilizar "partición lógica" para cambiar datos entre tablas:

Con la actualización de la columna de partición, los datos se moverán automáticamente a la otra tabla:

aquí está la muestra:

CREATE TABLE TBL_Part1 
(id INT NOT NULL, 
val VARCHAR(10) NULL, 
PartitionColumn VARCHAR(10) CONSTRAINT CK_Part1 CHECK(PartitionColumn = 'TBL_Part1'), 
CONSTRAINT TBL_Part1_PK PRIMARY KEY(PartitionColumn, id) 
); 

CREATE TABLE TBL_Part2 
(id INT NOT NULL, 
val VARCHAR(10) NULL, 
PartitionColumn VARCHAR(10) CONSTRAINT CK_Part2 CHECK(PartitionColumn = 'TBL_Part2'), 
CONSTRAINT TBL_Part2_PK PRIMARY KEY(PartitionColumn, id) 
); 

GO 

CREATE VIEW TBL(id, val, PartitionColumn) 
WITH SCHEMABINDING 
AS 
    SELECT id, val, PartitionColumn FROM dbo.TBL_Part1 
    UNION ALL 
    SELECT id, val, PartitionColumn FROM dbo.TBL_Part2; 

GO 

--Insert sample to TBL (will be inserted to Part1) 
INSERT INTO TBL 
VALUES(1, 'rec1', 'TBL_Part1'); 

INSERT INTO TBL 
VALUES(2, 'rec2', 'TBL_Part1'); 

GO 

--Query sub table to verify 
SELECT * FROM TBL_Part1 

GO 
--move the data to table TBL_Part2 by Logical Partition switching technique 
UPDATE TBL 
    SET 
     PartitionColumn = 'TBL_Part2'; 

GO 

--Query sub table to verify 
SELECT * FROM TBL_Part2 
0

Utilice esta única declaración sql que es segura sin necesidad de confirmar/deshacer con múltiples instrucciones.

INSERT Table2 (
     username,password 
) SELECT username,password 
     FROM (
      DELETE Table1 
      OUTPUT 
        DELETED.username, 
        DELETED.password 
      WHERE username = 'X' and password = 'X' 
    ) AS RowsToMove ; 

Obras en el servidor SQL hacer los cambios apropiados para MySQL

Cuestiones relacionadas