Я создал триггер для установки уникального имени (ref) для покупки, используя часовой пояс для поля create_date.Это работало нормально, пока я не заметил дубликаты ссылок, одна из ссылок имеет дату в ссылке, не совпадающую с датой в поле create_date (1 день различий)? !!
BEGIN
SET NEW.reference := concat(
(SELECT name FROM provider WHERE id = NEW.provider_id),
date_format(NEW.create_date, '%Y%m%d'), '/',
(SELECT LPAD(IFNULL(MAX(SUBSTRING_INDEX(reference, '/', -1)) + 1, 0), 3, '0')
FROM purchase
WHERE date_format(NEW.create_date, '%Y%m%d') = date_format(create_date, '%Y%m%d')
AND NEW.provider_id = provider_id
)
);
END
У кого-нибудь есть идеякакой хэппинг или лучший подход?
PS: дата в поле create_date является правильной, дата в NEW.create_date, которая используется в ссылке, неверна (возможно, б / с клиентачасовой пояс, поскольку мы отправляем его в виде строки)
Обновление
Структура таблиц:
Покупка:
CREATE TABLE purchase
(
id int auto_increment primary key,
provider_id int not null,
create_date timestamp null,
create_user int null,
change_date timestamp null,
change_user int null,
group_id int null,
reference varchar(45) null
);
CREATE INDEX purchase_reference_index ON purchase (reference);
CREATE INDEX purchase_provider_index ON purchase (provider_id);
Поставщик:
CREATE TABLE provider
(
id int auto_increment primary key,
name varchar(45) null,
constraint name_uniq unique (name)
);
Пример запроса:
INSERT INTO purchase (provider_id, create_date, create_user, group_id)
VALUE (4, '2019-01-30 02:36:58', 1, 3);
2019-01-30 02:36:58
сохраняется в базе данных как 2019-01-29 23:36:58
, когда я выбираю его из сеанса с часовым поясом сервера использования.
Функциячто я использую для установки часового пояса:
function update_timezone($timezone = null)
{
if (is_null($timezone)) $timezone = __SERVER_TIMEZONE;
if (in_array($timezone, timezone_identifiers_list())) {
date_default_timezone_set($timezone);
$tz = (new DateTime('now', new DateTimeZone(date_default_timezone_get())))->format('P');
$conn = Database::Connect();
Database::NonQuery("SET time_zone = '$tz';", $conn);
}
}
Что я ожидаю:
reference === 'provider_name20190129/00X'
Что я получаю:
reference === 'provider_name20190130/00Y'
Как воспроизвестивыпуск:
CREATE DATABASE test;
CREATE TABLE purchase
(
id int auto_increment primary key,
provider_id int not null,
create_date timestamp null,
create_user int null,
change_date timestamp null,
change_user int null,
group_id int null,
reference varchar(45) null
);
CREATE INDEX purchase_reference_index ON purchase (reference);
CREATE INDEX purchase_provider_index ON purchase (provider_id);
CREATE TABLE provider
(
id int auto_increment primary key,
name varchar(45) null,
constraint name_uniq unique (name)
);
CREATE TRIGGER test.purchase_ref_insert
BEFORE INSERT
ON test.purchase
FOR EACH ROW
BEGIN
SET NEW.reference := concat(
(SELECT name FROM provider WHERE id = NEW.provider_id),
date_format(NEW.create_date, '%Y%m%d'), '/',
(SELECT LPAD(IFNULL(MAX(SUBSTRING_INDEX(reference, '/', -1)) + 1, 0), 3, '0')
FROM purchase
WHERE date_format(NEW.create_date, '%Y%m%d') = date_format(create_date, '%Y%m%d')
AND NEW.provider_id = provider_id
)
);
END
;
INSERT INTO provider (name) VALUE ('test');
SET time_zone = '+00:00';
INSERT INTO purchase (provider_id, create_date, create_user, group_id)
VALUE (1, '2019-01-30 02:36:58', 1, 3);
SET time_zone = '+05:00';
INSERT INTO purchase (provider_id, create_date, create_user, group_id)
VALUE (1, '2019-01-30 02:36:58', 1, 3);
SET time_zone = '-05:00';
INSERT INTO purchase (provider_id, create_date, create_user, group_id)
VALUE (1, '2019-01-30 02:36:58', 1, 3);
SET time_zone = '+00:00';
SELECT create_date, reference FROM purchase;
И вот что я получаю: