如何自定义要插入的数据?

时间:2013-08-16 03:40:30

标签: mysql

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

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

4 个答案:

答案 0 :(得分: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>;

答案 1 :(得分:1)

除了您可能最好将此ID存储在单独的列中并根据需要显示(例如,使用视图),您的单词 ... autoincrement value ... 可能会解释为至少有两种方式:

  1. 您有一个auto_increment PK列id,并且您希望在生成此复合二次ID时使用其值
  2. 您有一个PK列id(无论是否为auto_increment),但您希望生成每年和每月组合唯一的int值。

  3. 如果是第一种情况,您可以使用单独的表进行排序以及像这样的触发器来解决这个问题

    表架构

    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 |   ITEM_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 |   ITEM_ID |
    ------------------
    |  1 | 13-08-001 |
    |  2 | 13-08-002 |
    

    这是 SQLFiddle 演示

答案 2 :(得分:0)

创建after insert trigger,根据您正在制作的模式更新列

答案 3 :(得分:0)

我不相信这可以通过触发器实现,无论是插入前还是后插入。并且分配给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函数转换日期/日期时间/ timestamp到字符串中,基于第二个参数中提供的格式。


修改

我可能已经阅读了“(除了使用的索引ID )”和“自动增量”之外的更多内容。我认为这意味着该表具有定义为AUTO_INCREMENT的ID列。如果情况并非如此,那么上面的答案就不起作用了。

(这是问题中的更多细节,即SHOW CREATE TABLE的输出,以及一些示例数据,显示了将要分配的值的类型(自动增量id是否为每个不同的值“重置”'yy- mm-',或者它是否持续上升。)

如果 autoincrement 部分的值是从AUTO_INCREMENT以外的机制派生的,那么可以在BEFORE INSERT触发器中为列分配值。


尽管如此,我怀疑是否需要以这种格式存储列。 (添加此列没有明显的要求,没有理由说明为什么需要此列。)

如果dateid作为单独的列存储在表中,则格式化字符串的生成非常简单,可以在查询的SELECT列表中处理。我无法看到这对于排序非常有用,因为不能保证对字符串值的排序按照数字顺序对给定yy-mm-中的id值进行排序,而不将其拆分。