简体   繁体   English

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

[英]Move SQL data from one table to another

I was wondering if it is possible to move all rows of data from one table to another, that match a certain query?我想知道是否可以将与某个查询匹配的所有数据行从一个表移动到另一个表?

For example, I need to move all table rows from Table1 to Table2 where their username = 'X' and password = 'X', so that they will no longer appear in Table1.例如,我需要将所有表行从表 1 移动到表 2,其中它们的用户名 = 'X' 和密码 = 'X',这样它们就不会再出现在表 1 中。

I'm using SQL Server 2008 Management Studio.我正在使用 SQL Server 2008 Management Studio。

Should be possible using two statements within one transaction, an insert and a delete:应该可以在一个事务中使用两个语句,插入和删除:

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

DELETE FROM Table1
WHERE <condition>;

COMMIT;

This is the simplest form.这是最简单的形式。 If you have to worry about new matching records being inserted into table1 between the two statements, you can add an and exists <in table2> .如果您必须担心在两个语句之间将新的匹配记录插入到 table1 中,您可以添加一个and exists <in table2>

This is an ancient post, sorry, but I only came across it now and I wanted to give my solution to whoever might stumble upon this one day.这是一篇古老的帖子,抱歉,但我现在才发现它,我想将我的解决方案提供给有一天可能会偶然发现的人。

As some have mentioned, performing an INSERT and then a DELETE might lead to integrity issues, so perhaps a way to get around it, and to perform everything neatly in a single statement, is to take advantage of the [deleted] temporary table.正如一些人所提到的,先执行INSERT然后执行DELETE可能会导致完整性问题,因此,也许可以绕过它并在单个语句中整齐地执行所有操作的方法是利用[deleted]临时表。

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

All these answers run the same query for the INSERT and DELETE.所有这些答案都对 INSERT 和 DELETE 运行相同的查询。 As mentioned previously, this risks the DELETE picking up records inserted between statements and could be slow if the query is complex (although clever engines "should" make the second call fast).如前所述,这可能会导致 DELETE 获取语句之间插入的记录,并且如果查询很复杂,可能会很慢(尽管聪明的引擎“应该”使第二次调用更快)。

The correct way (assuming the INSERT is into a fresh table) is to do the DELETE against table1 using the key field of table2.正确的方法(假设 INSERT 是到一个新表中)是使用 table2 的键字段对 table1 执行 DELETE。

The delete should be:删除应该是:

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

Excuse my syntax, I'm jumping between engines but you get the idea.请原谅我的语法,我在引擎之间跳跃,但你明白了。

Yes it is.是的。 First INSERT + SELECT and then DELETE orginals.首先 INSERT + SELECT 然后 DELETE 原件。

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

then delete orginals然后删除原文

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

you may want to preserve UserID or someother primary key, then you can use IDENTITY INSERT to preserve the key.您可能希望保留UserID或其他主键,然后您可以使用IDENTITY INSERT来保留该键。

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

A cleaner representation of what some other answers have hinted at:更清晰地表示其他一些答案所暗示的内容:

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

Use this single sql statement which is safe no need of commit/rollback with multiple statements.使用这个单一的 sql 语句是安全的,不需要提交/回滚多个语句。

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

Works on SQL server make appropriate changes for MySql在 SQL 服务器上工作对 MySql 进行适当的更改

You should be able to with a subquery in the INSERT statement.您应该能够在 INSERT 语句中使用子查询。

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

followed by deleting from table1.然后从table1中删除。

Remember to run it as a single transaction so that if anything goes wrong you can roll the entire operation back.请记住将其作为单个事务运行,以便如果出现任何问题,您可以回滚整个操作。

Try this试试这个

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

Then然后

DELETE FROM TABLE1 WHERE Criteria

You could try this:你可以试试这个:

SELECT * INTO tbl_NewTableName 
FROM tbl_OldTableName
WHERE Condition1=@Condition1Value

Then run a simple delete:然后运行一个简单的删除:

DELETE FROM tbl_OldTableName
WHERE Condition1=@Condition1Value

You may use "Logical Partitioning" to switch data between tables:您可以使用“逻辑分区”在表之间切换数据:

By updating the Partition Column, data will be automatically moved to the other table:通过更新分区列,数据将自动移动到另一个表:

here is the sample:这是示例:

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

Here is how do it with single statement这是使用单个语句的方法

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

EXAMPLE:例子:

    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

If the two tables use the same ID or have a common UNIQUE key:如果两个表使用相同的 ID 或有一个共同的 UNIQUE 键:

1) Insert the selected record in table 2 1)在表2中插入选中的记录

INSERT INTO table2 SELECT * FROM table1 WHERE (conditions)

2) delete the selected record from table1 if presents in table2 2) 如果存在于 table2 中,则从 table1 中删除所选记录

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

It will create a table and copy all the data from old table to new table它将创建一个表并将所有数据从旧表复制到新表

SELECT * INTO event_log_temp FROM event_log

And you can clear the old table data.并且可以清除旧表数据。

DELETE FROM event_log

对于某些情况,最简单的方法是编写 Table1 脚本,将现有的 Table1 重命名为 Table2,然后运行脚本重新创建 Table1。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM