2009-10-23 153 views
40

我想知道是否有可能将所有数据行从一个表移动到另一个表,并匹配某个查询?将SQL数据从一个表移动到另一个表

例如,我需要将Table1中的所有表格行移动到Table2,其中username ='X'和password ='X',以便它们不会再出现在Table1中。

我正在使用SQL Server 2008 Management Studio。

谢谢。

+0

嘿,伙计们,非常感谢你的快速反应。非常感激。 – doubleplusgood 2009-10-23 09:38:07

回答

70

应该使用一个事务,插入和删除中的两个语句是可能的:

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

DELETE FROM Table1 
WHERE <condition>; 

COMMIT; 

这是最简单的形式。如果您不必担心在两个语句之间插入table1的新匹配记录,则可以添加一个and exists <in table2>

+1

你想确保两个语句都是作为单个事务完成的。要说,关闭自动提交,并且在删除之后做一次提交,只要没有发生错误。如果插入失败,您可能不想删除,反之亦然。 – Jay 2009-10-23 12:55:00

+0

已经足够了,但即使它们是作为单个事务完成的,如果在执行两条语句期间发生插入操作,也可能会出现问题。没有太多的数据库以某种方式运行,以便在事务中“读取是可重复的”。 – Thorsten 2009-10-23 17:35:38

+0

我相信你可以使用“SET TRANSACTION ISOLATION LEVEL SERIALIZABLE”进行交易,以确保你没有看到新的记录 – 2009-10-23 17:41:37

2

试试这个

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

然后

DELETE FROM TABLE1 WHERE Criteria 
3

你应该能够与在INSERT语句中的子查询。

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

其次是从表1中删除。

请记住将其作为单个事务运行,以便如果出现任何问题,可以将整个操作返回。

8

是的。先执行INSERT + SELECT,然后删除orginals。

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

然后删除orginals

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

您可能希望保留UserID或一些其它的主键,那么你可以使用IDENTITY INSERT保存键。

see more on SET IDENTITY_INSERT on MSDN

15

所有这些问题的答案运行的INSERT相同的查询和删除。如前所述,这会使DELETE拾取插入到语句之间的记录,如果查询很复杂(尽管聪明的引擎“应该”快速地进行第二个调用)可能会很慢。

正确的方法(假设INSERT进入一个新表)是使用table2的键字段对table1执行DELETE操作。

的删除应该是:

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

原谅我的语法,我在引擎之间的跳跃,但你的想法。

29

这是一个古老的帖子,对不起,但我现在只是遇到它,我想给我的解决方案谁可能会偶然发现这一天。

如一些人所提到的,执行INSERT然后DELETE可能导致完整性问题,所以也许一个方法来解决它,并在单个语句整齐执行的一切,就是要把[deleted]临时表的优势。

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

我永远不会删除任何内容,然后再将它添加到我需要的地方。如果出现问题,可能很难弄清楚! – d00dle 2014-07-15 16:42:23

+2

使用DELETE语句,在DELETE子句解析之前,所有记录首先被写入到临时表中,在这种情况下插入到另一个表中 - 之后,声明已解决。如果语句的处理部分失败,则整个语句终止;不仅是'INTO'子句。此外,“BEGIN TRY ... BEGIN CATCH”和“ROLLBACK TRANSACTION”是很好的预防性陈述。 – that0th3rGuy 2014-07-16 10:14:13

+5

如果目的地涉及外键关系,则会出现问题。您将收到错误:OUTPUT INTO子句的目标表''不能位于(主键,外键)关系的任一侧。找到参考约束'<约束名称>'。 – 2014-11-26 08:34:08

0

如果两个表使用相同的ID或具有共同UNIQUE键:

1)将表2中

INSERT INTO table2 SELECT * FROM table1 WHERE (conditions) 

2所选择的记录)中删除从表1所选择的记录如果出现在表2中

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

以下是它如何与单一语句

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

实施例:

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

你可以使用“逻辑分区”表之间切换数据:

通过更新分配柱,数据将自动移动到另一个表:

这里是样本:

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

使用这个安全的单个sql语句,不需要多条语句提交/回滚。

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

工程SQL服务器上做出的MySql适当的修改

相关问题