我想知道是否有可能将所有数据行从一个表移动到另一个表,以匹配某个查询?
例如,我需要将所有表行从表1移动到表2,其中用户名=“ X”,密码=“ X”,以便它们不再出现在表1中。
我正在使用SQL Server 2008 Management Studio。
Answers:
应该可以在一个事务中使用两个语句,即插入和删除:
BEGIN TRANSACTION;
INSERT INTO Table2 (<columns>)
SELECT <columns>
FROM Table1
WHERE <condition>;
DELETE FROM Table1
WHERE <condition>;
COMMIT;
这是最简单的形式。如果您需要担心在两个语句之间的table1中插入了新的匹配记录,则可以添加and exists <in table2>
。
BEGIN TRANSACTION;
在此示例的开头没有。将其添加到答案的示例中不是一个好主意吗?
抱歉,这是一篇古老的文章,但我现在才偶然遇到,我想将我的解决方案提供给可能在这一天迷路的任何人。
正如一些人提到的那样,先执行“ an”INSERT
然后执行“ an”DELETE
可能会导致完整性问题,因此,一种解决方法以及在单个语句中巧妙地执行所有操作的一种方法就是利用[deleted]
临时表。
DELETE FROM [source]
OUTPUT [deleted].<column_list>
INTO [destination] (<column_list>)
DELETE
语句,所有记录首先[deleted]
在该DELETE
子句解析之前写入临时表中,然后从该表中进行处理(在这种情况下,将其插入到另一个表中),然后解析该语句。如果语句的处理部分失败,则终止整个语句;否则,终止整个语句。不仅INTO
条款。此外,BEGIN TRY...BEGIN CATCH
和ROLLBACK TRANSACTION
都是很好的预防性陈述。
OUTPUT
关键字仅用于将表数据集返回到后续语句,但是仅在某些情况下有效,例如UPDATE
([inserted]
)且DELETE
我记得正确。该[deleted]
表是一个隐式的临时表-不能完全确定它的位置或管理该进程的范围-限于当前语句的执行范围。因此,就像您可以执行类似的操作SELECT [source].[column] INTO [destination]
(在其中SELECT
返回数据集并INTO
接收数据)一样,您可以使用OUTPUT
将已删除的数据集返回到INTO
接收数据集的。
OUTPUT
语句是非标准SQL FWIW(例如,在中不起作用sqlite3
)。
所有这些答案都会对INSERT和DELETE运行相同的查询。如前所述,这冒着删除语句之间插入记录的风险,如果查询很复杂(尽管聪明的引擎“应该”使第二个调用快速执行),这可能会很慢。
正确的方法(假设INSERT已插入到新表中)是使用table2的键字段对table1进行DELETE。
删除应为:
DELETE FROM tbl_OldTableName WHERE id in (SELECT id FROM tbl_NewTableName)
请原谅我的语法,我在引擎之间切换,但是您明白了。
是的。首先执行INSERT + SELECT,然后删除DELETE原点。
INSERT INTO Table2 (UserName,Password)
SELECT UserName,Password FROM Table1 WHERE UserName='X' AND Password='X'
然后删除原件
DELETE FROM Table1 WHERE UserName='X' AND Password='X'
您可能想要保留UserID
或其他主键,则可以使用IDENTITY INSERT
保留键。
使用此单个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 Server上可以对MySql进行适当的更改
您可以使用“逻辑分区”在表之间切换数据:
通过更新分区列,数据将被自动移动到另一个表:
这是示例:
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
这是单个语句的处理方式
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
它将创建一个表并将所有数据从旧表复制到新表
SELECT * INTO event_log_temp FROM event_log
您可以清除旧表数据。
DELETE FROM event_log