[英]INSERT INTO table2 SELECT FROM table1 then UPDATE table1 rows that selected/inserted
我正在编写一个程序,将数据从表data_entry
复制到另一个表promotional
中data_entry
表结构如下(不包括非相关字段)-
CREATE TABLE `data_entry` (
`school_id` int(11) NOT NULL AUTO_INCREMENT,
`school_name` varchar(255) NOT NULL,
`mobile_number` varchar(15) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
`website` varchar(255) DEFAULT NULL,
`city` varchar(250) DEFAULT NULL,
`pin` varchar(6) DEFAULT NULL,
`is_copied_to_promo` tinyint(4) DEFAULT '0'
PRIMARY KEY (`school_id`)
)
promotional
表格结构(不相关的字段除外)
CREATE TABLE `promotional` (
`promo_id` int(11) NOT NULL AUTO_INCREMENT, //renamed to avoid confusion
`school_name` varchar(255) NOT NULL,
`mobile_number` varchar(15) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
`website` varchar(255) DEFAULT NULL,
`city` varchar(250) DEFAULT NULL,
`pin` varchar(6) DEFAULT NULL,
`copied_school_id` INT, // edit - school_id of data_entry table will go here
PRIMARY KEY (`promo_id`)
)
这是将data_entry
所有行复制到is_copied_to_promo=0
promotional
中的is_copied_to_promo=0
。
程序
CREATE PROCEDURE `uspCopySchoolsToPromotional`(IN param_insert_datetime DATETIME)
BEGIN
INSERT IGNORE INTO promotional (
school_name,
mobile_number,
email,
website,
city,
pin,
copied_school_id
)
SELECT school_name,
mobile_number,
email,
website,
city,
pin,
school_id
FROM data_entry
WHERE is_copied_to_promo =0 ;
END;
我现在要做到及时更新is_copied_to_promo
到1
在data_entry
表从上述过程全部插入/受影响的行,使每个我执行上面的程序时仅新行data_entry
表应该复制到促销。
我通过PHP
代码调用此过程。 解决方案可以在同一过程中添加更新查询,或者在执行uspCopySchoolsToPromotional
之后运行另一个查询/ uspCopySchoolsToPromotional
。
提前致谢。
编辑:
我忘了提到两个表中的school_id是不同的。 在促销表中,数据来自多个来源。 因此,为了避免引起您的困惑, promo_id
在促销表中使用promo_id
重命名了school_id
。
如果您还复制了school_id,则您有一个唯一的密钥可以使用,然后可以在INSERT之后添加一个UPDATE来执行此操作,例如:
CREATE PROCEDURE `uspCopySchoolsToPromotional`(IN param_insert_datetime DATETIME)
BEGIN
INSERT IGNORE INTO promotional (
school_id,
school_name,
mobile_number,
email,
website,
city,
pin
)
SELECT school_id,
school_name,
mobile_number,
email,
website,
city,
pin,
FROM data_entry
WHERE is_copied_to_promo =0 ;
UPDATE data_entry
SET is_copied_to_promo=1
WHERE
school_id=(SELECT school_id FROM promotional)
AND is_copies_to_promo=0;
END;
希望这可以帮助 :)
Mysql 8应该具有Common Table Expressions,但是它似乎没有出现在发行公告中 ,因此您将不得不使用其他某种机制来实现这一点。 一种解决方案是使用插入后触发器
CREATE TRIGGER data_entry AFTER INSERT ON promotional_update
FOR EACH ROW
BEGIN
UPDATE data_entry SET
WHERE is_copied_to_promo = 1 WHERE school_id = new.ID;
END
另一种解决方案是在插入后进行表级锁定和更新
CREATE PROCEDURE `uspCopySchoolsToPromotional`(IN param_insert_datetime DATETIME)
BEGIN
LOCK TABLES data_entry WRITE;
....
UPDATE data_entry
SET is_copied_to_promo=1
WHERE
school_id=(SELECT school_id FROM promotional)
AND is_copies_to_promo=0;
UNLOCK TABLES:
END;
请注意,如果不锁定表,则可能会发现竞争条件导致不一致。 两种方法(触发vs锁定和更新)各有利弊。
如果两个表中都没有School_id作为auto_increment,则可以遵循Flauntster的查询。
如果两个表中的列均为auto_increment,则可以按照以下查询
CREATE PROCEDURE `uspCopySchoolsToPromotional`(IN param_insert_datetime DATETIME)
BEGIN
INSERT IGNORE INTO promotional (
school_id,
school_name,
mobile_number,
email,
website,
city,
pin
)
SELECT school_id,
school_name,
mobile_number,
email,
website,
city,
pin,
FROM data_entry
WHERE is_copied_to_promo =0 ;
UPDATE data_entry de
JOIN promotional p ON de.school_name = p.school_name
AND de.mobile_number = p.mobile_number
AND is_copies_to_promo = 0
SET is_copied_to_promo=1;
END;
希望这能解决您的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.