我需要一个查询来将记录从一个表移动到另一个表而不使用多个语句?
答案 0 :(得分:16)
不,您无法在一个SQL语句中移动记录。您必须使用INSERT
后跟DELETE
语句。您应该将这些语句包装到transaction中,以确保复制操作保持原子。
START TRANSACTION;
INSERT INTO
new_table
SELECT
*
FROM
old_table
WHERE
some_field = 'your_criteria';
DELETE FROM old_table WHERE some_field = 'your_criteria';
COMMIT;
答案 1 :(得分:10)
如果 确实 想要在单个SQL语句中执行此操作,实现此目的的一种方法是在源表上创建“after delete”触发器将行插入目标表。这样,您可以将行从源表中移动到目标表,只需将其从源表中删除即可。当然,只有当你想在源表上插入 每次 删除目标表时,这才有效。
DELIMITER $$
DROP TRIGGER IF EXISTS TR_A_DEL_SOURCE_TABLE $$
CREATE TRIGGER TR_A_DEL_SOURCE_TABLE AFTER DELETE ON SOURCE_TABLE FOR EACH ROW BEGIN
INSERT IGNORE INTO TARGET_TABLE(id,val1,val2) VALUES(old.id,old.va1,old.val2);
END $$
DELIMITER ;
所以将id为42的行从源表移动到目标表:
delete from source_table where id = 42;
答案 2 :(得分:5)
不 - 您可以在一个嵌套语句中执行INSERT
,但仍需要删除该记录。
答案 3 :(得分:2)
无法将其作为单个查询,但如果您必须在应用程序中的单个查询中执行此操作,则可以创建存储过程来为您执行此操作。
DELIMITER $$
DROP PROCEDURE IF EXISTS `copydelete` $$
CREATE PROCEDURE `copydelete` (id INT)
BEGIN
INSERT INTO New_Table SELECT * from Old_Table WHERE Old_Table.IdField=id;
DELETE FROM Old_Table where IdField=id;
END $$
DELIMITER ;
然后你的新查询就是
CALL copydelete(4);
将删除WHERE IdField = 4;
答案 4 :(得分:0)
请注意,插入选择和删除之间的时间延迟可能导致您删除太多。
对于安全路线,您可以使用更新字段:
update old_table set move_flag=1 where your_criteria
insert into ... select from ... where move_flag = 1
delete from old_table where move_flag=1
或者使用锁定old_table的事务,因此在insert ... select和delete之间不能添加任何数据。