2016-11-07 80 views
2

我写一个程序从一个表data_entry的数据复制到另一个表promotionaldata_entry 表结构如下表1的行(除去非相关领域) -INSERT INTO table2中选择FROM表1然后更新所选择/插入

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到01的程序其中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; 

我想现在要做从上述过程中data_entry表更新is_copied_to_promo1为所有插入/受影响的行,使每个我执行上述方法由data_entry表只新行时间应复制到促销。

我正在通过PHP代码调用此过程。该解决方案可以在执行uspCopySchoolsToPromotional后,在相同的过程中添加更新查询或运行其他查询/程序。

在此先感谢。

编辑:

我忘了提两个表在学校ID是不同的。在促销表中,数据来自多个来源。所以我在促销表中将school_id改为promo_id以避免混淆。

回答

1

如果你在学校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; 

希望这有助于:)

+0

对不起。我忘了提到两个表中的school_id都不一样。在促销表中,数据来自多个来源。其中之一是'data_entry'表。 – prograshid

+0

是否是唯一的school_name值?如果是的话,你可以在UPDATE WHERE子句中进行匹配:) – flauntster

+0

学校名称并不是唯一的。但是,如果我在'promotional'表中添加一个新的'copied_school_id'列,'data_entry'表中的'school_id'将会插入它。在这种情况下,你可能会有帮助 – prograshid

1

Mysql 8应该有公用表表达式,但它似乎并不出现在release announcements中,所以您将不得不使用其他一些机制来实现这一点。一个解决方案是使用after insert trigger

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锁定和更新)有其优缺点。

+0

去尝试触发器选项并让你知道。 – prograshid

1

如果两个表中没有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; 

希望这应该解决您的问题。