Skip to content

Instantly share code, notes, and snippets.

@rsisco
Last active April 5, 2018 15:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rsisco/5babcca3cea584e1dc2d6119f8e40f20 to your computer and use it in GitHub Desktop.
Save rsisco/5babcca3cea584e1dc2d6119f8e40f20 to your computer and use it in GitHub Desktop.
MySQL to create stored procedure and function to update duplicate URL keys to be unique
DELIMITER ;;
CREATE DEFINER=`magento_prod`@`%` FUNCTION `generate_unique_url_key`(target_value_id INT) RETURNS LONGTEXT CHARSET latin1
READS SQL DATA
BEGIN
DECLARE url_key_attr_id INT DEFAULT 124;
DECLARE counter INT DEFAULT 1;
DECLARE url_key LONGTEXT;
DECLARE first_pass BOOLEAN DEFAULT TRUE;
# Retrieve current URL key for provided value_id row
SELECT `VALUE` INTO @current_url_key FROM catalog_product_entity_varchar WHERE value_id = target_value_id;
SET @new_url_key = @current_url_key;
SELECT count(*) INTO @url_count FROM catalog_product_entity_varchar WHERE attribute_id = url_key_attr_id AND `VALUE` = @new_url_key;
WHILE @url_count > 1 DO
# There is more than one occurrence of URL key
IF first_pass IS TRUE
THEN
# Count number of hyphens in URL
SELECT LENGTH(@current_url_key) - LENGTH(REPLACE(@current_url_key, '-', '')) INTO @hyphen_count;
IF @hyphen_count > 0
THEN
# Extract the right-most section of the URL key
SELECT SUBSTRING_INDEX(@current_url_key, '-', -1) INTO @tail_section;
ELSE
SET @tail_section = NULL;
END IF;
IF @tail_section REGEXP '^-?[0-9]+$'
THEN
# This key appears to already have an appended hyphen and increment number, remove it before proceeding
SET @current_url_key = SUBSTRING(@current_url_key, 1, (LENGTH(@current_url_key) - (LENGTH(@tail_section) + 1)));
END IF;
# No longer the first pass
SET first_pass = FALSE;
END IF;
# Append hyphen and counter
SET @new_url_key = concat(@current_url_key, '-', counter);
# Increase counter for next run through
SET counter = counter + 1;
# Check for other instances of this key
SELECT count(*) INTO @url_count FROM catalog_product_entity_varchar WHERE attribute_id = url_key_attr_id AND `VALUE` = @new_url_key;
# Add one, because we will have one more instance if we use this key
SET @url_count = @url_count + 1;
END WHILE;
RETURN @new_url_key;
END;;
DELIMITER ;
DELIMITER $$
# Procedure to replace duplicate URL keys with unqiue ones
CREATE PROCEDURE update_duplicate_url_keys() MODIFIES SQL DATA
BEGIN
DECLARE url_key_attr_id INT DEFAULT 124;
DECLARE cursor_value_id INT;
DECLARE done INT DEFAULT FALSE;
# Define cursor to retrieve list of duplicate value IDs
DECLARE cursor_i CURSOR FOR SELECT value_id FROM catalog_product_entity_varchar WHERE attribute_id = url_key_attr_id and `value` IN (SELECT DISTINCT `VALUE` FROM catalog_product_entity_varchar WHERE attribute_id = url_key_attr_id GROUP BY `VALUE` HAVING count(`VALUE`) > 1);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cursor_i;
read_loop: LOOP
FETCH cursor_i INTO cursor_value_id;
IF done THEN
LEAVE read_loop;
END IF;
# Update offending value ID with a new (unique) URL key value
UPDATE catalog_product_entity_varchar SET `VALUE` = generate_unique_url_key(cursor_value_id) WHERE value_id = cursor_value_id;
COMMIT;
END LOOP;
CLOSE cursor_i;
END $$
DELIMITER ;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment