将SQL数据从一个表移动到另一个表

dou*_*ood 64 sql sql-server

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

例如,我需要将所有表行从Table1移动到Table2,其中username ='X'和password ='X',这样它们将不再出现在Table1中.

我正在使用SQL Server 2008 Management Studio.

Tho*_*ten 108

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

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

DELETE FROM Table1
WHERE <condition>;

COMMIT;
Run Code Online (Sandbox Code Playgroud)

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

  • 不过,您想确保这两个语句都作为单个事务完成。也就是说,关闭自动提交,并且仅在没有发生错误的情况下在删除后执行一次提交。如果插入失败,您可能不想删除,反之亦然。 (2认同)
  • 我不小心删除了所有我想移动的数据,因为在这个例子的开头没有“BEGIN TRANSACTION;”。将其添加到答案的示例中不是一个好主意吗? (2认同)

tha*_*Guy 44

这是一个古老的帖子,对不起,但我现在才遇到它,我想解决有一天可能偶然发现的人.

正如一些人所提到的那样,执行a INSERT然后执行a DELETE可能会导致完整性问题,所以也许一种解决它的方法,并在一个语句中巧妙地执行所有操作,就是利用[deleted]临时表.

DELETE FROM [source]
OUTPUT [deleted].<column_list>
INTO [destination] (<column_list>)
Run Code Online (Sandbox Code Playgroud)

  • 如果目的地涉及外键关系,这将遇到问题.您将收到错误:OUTPUT INTO子句的目标表'<destination>'不能位于(主键,外键)关系的任何一侧.找到引用约束'<约束名称>'. (5认同)
  • 使用`DELETE`语句,所有记录首先写入`[deleted]`临时表,在`DELETE`子句结束之前,从它们可以处理它们 - 在这种情况下插入另一个表 - 之后语句解析.如果语句的处理部分失败,则整个语句终止; 不仅是`INTO`条款.此外,"开始尝试...开始捕捉"和"回滚交易"是很好的预防性陈述. (3认同)

小智 18

所有这些答案都对INSERT和DELETE运行相同的查询.如前所述,这可能会使DELETE获取在语句之间插入的记录,如果查询很复杂,则可能会很慢(尽管聪明的引擎"应该"使第二次调用快速).

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

删除应该是:

DELETE FROM tbl_OldTableName WHERE id in (SELECT id FROM tbl_NewTableName)
Run Code Online (Sandbox Code Playgroud)

请原谅我的语法,我在引擎之间跳跃,但你明白了.


pir*_*rho 8

是的.首先是INSERT + SELECT,然后是DELETE orginals.

INSERT INTO Table2 (UserName,Password)
SELECT UserName,Password FROM Table1 WHERE UserName='X' AND Password='X'
Run Code Online (Sandbox Code Playgroud)

然后删除orginals

DELETE FROM Table1 WHERE UserName='X' AND Password='X'
Run Code Online (Sandbox Code Playgroud)

你可能想要保留UserID或其他主键,然后你可以IDENTITY INSERT用来保存密钥.

在MSDN上查看有关SET IDENTITY_INSERT的更多信息


Gre*_*age 8

更清晰地表示其他一些答案所暗示的内容:

DELETE sourceTable
OUTPUT DELETED.*
INTO destTable (Comma, separated, list, of, columns)
WHERE <conditions (if any)>
Run Code Online (Sandbox Code Playgroud)


wor*_*ad3 5

您应该能够在 INSERT 语句中使用子查询。

INSERT INTO table1(column1, column2) SELECT column1, column2 FROM table2 WHERE ...;
Run Code Online (Sandbox Code Playgroud)

然后从 table1 中删除。

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


Dhe*_*rni 5

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

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

在 SQL 服务器上工作对 MySql 进行适当的更改

  • 不幸的是,如果目标(插入)表包含外键约束,则这将不起作用。在这种情况下,唯一的解决方案是在单个事务中使用不同的插入和删除语句。 (2认同)