Немного предыстории для выпуска:DB Комплексные Возрастающие Счетчики
В Венесуэле существует закон, который определяет, как специальный документ под названием удерживаемое Получение(выдается, когда компания, назначенная налоговой администрация, удержана налоги, объявляемые компанией, а не клиентом, действительно запутывающие юридические вещи) будет идентифицироваться и информация, которую она представит. Он говорит, что это должно быть пронумеровано в следующем формате:
YYYYMMXXXXXXXX
Где YYYY
представляет год, MM
месяц и XXXXXXXX
представляют порядковый номер (ширину до 8 цифр), который будет обновляться (начало от 0 снова), если он переполнен.
Я мог бы использовать простую ванилью AUTO_INCREMENT
, чтобы решить эту загадку, однако настоящая проблема начинается здесь.
По словам агентов налоговой администрации, инкрементная нумерация автоматически обновляется каждый месяц, то есть квитанция № 20151200000001
и № 20160100000001
могут существовать в базе данных и не сталкиваться.
Это означает, что невозможно использовать поле AUTO_INCREMENT
, так как его значение будет сбрасываться до 0
каждый месяц.
Какие варианты могут быть использованы для решения этой головоломки? Использование, конечно, только функций базы данных.
PS: Может быть в любой базе данных (включая No-SQL).
PS2: год и месяц могут быть полями на столе/документе/объекте.
Редактировать
Я сделал некоторые исследования на MySQL, основанный на @Gordon Linoff ответ, вот рабочий пример
CREATE TABLE IF NOT EXISTS test (
id int(11) NOT NULL AUTO_INCREMENT,
invoice_no varchar(12) NOT NULL,
year int(11) NOT NULL,
month int(11) NOT NULL,
identifier int(11) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB;
DELIMITER //
CREATE TRIGGER ins_tr BEFORE INSERT ON test
FOR EACH ROW BEGIN
SET @maxID = (SELECT COALESCE(MAX(identifier), 0)
FROM test
WHERE CONCAT(year, lpad(month, 2, '0')) = CONCAT(NEW.year, lpad(NEW.month, 2, '0'))
);
SET NEW.identifier = @maxID +1;
END
//
DELIMITER ;
INSERT INTO test (invoice_no, year, month) VALUES (1, 2015, 12), (2, 2015, 12), (3, 2016, 1), (4, 2016, 1);
Результат:
+----+------------+------+-------+------------+
| id | invoice_no | year | month | identifier |
+----+------------+------+-------+------------+
| 1 | 1 | 2015 | 12 | 1 |
| 2 | 2 | 2015 | 12 | 2 |
| 3 | 3 | 2016 | 1 | 1 |
| 4 | 4 | 2016 | 1 | 2 |
+----+------------+------+-------+------------+
В исследовании на пути для MongoDB или любого механизма NoSQL.
Я действительно думал об этом выборе, но я неохотно делаю это программно, там должен быть движок db с этой функцией где-то! – josegomezr
С достаточным воображением вы можете поместить всю логику программирования в один триггер. Вы все-таки сказали любую базу данных. –