2016-11-07 58 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; 

希望這應該解決您的問題。