我有这个项目表,在插入它时,一个 ID 字段(除了使用的索引 ID)应该在这个模式中生成日期和自动增量值的组合
“yy-mm-xxx” 其中 yy-当前年份的最后 2 位数字,mm-月,xxx-自动生成的 id。
我有这个项目表,在插入它时,一个 ID 字段(除了使用的索引 ID)应该在这个模式中生成日期和自动增量值的组合
“yy-mm-xxx” 其中 yy-当前年份的最后 2 位数字,mm-月,xxx-自动生成的 id。
实现这一点的最好方法是有一个单独的列,由触发器更新
CREATE TRIGGER before_insert_table_name
BEFORE INSERT ON table_name
FOR EACH ROW
SET new.id = <your_own_function_to_create_this_prefixed_id>;
除了您可能最好将此 id 存储在单独的列中并根据需要(例如通过视图)呈现它之外,您的话...自动增量值...可能至少以两种方式解释:
auto_increment
PK 列id
,并且您想在生成此复合二级 id 时使用它的值id
(无论是否auto_increment
),但您希望生成每个年和月组合唯一的 int 值。如果这是第一种情况,您可以使用单独的表进行排序和这样的触发器来解决这个问题
表架构
CREATE TABLE items_seq (id int not null auto_increment primary key);
CREATE TABLE items (id int not null default 0 primary key,
item_id varchar(9) default '', ...);
触发器
DELIMITER $$
CREATE TRIGGER tg_bi_items
BEFORE INSERT ON items
FOR EACH ROW
BEGIN
INSERT INTO items_seq (id) VALUES(NULL);
SET NEW.id = LAST_INSERT_ID(),
NEW.item_id = CONCAT(DATE_FORMAT(CURDATE(), '%y-%m-'),
LPAD(LAST_INSERT_ID(), 3, '0'));
END$$
DELIMITER ;
现在您只需插入行
INSERT INTO items (item_id) VALUES (NULL),(NULL);
你会得到
| 身份证 | 项目 ID | ------------------ | 1 | 13-08-001 | | 2 | 13-08-002 |
这是SQLFiddle演示
如果是第二种情况,那么您可以使用这样的触发器来执行此操作
CREATE TRIGGER tg_bi_items
BEFORE INSERT ON items
FOR EACH ROW
SET NEW.item_id = CONCAT(
DATE_FORMAT(CURDATE(), '%y-%m-'),
LPAD(COALESCE(
(
SELECT SUBSTRING_INDEX(MAX(item_id), '-', -1)
FROM items
WHERE item_id LIKE DATE_FORMAT(CURDATE(), '%y-%') -- based on your comments reset to 1 every year
), 0) + 1, 3, '0'));
使用这种方法,您必须为每一行发出单独的插入语句,否则您最终会得到相同的生成数字。
INSERT INTO items (item_id) VALUES (NULL);
INSERT INTO items (item_id) VALUES (NULL);
你会得到
| 身份证 | 项目 ID | ------------------ | 1 | 13-08-001 | | 2 | 13-08-002 |
这是SQLFiddle演示
创建一个after insert trigger
应该根据您正在制作的模式更新列的内容
我不相信这可以通过触发器来完成,无论是 BEFORE INSERT 还是 AFTER INSERT。并且分配给 AUTO_INCREMENT 列的值不适用于 INSERT 语句中的表达式。
关于你将得到的最接近的(我认为)是一个单独的 UPDATE 语句。诀窍将是识别刚刚插入的行。一种方法是向该列插入 NULL 值,然后更新该列中具有 NULL 的所有行:
UPDATE mytable t
SET t.myidcol = CONCAT(DATE_FORMAT(NOW(),'%y-%i-'),t.id)
WHERE t.myidcol IS NULL;
(您没有指定该日期值的来源;上面的语句使用系统中的当前日期。如果它是表中的日期列,则改用它。DATE_FORMAT 函数将日期/日期时间/时间戳转换为一个字符串,基于第二个参数中提供的格式。
编辑
我可能已经阅读了比预期更多的“(除了使用的索引 id)”和“自动增量”。我认为这意味着该表有一个定义为 AUTO_INCREMENT 的 ID 列。如果不是这种情况,那么上面的答案就不起作用了。
(这是问题中的更多细节,即 SHOW CREATE TABLE 的输出和一些示例数据,显示将分配的值的类型(对于每个不同的值 'yy-mm-',自动增量 ID 是否“重置”) ,或者它是否连续上升。)
如果自动增量部分的值是从 AUTO_INCREMENT 以外的机制派生的,那么将值分配给列可能会在 BEFORE INSERT 触发器中完成。
尽管如此,我质疑以这种格式存储列的必要性。(添加此列并没有满足明显的要求,没有给出需要此列的原因。)
如果date
和id
在表中存储为单独的列,则格式化字符串的生成是微不足道的,并且可以在查询的 SELECT 列表中处理。我看不出这对于排序非常有用,因为不能保证对字符串值进行排序以数字顺序对给定 yy-mm- 内的 id 值进行排序,而不会将其拆分回来。