Естествено, че в MySQL няма вградени функции за работа с ЕГН-та, но това не пречи да си ги дефинираме сами. След като преди време търсих такива за Excel и всичко, което намерих – чеп за зеле не ставаше, написах си мои. Сега търсих функции за ЕГН и ЛНЧ в MySQL и естествено – не намерих. Затова на бързо си сътворих няколко и ги шервам тук.

Няма да навлизам в тежък обяснителен режим кое, как и защо. Първата функция е check_egn и проверява дали контролната сума на подадения ЕГН е валидна. НЕ валидира, дали датата вътре е „възможна“, а само дали контролната сума е валидна. Връща 1, ако е валидна или 0, ако не е валидна. Ако имаме таблица с колона `egn` може да извадим само записите с невалидните ЕГН-та със следната заявка: SELECT * FROM `table_name` WHERE egn_check(`egn`) = 0; ерго, ако трябват само валидните в условието може да се посочи единица. Ако ЕГН-то не е 10 символа – автоматично връща 0.

DELIMITER $$
CREATE FUNCTION `check_egn`(`egn` VARCHAR(10)) RETURNS tinyint(3) UNSIGNED
NO SQL
DETERMINISTIC
BEGIN
DECLARE s1_sum, i, c, w INT DEFAULT 0;
DECLARE weights VARCHAR(9) DEFAULT ‘248509736′;

IF CHAR_LENGTH(egn) <> 10 THEN
RETURN 0;
END IF;

label1: LOOP
SET i = i + 1;
IF i < 10 THEN
SET c = CAST(SUBSTRING(egn, i, 1) AS UNSIGNED);
SET w = CAST(SUBSTRING(weights, i, 1) AS UNSIGNED);
IF w = 0 THEN
SET w = 10;
END IF;
SET s1_sum = s1_sum + (c * w);
ITERATE label1;
END IF;
LEAVE label1;
END LOOP label1;
SET s1_sum = (s1_sum % 11) %10;

IF s1_sum = CAST(SUBSTRING(egn, 10, 1) AS UNSIGNED) THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END$$
DELIMITER ;

Втората функция е почти същата, като първата, но проверява за контролната сума на ЛНЧ (която неизвестно защо е с различни тегла и делител от ЕГН). Извиква се по същия начин, както и предишната функция, връща същите резултати, само името на функцията е check_lnc().

DELIMITER $$
CREATE FUNCTION `check_lnc`(`lnc` VARCHAR(10)) RETURNS tinyint(3) unsigned
NO SQL
DETERMINISTIC
BEGIN
DECLARE s1_sum, i, c, w INT DEFAULT 0;
DECLARE weights VARCHAR(18) DEFAULT ‘211917131109070301′;

IF CHAR_LENGTH(lnc) <> 10 THEN
RETURN 0;
END IF;

label1: LOOP
SET i = i + 1;
IF i < 10 THEN
SET c = CAST(SUBSTRING(lnc, i, 1) AS UNSIGNED);
SET w = CAST(SUBSTRING(weights, (i*2)-1, 2) AS UNSIGNED);
SET s1_sum = s1_sum + (c * w);
ITERATE label1;
END IF;
LEAVE label1;
END LOOP label1;
SET s1_sum = s1_sum %10;

IF s1_sum = CAST(SUBSTRING(lnc, 10, 1) AS UNSIGNED) THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END$$
DELIMITER ;

И накрая – третата функция връща датата на раждане от подаден ЕГН. Върнатата стойност е от тип DATE, т.е. във формат 0000-00-00. При евентуална необходимост може да бъде преформатирана в различен формат. Пример няма да посочвам – от първия би трябвало да става достатъчно ясно.

DELIMITER $$
CREATE FUNCTION `egn2date`(`egn` VARCHAR(10)) RETURNS date
NO SQL
DETERMINISTIC
BEGIN
DECLARE y, m, d INT DEFAULT 0;

IF CHAR_LENGTH(egn) <> 10 THEN
RETURN STR_TO_DATE(‘0000-00-00′, ‘%Y-%m-%d’);
END IF;

SET y = CAST(SUBSTRING(egn, 1, 2) AS UNSIGNED);
SET m = CAST(SUBSTRING(egn, 3, 2) AS UNSIGNED);
SET d = CAST(SUBSTRING(egn, 5, 2) AS UNSIGNED);

CASE
WHEN FLOOR(m / 20) = 1 THEN
SET y = y + 1800;
SET m = m – 20;
WHEN FLOOR(m / 20) = 2 THEN
SET y = y + 2000;
SET m = m – 40;
ELSE
SET y = y + 1900;
END CASE;

RETURN STR_TO_DATE(CONCAT(y,’-',LPAD(m,2,’00′),’-',LPAD(d,2,’00′)), ‘%Y-%m-%d’);

END$$
DELIMITER ;

Ползвайте със здраве, ако има някакви проблеми – пишете, да ги „ъпдейтна“… и успех с базите.