Je me demandais s'il était possible de déplacer toutes les lignes de données d'une table à une autre, correspondant à une requête donnée?
Par exemple, je dois déplacer toutes les lignes de table de Table1 vers Table2, où leur nom d'utilisateur = 'X' et mot de passe = 'X', afin qu'elles n'apparaissent plus dans Table1.
J'utilise SQL Server 2008 Management Studio.
Doit être possible en utilisant deux instructions dans une transaction, une insertion et une suppression:
INSERT INTO Table2 (<columns>)
SELECT <columns>
FROM Table1
WHERE <condition>;
DELETE FROM Table1
WHERE <condition>;
COMMIT;
C'est la forme la plus simple. Si vous devez vous soucier des nouveaux enregistrements correspondants insérés dans la table1 entre les deux instructions, vous pouvez ajouter un and exists <in table2>
.
C’est un article ancien, désolé, mais je ne l’ai trouvé que maintenant et je voulais donner ma solution à quiconque pourrait tomber sur ce jour.
Comme certains l'ont mentionné, effectuer INSERT
puis DELETE
pourrait entraîner des problèmes d'intégrité. Un moyen de contourner le problème et d'exécuter parfaitement toutes les tâches dans une seule instruction consiste à tirer parti de la table temporaire [deleted]
.
DELETE FROM [source]
OUTPUT [deleted].<column_list>
INTO [destination] (<column_list>)
Toutes ces réponses exécutent la même requête pour INSERT et DELETE. Comme mentionné précédemment, cela risquerait que DELETE récupère les enregistrements insérés entre les instructions et pourrait être lent si la requête est complexe (bien que des moteurs intelligents "devraient" effectuer le second appel rapidement).
La bonne façon (en supposant que l'INSERT soit dans une table fraîche) consiste à effectuer la commande DELETE contre table1 en utilisant le champ clé de table2.
La suppression devrait être:
DELETE FROM tbl_OldTableName WHERE id in (SELECT id FROM tbl_NewTableName)
Excusez ma syntaxe, je saute de moteur à l’autre, mais vous voyez l’idée.
Oui, ça l'est. D'abord INSERT + SELECT et ensuite DELETE orginals.
INSERT INTO Table2 (UserName,Password)
SELECT UserName,Password FROM Table1 WHERE UserName='X' AND Password='X'
puis supprimez les orginales
DELETE FROM Table1 WHERE UserName='X' AND Password='X'
vous souhaiterez peut-être conserver UserID
ou une autre clé primaire, vous pourrez alors utiliser IDENTITY INSERT
pour conserver la clé.
Vous devriez pouvoir utiliser une sous-requête dans l'instruction INSERT.
INSERT INTO table1(column1, column2) SELECT column1, column2 FROM table2 WHERE ...;
suivie par la suppression de table1.
N'oubliez pas de l'exécuter en tant que transaction unique afin qu'en cas de problème, vous puissiez annuler toute l'opération.
Essaye ça
INSERT INTO TABLE2 (Cols...) SELECT Cols... FROM TABLE1 WHERE Criteria
Ensuite
DELETE FROM TABLE1 WHERE Criteria
Vous pouvez essayer ceci:
SELECT * INTO tbl_NewTableName
FROM tbl_OldTableName
WHERE Condition1=@Condition1Value
Puis exécutez une suppression simple:
DELETE FROM tbl_OldTableName
WHERE Condition1=@Condition1Value
Une représentation plus claire de ce à quoi certaines autres réponses ont fait allusion:
DELETE sourceTable
OUTPUT DELETED.*
INTO destTable (Comma, separated, list, of, columns)
WHERE <conditions (if any)>
Voici comment faire avec une seule déclaration
WITH deleted_rows AS (
DELETE FROM source_table WHERE id = 1
RETURNING *
)
INSERT INTO destination_table
SELECT * FROM deleted_rows;
EXEMPLE:
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
Utilisez cette instruction SQL unique qui ne présente aucun risque, sans avoir besoin de commettre/annuler des déclarations multiples.
INSERT Table2 (
username,password
) SELECT username,password
FROM (
DELETE Table1
OUTPUT
DELETED.username,
DELETED.password
WHERE username = 'X' and password = 'X'
) AS RowsToMove ;
Works sur le serveur SQL apporter les modifications appropriées pour MySql
Si les deux tables utilisent le même ID ou ont une clé UNIQUE commune:
1) Insérer l'enregistrement sélectionné dans le tableau 2
INSERT INTO table2 SELECT * FROM table1 WHERE (conditions)
2) supprimer l'enregistrement sélectionné de la table1 s'il est présent dans la table2
DELETE FROM table1 as A, table2 as B WHERE (A.conditions) AND (A.ID = B.ID)
Vous pouvez utiliser "Partitionnement logique" pour permuter les données entre les tables:
En mettant à jour la colonne de partition, les données seront automatiquement déplacées vers l'autre table:
voici l'échantillon:
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
Il va créer une table et copier toutes les données de l'ancienne table dans la nouvelle table
SELECT * INTO event_log_temp FROM event_log
Et vous pouvez effacer les anciennes données de la table.
DELETE FROM event_log