【发布时间】:2019-04-01 19:24:42
【问题描述】:
是否有代码不允许将已保存的值直接插入表中。该字段是一个 ENUM。
在任何地方都找不到代码
ENUM 没有可用的
时隙 ENUM('09:00','09:30','10:00') 09:00 已保存
'09:30' 不应该被允许插入到表中 '10:00' 应该插入正常
【问题讨论】:
是否有代码不允许将已保存的值直接插入表中。该字段是一个 ENUM。
在任何地方都找不到代码
ENUM 没有可用的
时隙 ENUM('09:00','09:30','10:00') 09:00 已保存
'09:30' 不应该被允许插入到表中 '10:00' 应该插入正常
【问题讨论】:
据我所知,没有默认功能可以执行您想要的操作。
我认为您将不得不使用 ENUM 索引进行一些检查。 ENUM 值映射到数字索引。您可以在 ENUM 列上选择 column_name+0,这将为您提供 ENUM 的索引值,而不是 ENUM 值。 MySQL ENUM Doc
在您的情况下,ENUM 索引看起来像这样:
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 语句中的子查询,以将此新值的索引与之前值的索引进行比较。
编辑(2019 年 4 月 2 日): 经过几次 cmet,我认为以下内容可能会让您更接近您的需求。我无法测试这个查询,但它应该很接近。
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。我们将其存储在临时表中并从插入访问临时表.
【讨论】: