* Регулярни изрази в MySQL
Публикувано на 21 май 2015 в раздел Бази от Данни.
Имаме таблица, в която ще съхраняваме потребителски имена и пароли. Искаме да направим така, че СУБД да валидира данните, които се въвеждат в базата от данни. Например искаме имената да са съставени само от малки букви и цифри, от 4 до 32 символа, а паролите да са от 6 до 64 символа, като задължително има поне една малка, поне една главна буква и поне една цифра. Дадената таблица е следната:
CREATE TABLE users( id SERIAL PRIMARY KEY, user VARCHAR(32) NOT NULL UNIQUE, pass VARCHAR(64) NOT NULL );
Лесно можем да гарантираме чрез тригери, че в потребителското име няма да има главни букви, ако просто ги превръщаме винаги в малки:
CREATE TRIGGER usernameCheck BEFORE INSERT ON users FOR EACH ROW BEGIN SET NEW.user = LOWER(NEW.user); END;
Аналогично трябва да направим тригер за UPDATE. Дължините също не са проблем. Вътре в тригера добавяме условие:
IF(CHAR_LENGTH(NEW.user) NOT BETWEEN 4 AND 32 OR CHAR_LENGTH(NEW.pass) NOT BETWEEN 6 AND 64) THEN SIGNAL SQLSTATE '45000' SET message_text = "Username or password too short"; END IF;
Това обаче не гарантира допълнителните условия - потребителското име трябва да е САМО от малки букви и цифри, т.е. други символи не са позволени. За решението на тази задача MySQL ни позволява да използваме регулярни изрази:
IF(NEW.user NOT REGEXP '^[a-z0-9]+$') THEN SIGNAL SQLSTATE '45000' SET message_text = "Username must be only letters and digits"; END IF;
Досещате се, че условието за дължина на низа може да бъде обединено с регулярния израз без проблем като той стане '^[a-z0-9]{4,32}$'. Абсолютно по аналогичен начин ще направим и проверката за паролата:
IF(NEW.pass NOT REGEXP '[a-z]' OR NEW.pass NOT REGEXP '[A-Z]' OR NEW.pass NOT REGEXP '[0-9]') THEN SIGNAL SQLSTATE '45000' SET message_text = "Password must have uppercase, lowercase letter and a digit; END IF;
Ето и кода на готовия тригер:
CREATE TRIGGER usernameInsertCheck BEFORE INSERT ON users FOR EACH ROW BEGIN SET NEW.user = LOWER(NEW.user); IF(CHAR_LENGTH(NEW.user) NOT BETWEEN 4 AND 32 OR CHAR_LENGTH(NEW.pass) NOT BETWEEN 6 AND 64) THEN SIGNAL SQLSTATE '45000' SET message_text = "Username or password too short"; END IF; IF(NEW.user NOT REGEXP '^[a-z0-9]+$') THEN SIGNAL SQLSTATE '45000' SET message_text = "Username must be only letters and digits"; END IF; IF(NEW.pass NOT REGEXP '[a-z]' OR NEW.pass NOT REGEXP '[A-Z]' OR NEW.pass NOT REGEXP '[0-9]') THEN SIGNAL SQLSTATE '45000' SET message_text = "Password must have uppercase, lowercase letter and a digit; END IF; END;
Аналогично можете да направите същия по съдържание тригер с условие BEFORE UPDATE. Регулярните изрази може да ги използвате и в съхранени процедури и в обикновени SELECT заявки.
Писането на регулярни изрази в MySQL си има своите специфики и най-вече ограничения спрямо регулярните изрази в езиците за програмиране. Няма да се спираме на подробности, но при интерес може да ги намерите в документацията.
Добави коментар