0

我有这个项目表,在插入它时,一个 ID 字段(除了使用的索引 ID)应该在这个模式中生成日期和自动增量值的组合

“yy-mm-xxx” 其中 yy-当前年份的最后 2 位数字,mm-月,xxx-自动生成的 id。

4

4 回答 4

1

实现这一点的最好方法是有一个单独的列,由触发器更新

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>;
于 2013-08-16T03:48:38.347 回答
1

除了您可能最好将此 id 存储在单独的列中并根据需要(例如通过视图)呈现它之外,您的话...自动增量值...可能至少以两种方式解释:

  1. 您有一个auto_incrementPK 列id,并且您想在生成此复合二级 id 时使用它的值
  2. 您有一个 PK 列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演示

于 2013-08-16T05:14:18.777 回答
0

创建一个after insert trigger应该根据您正在制作的模式更新列的内容

于 2013-08-16T03:49:26.367 回答
0

我不相信这可以通过触发器来完成,无论是 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 触发器中完成。


尽管如此,我质疑以这种格式存储列的必要性。(添加此列并没有满足明显的要求,没有给出需要此列的原因。)

如果dateid在表中存储为单独的列,则格式化字符串的生成是微不足道的,并且可以在查询的 SELECT 列表中处理。我看不出这对于排序非常有用,因为不能保证对字符串值进行排序以数字顺序对给定 yy-mm- 内的 id 值进行排序,而不会将其拆分回来。

于 2013-08-16T04:12:20.100 回答