#mysql #time #enums #triggers
#mysql #время #перечисления #триггеры
Вопрос:
Есть ли код, чтобы не разрешать вставлять значение непосредственно после значения, которое уже сохранено, в таблицу. Поле является ENUM.
Нигде не могу найти код
Нет доступных для ENUM
Временной интервал(’09:00′,’09:30′,’10:00′) 09:00 сохранено уже
’09:30′ не должно быть разрешено вставлять в таблицу ’10:00′ должно вставляться нормально
Ответ №1:
Нет функции по умолчанию, о которой я знаю, чтобы делать то, что вы хотите.
Я думаю, вам придется выполнить некоторые проверки, используя индекс перечисления. Значения ENUM сопоставляются числовому индексу. Вы можете выбрать column_name 0 в столбце ПЕРЕЧИСЛЕНИЯ, и это даст вам значение индекса перечисления, а не само значение перечисления. MySQL ENUM Doc
В вашем случае индекс ПЕРЕЧИСЛЕНИЯ выглядел бы примерно так:
NULL -> NULL
0 -> ''
1 -> '9:00'
2 -> '9:30'
3 -> '10:00'
Например, если у вас есть 1 запись с временным интервалом, установленным на ‘9:00’, и вы ‘ВЫБИРАЕТЕ временной интервал 0 ИЗ таблицы’, ваш результат для записи будет равен 1. Если бы значение столбца было ‘9:30’, индекс был бы равен 2 и т.д.
Вы можете найти потенциальный индекс входящего значения, используя что-то вроде этого:
SELECT FIND_IN_SET('new_value', REPLACE(SUBSTRING(column_type,6, LENGTH(column_type) - 6), ''', '') ) AS enum_options
FROM information_schema.columns
WHERE column_name='your_enum_column'
AND table_schema = 'your_schema';
Если результат этого равен любому из значений индекса (или значение индекса 1) любого из значений, уже имеющихся в таблице, вы не хотите разрешать эту новую запись. Вы можете использовать приведенный выше запрос в качестве подзапроса внутри оператора case, чтобы сравнить индекс этого нового значения с индексами ваших предыдущих значений.
РЕДАКТИРОВАТЬ (4/2/2019): После пары комментариев я думаю, что следующее может приблизить вас к тому, что вам нужно. Я не смог протестировать этот запрос, но он должен быть близок.
CREATE TEMPORARY TABLE booking_conflicts AS (
SELECT MAX(
IF(
FIND_IN_SET(
(SELECT FIND_IN_SET('12:00', REPLACE(SUBSTRING(column_type,6, LENGTH(column_type) - 6), ''', '') )
FROM information_schema.columns
WHERE column_name='your_enum_column'
AND table_name = 'booking'
AND table_schema = 'your_schema'),
CONCAT(time_slot 0, ',', time_slot 1)
) > 0,
1,
0) AS is_time_conflict
FROM booking
WHERE facility_id = 6
AND booking_date = '2020-07-04'
);
INSERT INTO bookings
(facility_id,booking_date,time_slot,member_id)
VALUES (6,'2020-07-04','12:00',2)
WHERE (SELECT is_time_conflict FROM booking_conflicts) = 0;
Что это делает, так это получение всех использованных временных интервалов с этой даты для этого объекта и сравнение их с новым временным интервалом, который вы пытаетесь использовать. Если индекс нового временного интервала равен индексу ранее использованного time_slot или ранее использованного time_slot 1, то запрос вернет 1, в противном случае 0. Мы сохраняем это во временной таблице и получаем доступ к временной таблице из вставки.
Комментарии:
1. Спасибо за ответ. У меня просто возникли небольшие проблемы с тем, как я мог бы вписать это в оператор case
2. Вставить в значения бронирований (facility_id,booking_date, time_slot, member_id) (6,’2020-07-04′,’12:00′,2) ГДЕ ВЫБЕРИТЕ FIND_IN_SET(‘new_value’, ЗАМЕНИТЬ(ПОДСТРОКА(column_type,6, ДЛИНА(column_type) — 6), ‘», «) ) КАК enum_options ИЗ information_schema.columns, ГДЕ column_name=’time_slot’ И table_schema = ‘mylescoop’, что я уже пробовал, не уверен, как связать предложение where
3. Я добавляю новый фрагмент SQL к приведенному выше ответу, который может быть полезен.
4. Спасибо за ответ, очень четкий и понятный, можно ли это интегрировать в триггер? Чтобы временная таблица хранила значение, при котором триггер активируется перед вставкой в заказы. Таким образом, тогда запускается сообщение об ошибке. Поскольку это позволило бы создать более оптимизированную базу данных, поскольку она автоматически проверяла бы это каждый раз, когда в таблице происходит вставка
5. Я не понимаю, почему этого не могло быть. Хотя, возможно, вы захотите рассмотреть возможность создания хранимой процедуры / функции вместо этого. Таким образом, вы могли бы легко заставить функцию / процедуру возвращать, была ли создана новая запись или нет, так что вы можете использовать это значение для уведомления пользователя об успехе / сбое.