Jul 20, 2009

More stored procedures in MySQL

Recently I had to do some maintenance on MySQL database for a customer. It is all for his e-commerce web site. The issue was that all brands are stored separately in a table. However there is several synchronization tools that update site's content. So it happened that we have plenty of the brand names with different casing (e.g. Panasonic and PANASONIC).

As there is few different programs talking to the database written in different programing languages I decided to centralize the functionality in the DB itself. The issue is that we are using UTF-8 names of brands and depending on a language and its version the eastern european characters are being lowercased differently.

So I made another column for storing the hash. The issue here is to have a central code for lowercasing and then hashing string (the brand name) before it is stored to the DB. For this I created following function:

CREATE FUNCTION get_brand_id (s VARCHAR(255)) RETURNS BIGINT (20)
DETERMINISTIC
BEGIN
DECLARE my_hash VARCHAR(255);
DECLARE out1 BIGINT(20);
SET my_hash = md5(lower(s));
INSERT IGNORE INTO brands SET name=s, hash=my_hash;
SELECT brand_id INTO out1 FROM brands WHERE hash=my_hash;
RETURN out1;
END


Then I needed to create hash for all existing brands. So I made following procedure:
CREATE PROCEDURE hash_brands()
BEGIN
DECLARE my_hash, my_name VARCHAR(255);
DECLARE my_brand_id BIGINT(20);
DECLARE is_done INT DEFAULT 0;

DECLARE cur CURSOR FOR
SELECT brand_id, name FROM BRANDS;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET is_done = 1;

OPEN cur;
WHILE NOT is_done DO
FETCH cur INTO my_brand_id, my_name;
SET my_hash = md5(lower(my_name));
UPDATE brands SET
hash=my_hash
WHERE brand_id=my_brand_id;
END WHILE;
CLOSE cur;
END
Then I just neede to change unique key from name to hash field. Now I need to change couple of scripts to use my function or better to trigger insert on the brands table to use my function. Will see about that.

No comments: