2009-10-23 214 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適當的修改

相關問題