2015-11-08 56 views
0

我有兩個表productscompanies。每種產品都屬於一家公司。每個產品也可以有一些關鍵字。關鍵字存儲在第i列產品表中,並由空間分隔。觸發器和過程遍歷行

我想在公司名稱keywords字段在最後位置。我正在寫觸發器和程序來解決我的目標。

我已經創建了下面的觸發器:

DELIMITER // 
CREATE TRIGGER `update_product_keywords_after_update_companies` 
AFTER UPDATE ON `companies` 
FOR EACH ROW 
    BEGIN 
     set @company_id = new.id; 
     set @company_new_name = new.company_name; 
     set @company_old_name = old.company_name; 

     CALL update_product_keywords_by_company_name(@company_id, @company_old_name, @company_new_name); 
    END 
; 
// 
DELIMITER ; 

並且該過程如下所示:

DELIMITER // 
CREATE PROCEDURE update_product_keywords_by_company_name(IN company_id INT(10) UNSIGNED, IN company_old_name VARCHAR(120), IN company_new_name VARCHAR(120)) 
BEGIN 
    DECLARE done INT DEFAULT 0; 
    DECLARE keywords TEXT; 
    DECLARE cur CURSOR FOR SELECT `keywords` FROM `products` WHERE `company_id` = company_id; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; 

    OPEN cur; 
    -- iterate over every product of that company 
    REPEAT 
     FETCH cur INTO keywords; 
     IF NOT done THEN 
      IF (keywords LIKE concat('%', company_old_name)) 
      THEN 
       -- if keywords contains old company name, replace it with new company name 
       UPDATE `products` SET `keywords` = REPLACE(keywords, company_old_name, company_new_name) WHERE `products`.`company_id` = company_id; 
      ELSE 
       -- if keywords does not contain old company name, appen new company name at the end of keywords 
       UPDATE `products` SET `keywords` = CONCAT_WS(' ', keywords, company_new_name) WHERE `products`.`company_id` = company_id; 
      END IF; 
     END IF; 
    UNTIL done END REPEAT; 

    CLOSE cur; 
END 
// 
DELIMITER ; 

不幸的是,我的程序總是通過清除它,只有加入更新的每個產品的關鍵字(公司)新的公司名稱。即使早些時候有一些關鍵字,它們也會被刪除。

我正在使用MariaDB 10.任何幫助非常感謝。

回答

0

避免將變量和參數命名爲表格的列。

嘗試:

DELIMITER // 

CREATE TRIGGER `update_product_keywords_after_update_companies` 
AFTER UPDATE ON `companies` 
FOR EACH ROW 
    BEGIN 
     /* 
     set @company_id = new.id; 
     set @company_new_name = new.company_name; 
     set @company_old_name = old.company_name; 
     */ 

     /* 
     CALL update_product_keywords_by_company_name(@company_id, @company_old_name, @company_new_name); 
     */ 

     CALL update_product_keywords_by_company_name(NEW.`id`, OLD.`company_name`, NEW.`company_name`); 
    END// 

DELIMITER ; 

DELIMITER // 

/* 
CREATE PROCEDURE update_product_keywords_by_company_name(IN company_id INT(10) UNSIGNED, IN company_old_name VARCHAR(120), IN company_new_name VARCHAR(120)) 
*/ 
CREATE PROCEDURE `update_product_keywords_by_company_name`(
    IN `_company_id` INT(10) UNSIGNED, 
    IN `company_old_name` VARCHAR(120), 
    IN `company_new_name` VARCHAR(120) 
) 
BEGIN 
    DECLARE done INT DEFAULT 0; 
    DECLARE keywords TEXT; 
    /* 
    DECLARE cur CURSOR FOR SELECT `keywords` FROM `products` WHERE `company_id` = company_id; 
    */ 
    DECLARE cur CURSOR FOR 
    SELECT `keywords` 
    FROM `products` 
    WHERE `company_id` = `_company_id`; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; 

    OPEN cur; 
    -- iterate over every product of that company 
    REPEAT 
     FETCH cur INTO keywords; 
     IF NOT done THEN 
      IF (keywords LIKE concat('%', /*company_old_name*/ `company_old_name`)) 
      THEN 
       -- if keywords contains old company name, replace it with new company name 
       UPDATE `products` 
       SET `keywords` = REPLACE(keywords, /*company_old_name*/ `company_old_name`, /*company_new_name*/ `company_new_name`) 
       WHERE `products`.`company_id` = /*company_id*/ `_company_id`; 
      ELSE 
       -- if keywords does not contain old company name, appen new company name at the end of keywords 
       UPDATE `products` 
       SET `keywords` = CONCAT_WS(' ', keywords, /*company_new_name*/ `company_new_name`) 
       WHERE `products`.`company_id` = /*company_id*/ `_company_id`; 
      END IF; 
     END IF; 
    UNTIL done END REPEAT; 

    CLOSE cur; 
END// 

DELIMITER ;